@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.
Files changed (636) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/LICENSE +661 -0
  3. package/README.ja.md +248 -0
  4. package/README.md +255 -0
  5. package/THIRD_PARTY_NOTICES.md +275 -0
  6. package/dist/api/api.d.ts +1259 -0
  7. package/dist/api/api.js +86 -0
  8. package/dist/api/context.d.ts +173 -0
  9. package/dist/api/context.js +193 -0
  10. package/dist/api/display-api.d.ts +1 -0
  11. package/dist/api/display-api.js +23 -0
  12. package/dist/api/event-api.d.ts +13 -0
  13. package/dist/api/event-api.js +17 -0
  14. package/dist/api/extension-api.d.ts +46 -0
  15. package/dist/api/extension-api.js +85 -0
  16. package/dist/api/feature-api.d.ts +11 -0
  17. package/dist/api/feature-api.js +101 -0
  18. package/dist/api/geometry/apply.d.ts +51 -0
  19. package/dist/api/geometry/apply.js +114 -0
  20. package/dist/api/geometry/boolean.d.ts +28 -0
  21. package/dist/api/geometry/boolean.js +65 -0
  22. package/dist/api/geometry/buffer.d.ts +11 -0
  23. package/dist/api/geometry/buffer.js +105 -0
  24. package/dist/api/geometry/split.d.ts +16 -0
  25. package/dist/api/geometry/split.js +75 -0
  26. package/dist/api/geometry/targets.d.ts +76 -0
  27. package/dist/api/geometry/targets.js +158 -0
  28. package/dist/api/geometry/types.d.ts +31 -0
  29. package/dist/api/geometry/types.js +3 -0
  30. package/dist/api/geometry-operations.d.ts +162 -0
  31. package/dist/api/geometry-operations.js +94 -0
  32. package/dist/api/group-api.d.ts +10 -0
  33. package/dist/api/group-api.js +78 -0
  34. package/dist/api/import-export/constants.d.ts +29 -0
  35. package/dist/api/import-export/constants.js +40 -0
  36. package/dist/api/import-export/embedded-file.d.ts +13 -0
  37. package/dist/api/import-export/embedded-file.js +31 -0
  38. package/dist/api/import-export/file-name.d.ts +10 -0
  39. package/dist/api/import-export/file-name.js +20 -0
  40. package/dist/api/import-export/format-detection.d.ts +12 -0
  41. package/dist/api/import-export/format-detection.js +29 -0
  42. package/dist/api/import-export/geojson-export.d.ts +19 -0
  43. package/dist/api/import-export/geojson-export.js +262 -0
  44. package/dist/api/import-export/geojson-import.d.ts +34 -0
  45. package/dist/api/import-export/geojson-import.js +538 -0
  46. package/dist/api/import-export/geometry-validation.d.ts +20 -0
  47. package/dist/api/import-export/geometry-validation.js +107 -0
  48. package/dist/api/import-export/image-import.d.ts +12 -0
  49. package/dist/api/import-export/image-import.js +53 -0
  50. package/dist/api/import-export/index.d.ts +9 -0
  51. package/dist/api/import-export/index.js +107 -0
  52. package/dist/api/import-export/native-format.d.ts +15 -0
  53. package/dist/api/import-export/native-format.js +126 -0
  54. package/dist/api/import-export/native-validation.d.ts +28 -0
  55. package/dist/api/import-export/native-validation.js +212 -0
  56. package/dist/api/import-export/own-property.d.ts +10 -0
  57. package/dist/api/import-export/own-property.js +19 -0
  58. package/dist/api/import-export/style-validation.d.ts +27 -0
  59. package/dist/api/import-export/style-validation.js +49 -0
  60. package/dist/api/import-export/types.d.ts +26 -0
  61. package/dist/api/import-export/types.js +3 -0
  62. package/dist/api/index.d.ts +15 -0
  63. package/dist/api/index.js +3 -0
  64. package/dist/api/input-api.d.ts +158 -0
  65. package/dist/api/input-api.js +144 -0
  66. package/dist/api/instance-api.d.ts +38 -0
  67. package/dist/api/instance-api.js +136 -0
  68. package/dist/api/layer-api.d.ts +12 -0
  69. package/dist/api/layer-api.js +62 -0
  70. package/dist/api/selection-api.d.ts +7 -0
  71. package/dist/api/selection-api.js +78 -0
  72. package/dist/api/snapping-api.d.ts +125 -0
  73. package/dist/api/snapping-api.js +50 -0
  74. package/dist/api/topology-api.d.ts +30 -0
  75. package/dist/api/topology-api.js +16 -0
  76. package/dist/api/tracing-api.d.ts +31 -0
  77. package/dist/api/tracing-api.js +16 -0
  78. package/dist/dispatcher/hit-test/box-strategies.d.ts +19 -0
  79. package/dist/dispatcher/hit-test/box-strategies.js +275 -0
  80. package/dist/dispatcher/hit-test/box-strategy.d.ts +59 -0
  81. package/dist/dispatcher/hit-test/box-strategy.js +37 -0
  82. package/dist/dispatcher/hit-test/globe-shape.d.ts +46 -0
  83. package/dist/dispatcher/hit-test/globe-shape.js +70 -0
  84. package/dist/dispatcher/hit-test/index.d.ts +14 -0
  85. package/dist/dispatcher/hit-test/index.js +9 -0
  86. package/dist/dispatcher/hit-test/local-frame.d.ts +77 -0
  87. package/dist/dispatcher/hit-test/local-frame.js +112 -0
  88. package/dist/dispatcher/hit-test/segment-grid.d.ts +32 -0
  89. package/dist/dispatcher/hit-test/segment-grid.js +79 -0
  90. package/dist/dispatcher/hit-test/service.d.ts +120 -0
  91. package/dist/dispatcher/hit-test/service.js +333 -0
  92. package/dist/dispatcher/hit-test/strategies/base.d.ts +136 -0
  93. package/dist/dispatcher/hit-test/strategies/base.js +66 -0
  94. package/dist/dispatcher/hit-test/strategies/circle.d.ts +10 -0
  95. package/dist/dispatcher/hit-test/strategies/circle.js +56 -0
  96. package/dist/dispatcher/hit-test/strategies/image.d.ts +22 -0
  97. package/dist/dispatcher/hit-test/strategies/image.js +115 -0
  98. package/dist/dispatcher/hit-test/strategies/index.d.ts +11 -0
  99. package/dist/dispatcher/hit-test/strategies/index.js +10 -0
  100. package/dist/dispatcher/hit-test/strategies/line.d.ts +17 -0
  101. package/dist/dispatcher/hit-test/strategies/line.js +30 -0
  102. package/dist/dispatcher/hit-test/strategies/multi.d.ts +44 -0
  103. package/dist/dispatcher/hit-test/strategies/multi.js +141 -0
  104. package/dist/dispatcher/hit-test/strategies/point.d.ts +20 -0
  105. package/dist/dispatcher/hit-test/strategies/point.js +29 -0
  106. package/dist/dispatcher/hit-test/strategies/polygon.d.ts +52 -0
  107. package/dist/dispatcher/hit-test/strategies/polygon.js +138 -0
  108. package/dist/dispatcher/hit-test/topmost.d.ts +48 -0
  109. package/dist/dispatcher/hit-test/topmost.js +157 -0
  110. package/dist/dispatcher/hit-test/visibility-lookup.d.ts +23 -0
  111. package/dist/dispatcher/hit-test/visibility-lookup.js +40 -0
  112. package/dist/dispatcher/index.d.ts +15 -0
  113. package/dist/dispatcher/index.js +3 -0
  114. package/dist/dispatcher/input-router.d.ts +1 -0
  115. package/dist/dispatcher/input-router.js +288 -0
  116. package/dist/dispatcher/normalizer.d.ts +1 -0
  117. package/dist/dispatcher/normalizer.js +513 -0
  118. package/dist/dispatcher/types.d.ts +144 -0
  119. package/dist/dispatcher/types.js +15 -0
  120. package/dist/display/chunk-set.d.ts +24 -0
  121. package/dist/display/chunk-set.js +533 -0
  122. package/dist/display/chunk.d.ts +1 -0
  123. package/dist/display/chunk.js +104 -0
  124. package/dist/display/columnar/index.d.ts +12 -0
  125. package/dist/display/columnar/index.js +13 -0
  126. package/dist/display/columnar/prepare.d.ts +42 -0
  127. package/dist/display/columnar/prepare.js +116 -0
  128. package/dist/display/columnar/source.d.ts +1 -0
  129. package/dist/display/columnar/source.js +531 -0
  130. package/dist/display/columnar/table.d.ts +1 -0
  131. package/dist/display/columnar/table.js +471 -0
  132. package/dist/display/columnar/types.d.ts +223 -0
  133. package/dist/display/columnar/types.js +3 -0
  134. package/dist/display/dataset.d.ts +2 -0
  135. package/dist/display/dataset.js +891 -0
  136. package/dist/display/index.d.ts +13 -0
  137. package/dist/display/index.js +3 -0
  138. package/dist/display/interaction.d.ts +1 -0
  139. package/dist/display/interaction.js +90 -0
  140. package/dist/display/manager.d.ts +1 -0
  141. package/dist/display/manager.js +440 -0
  142. package/dist/display/packed-rtree.d.ts +1 -0
  143. package/dist/display/packed-rtree.js +244 -0
  144. package/dist/display/partition.d.ts +1 -0
  145. package/dist/display/partition.js +226 -0
  146. package/dist/display/provider.d.ts +1 -0
  147. package/dist/display/provider.js +342 -0
  148. package/dist/display/retained.d.ts +40 -0
  149. package/dist/display/retained.js +898 -0
  150. package/dist/display/selection.d.ts +13 -0
  151. package/dist/display/selection.js +226 -0
  152. package/dist/display/source.d.ts +1 -0
  153. package/dist/display/source.js +119 -0
  154. package/dist/display/spatial.d.ts +1 -0
  155. package/dist/display/spatial.js +71 -0
  156. package/dist/display/style.d.ts +1 -0
  157. package/dist/display/style.js +126 -0
  158. package/dist/display/thinning.d.ts +65 -0
  159. package/dist/display/thinning.js +910 -0
  160. package/dist/display/triangulation.d.ts +1 -0
  161. package/dist/display/triangulation.js +0 -0
  162. package/dist/display/types.d.ts +561 -0
  163. package/dist/display/types.js +43 -0
  164. package/dist/extension/feature-handler.d.ts +182 -0
  165. package/dist/extension/feature-handler.js +3 -0
  166. package/dist/extension/index.d.ts +9 -0
  167. package/dist/extension/index.js +3 -0
  168. package/dist/extension/renderers.d.ts +208 -0
  169. package/dist/extension/renderers.js +3 -0
  170. package/dist/geometry/angle.d.ts +47 -0
  171. package/dist/geometry/angle.js +44 -0
  172. package/dist/geometry/bbox.d.ts +48 -0
  173. package/dist/geometry/bbox.js +83 -0
  174. package/dist/geometry/boolean.d.ts +162 -0
  175. package/dist/geometry/boolean.js +331 -0
  176. package/dist/geometry/buffer.d.ts +72 -0
  177. package/dist/geometry/buffer.js +218 -0
  178. package/dist/geometry/circle.d.ts +55 -0
  179. package/dist/geometry/circle.js +107 -0
  180. package/dist/geometry/coords.d.ts +97 -0
  181. package/dist/geometry/coords.js +149 -0
  182. package/dist/geometry/distance.d.ts +79 -0
  183. package/dist/geometry/distance.js +111 -0
  184. package/dist/geometry/errors.d.ts +74 -0
  185. package/dist/geometry/errors.js +104 -0
  186. package/dist/geometry/index.d.ts +28 -0
  187. package/dist/geometry/index.js +38 -0
  188. package/dist/geometry/measure.d.ts +81 -0
  189. package/dist/geometry/measure.js +236 -0
  190. package/dist/geometry/predicates.d.ts +62 -0
  191. package/dist/geometry/predicates.js +132 -0
  192. package/dist/geometry/simplify.d.ts +74 -0
  193. package/dist/geometry/simplify.js +159 -0
  194. package/dist/geometry/split.d.ts +68 -0
  195. package/dist/geometry/split.js +430 -0
  196. package/dist/geometry/types.d.ts +95 -0
  197. package/dist/geometry/types.js +3 -0
  198. package/dist/geometry/units.d.ts +35 -0
  199. package/dist/geometry/units.js +41 -0
  200. package/dist/index.d.ts +72 -0
  201. package/dist/index.js +20 -0
  202. package/dist/maplibre-gl-draw.d.ts +47 -0
  203. package/dist/maplibre-gl-draw.js +407 -0
  204. package/dist/messages.d.ts +64 -0
  205. package/dist/messages.js +36 -0
  206. package/dist/modes/cursor.d.ts +1 -0
  207. package/dist/modes/cursor.js +72 -0
  208. package/dist/modes/draw/circle.d.ts +1 -0
  209. package/dist/modes/draw/circle.js +222 -0
  210. package/dist/modes/draw/commit-layer.d.ts +26 -0
  211. package/dist/modes/draw/commit-layer.js +31 -0
  212. package/dist/modes/draw/freehand.d.ts +1 -0
  213. package/dist/modes/draw/freehand.js +264 -0
  214. package/dist/modes/draw/image.d.ts +1 -0
  215. package/dist/modes/draw/image.js +60 -0
  216. package/dist/modes/draw/index.d.ts +9 -0
  217. package/dist/modes/draw/index.js +11 -0
  218. package/dist/modes/draw/line.d.ts +1 -0
  219. package/dist/modes/draw/line.js +363 -0
  220. package/dist/modes/draw/point.d.ts +1 -0
  221. package/dist/modes/draw/point.js +87 -0
  222. package/dist/modes/draw/polygon.d.ts +1 -0
  223. package/dist/modes/draw/polygon.js +378 -0
  224. package/dist/modes/draw/trace-support.d.ts +79 -0
  225. package/dist/modes/draw/trace-support.js +161 -0
  226. package/dist/modes/handler.d.ts +285 -0
  227. package/dist/modes/handler.js +3 -0
  228. package/dist/modes/index.d.ts +7 -0
  229. package/dist/modes/index.js +3 -0
  230. package/dist/modes/manager.d.ts +15 -0
  231. package/dist/modes/manager.js +196 -0
  232. package/dist/modes/select/box-selection.d.ts +52 -0
  233. package/dist/modes/select/box-selection.js +140 -0
  234. package/dist/modes/select/click-handler.d.ts +32 -0
  235. package/dist/modes/select/click-handler.js +166 -0
  236. package/dist/modes/select/cursor-handler.d.ts +15 -0
  237. package/dist/modes/select/cursor-handler.js +59 -0
  238. package/dist/modes/select/drag/auxiliary.d.ts +26 -0
  239. package/dist/modes/select/drag/auxiliary.js +56 -0
  240. package/dist/modes/select/drag/intermediate-writes.d.ts +1 -0
  241. package/dist/modes/select/drag/intermediate-writes.js +171 -0
  242. package/dist/modes/select/drag/move.d.ts +24 -0
  243. package/dist/modes/select/drag/move.js +59 -0
  244. package/dist/modes/select/drag/operation.d.ts +30 -0
  245. package/dist/modes/select/drag/operation.js +18 -0
  246. package/dist/modes/select/drag/radius.d.ts +15 -0
  247. package/dist/modes/select/drag/radius.js +49 -0
  248. package/dist/modes/select/drag/transform.d.ts +17 -0
  249. package/dist/modes/select/drag/transform.js +155 -0
  250. package/dist/modes/select/drag/vertex.d.ts +17 -0
  251. package/dist/modes/select/drag/vertex.js +163 -0
  252. package/dist/modes/select/drag-handler.d.ts +1 -0
  253. package/dist/modes/select/drag-handler.js +254 -0
  254. package/dist/modes/select/hit-helpers.d.ts +40 -0
  255. package/dist/modes/select/hit-helpers.js +51 -0
  256. package/dist/modes/select/mode.d.ts +1 -0
  257. package/dist/modes/select/mode.js +397 -0
  258. package/dist/modes/select/shortcut-handler.d.ts +40 -0
  259. package/dist/modes/select/shortcut-handler.js +128 -0
  260. package/dist/operations/index.d.ts +9 -0
  261. package/dist/operations/index.js +3 -0
  262. package/dist/operations/layer-operations.d.ts +1 -0
  263. package/dist/operations/layer-operations.js +350 -0
  264. package/dist/operations/resize.d.ts +71 -0
  265. package/dist/operations/resize.js +252 -0
  266. package/dist/operations/rotate.d.ts +17 -0
  267. package/dist/operations/rotate.js +166 -0
  268. package/dist/operations/selection-operations.d.ts +20 -0
  269. package/dist/operations/selection-operations.js +159 -0
  270. package/dist/operations/shared-vertex.d.ts +1 -0
  271. package/dist/operations/shared-vertex.js +210 -0
  272. package/dist/operations/trace-graph.d.ts +96 -0
  273. package/dist/operations/trace-graph.js +283 -0
  274. package/dist/operations/vertex.d.ts +1 -0
  275. package/dist/operations/vertex.js +538 -0
  276. package/dist/plugins/index.d.ts +10 -0
  277. package/dist/plugins/index.js +3 -0
  278. package/dist/plugins/mutation-hooks.d.ts +28 -0
  279. package/dist/plugins/mutation-hooks.js +84 -0
  280. package/dist/plugins/plugin-context.d.ts +1 -0
  281. package/dist/plugins/plugin-context.js +367 -0
  282. package/dist/plugins/plugin-manager.d.ts +103 -0
  283. package/dist/plugins/plugin-manager.js +316 -0
  284. package/dist/plugins/plugin.d.ts +529 -0
  285. package/dist/plugins/plugin.js +3 -0
  286. package/dist/shared/config/constants.d.ts +66 -0
  287. package/dist/shared/config/constants.js +60 -0
  288. package/dist/shared/config/feature-style.d.ts +155 -0
  289. package/dist/shared/config/feature-style.js +154 -0
  290. package/dist/shared/config/index.d.ts +17 -0
  291. package/dist/shared/config/index.js +8 -0
  292. package/dist/shared/config/rendering.d.ts +107 -0
  293. package/dist/shared/config/rendering.js +33 -0
  294. package/dist/shared/config/selection-highlight.d.ts +29 -0
  295. package/dist/shared/config/selection-highlight.js +35 -0
  296. package/dist/shared/config/selection.d.ts +273 -0
  297. package/dist/shared/config/selection.js +266 -0
  298. package/dist/shared/config/topology.d.ts +33 -0
  299. package/dist/shared/config/topology.js +17 -0
  300. package/dist/shared/config/trace.d.ts +40 -0
  301. package/dist/shared/config/trace.js +17 -0
  302. package/dist/shared/math/angle.d.ts +21 -0
  303. package/dist/shared/math/angle.js +34 -0
  304. package/dist/shared/math/circle.d.ts +6 -0
  305. package/dist/shared/math/circle.js +10 -0
  306. package/dist/shared/math/constants.d.ts +48 -0
  307. package/dist/shared/math/constants.js +59 -0
  308. package/dist/shared/math/distance.d.ts +78 -0
  309. package/dist/shared/math/distance.js +147 -0
  310. package/dist/shared/math/globe-subdivision.d.ts +62 -0
  311. package/dist/shared/math/globe-subdivision.js +99 -0
  312. package/dist/shared/math/index.d.ts +17 -0
  313. package/dist/shared/math/index.js +21 -0
  314. package/dist/shared/math/intersection.d.ts +63 -0
  315. package/dist/shared/math/intersection.js +236 -0
  316. package/dist/shared/math/longitude.d.ts +20 -0
  317. package/dist/shared/math/longitude.js +31 -0
  318. package/dist/shared/math/mercator-plane.d.ts +27 -0
  319. package/dist/shared/math/mercator-plane.js +26 -0
  320. package/dist/shared/math/obb.d.ts +65 -0
  321. package/dist/shared/math/obb.js +107 -0
  322. package/dist/shared/math/rotation.d.ts +93 -0
  323. package/dist/shared/math/rotation.js +186 -0
  324. package/dist/shared/math/segment-grid.d.ts +69 -0
  325. package/dist/shared/math/segment-grid.js +159 -0
  326. package/dist/shared/math/transform.d.ts +140 -0
  327. package/dist/shared/math/transform.js +189 -0
  328. package/dist/shared/types/events.d.ts +128 -0
  329. package/dist/shared/types/events.js +3 -0
  330. package/dist/shared/types/model.d.ts +950 -0
  331. package/dist/shared/types/model.js +3 -0
  332. package/dist/shared/types/selection-box.d.ts +23 -0
  333. package/dist/shared/types/selection-box.js +3 -0
  334. package/dist/shared/types/style.d.ts +68 -0
  335. package/dist/shared/types/style.js +3 -0
  336. package/dist/shared/utils/color.d.ts +49 -0
  337. package/dist/shared/utils/color.js +180 -0
  338. package/dist/shared/utils/coordinates.d.ts +52 -0
  339. package/dist/shared/utils/coordinates.js +75 -0
  340. package/dist/shared/utils/embedded-image.d.ts +34 -0
  341. package/dist/shared/utils/embedded-image.js +161 -0
  342. package/dist/shared/utils/event-emitter.d.ts +262 -0
  343. package/dist/shared/utils/event-emitter.js +44 -0
  344. package/dist/shared/utils/feature-bbox.d.ts +8 -0
  345. package/dist/shared/utils/feature-bbox.js +207 -0
  346. package/dist/shared/utils/feature-segments.d.ts +23 -0
  347. package/dist/shared/utils/feature-segments.js +179 -0
  348. package/dist/shared/utils/id.d.ts +1 -0
  349. package/dist/shared/utils/id.js +35 -0
  350. package/dist/shared/utils/image.d.ts +34 -0
  351. package/dist/shared/utils/image.js +106 -0
  352. package/dist/shared/utils/index.d.ts +15 -0
  353. package/dist/shared/utils/index.js +24 -0
  354. package/dist/shared/utils/map.d.ts +26 -0
  355. package/dist/shared/utils/map.js +35 -0
  356. package/dist/shared/utils/name-generator.d.ts +197 -0
  357. package/dist/shared/utils/name-generator.js +337 -0
  358. package/dist/shared/utils/pixel-ratio.d.ts +111 -0
  359. package/dist/shared/utils/pixel-ratio.js +85 -0
  360. package/dist/shared/utils/property.d.ts +88 -0
  361. package/dist/shared/utils/property.js +140 -0
  362. package/dist/shared/utils/vertex-ref.d.ts +23 -0
  363. package/dist/shared/utils/vertex-ref.js +20 -0
  364. package/dist/snapping/custom-targets.d.ts +1 -0
  365. package/dist/snapping/custom-targets.js +21 -0
  366. package/dist/snapping/geometry.d.ts +1 -0
  367. package/dist/snapping/geometry.js +61 -0
  368. package/dist/snapping/index.d.ts +14 -0
  369. package/dist/snapping/index.js +4 -0
  370. package/dist/snapping/indicator.d.ts +19 -0
  371. package/dist/snapping/indicator.js +145 -0
  372. package/dist/snapping/providers/display.d.ts +72 -0
  373. package/dist/snapping/providers/display.js +268 -0
  374. package/dist/snapping/providers/guide.d.ts +69 -0
  375. package/dist/snapping/providers/guide.js +187 -0
  376. package/dist/snapping/providers/intersection.d.ts +1 -0
  377. package/dist/snapping/providers/intersection.js +92 -0
  378. package/dist/snapping/providers/shared.d.ts +39 -0
  379. package/dist/snapping/providers/shared.js +146 -0
  380. package/dist/snapping/providers/store.d.ts +1 -0
  381. package/dist/snapping/providers/store.js +132 -0
  382. package/dist/snapping/service.d.ts +1 -0
  383. package/dist/snapping/service.js +272 -0
  384. package/dist/snapping/types.d.ts +267 -0
  385. package/dist/snapping/types.js +66 -0
  386. package/dist/store/change-merger.d.ts +1 -0
  387. package/dist/store/change-merger.js +102 -0
  388. package/dist/store/draw-store.d.ts +1 -0
  389. package/dist/store/draw-store.js +396 -0
  390. package/dist/store/event-bridge.d.ts +1 -0
  391. package/dist/store/event-bridge.js +161 -0
  392. package/dist/store/index.d.ts +12 -0
  393. package/dist/store/index.js +4 -0
  394. package/dist/store/local-visibility.d.ts +21 -0
  395. package/dist/store/local-visibility.js +27 -0
  396. package/dist/store/lock.d.ts +67 -0
  397. package/dist/store/lock.js +54 -0
  398. package/dist/store/memory/change-bus.d.ts +60 -0
  399. package/dist/store/memory/change-bus.js +232 -0
  400. package/dist/store/memory/file-store.d.ts +15 -0
  401. package/dist/store/memory/file-store.js +33 -0
  402. package/dist/store/memory/frozen.d.ts +21 -0
  403. package/dist/store/memory/frozen.js +51 -0
  404. package/dist/store/memory/ui-state.d.ts +51 -0
  405. package/dist/store/memory/ui-state.js +223 -0
  406. package/dist/store/memory.d.ts +26 -0
  407. package/dist/store/memory.js +708 -0
  408. package/dist/store/spatial/index.d.ts +6 -0
  409. package/dist/store/spatial/index.js +4 -0
  410. package/dist/store/spatial/spatial-index.d.ts +90 -0
  411. package/dist/store/spatial/spatial-index.js +148 -0
  412. package/dist/store/spatial/store-spatial-index.d.ts +60 -0
  413. package/dist/store/spatial/store-spatial-index.js +125 -0
  414. package/dist/store/store.d.ts +417 -0
  415. package/dist/store/store.js +3 -0
  416. package/dist/store/types.d.ts +8 -0
  417. package/dist/store/types.js +3 -0
  418. package/dist/store/writable-layer.d.ts +35 -0
  419. package/dist/store/writable-layer.js +20 -0
  420. package/dist/view/cache/buffer.d.ts +28 -0
  421. package/dist/view/cache/buffer.js +176 -0
  422. package/dist/view/cache/earcut.d.ts +1 -0
  423. package/dist/view/cache/earcut.js +122 -0
  424. package/dist/view/cache/style-rule.d.ts +1 -0
  425. package/dist/view/cache/style-rule.js +97 -0
  426. package/dist/view/cache/terrain-fill.d.ts +30 -0
  427. package/dist/view/cache/terrain-fill.js +60 -0
  428. package/dist/view/cache/texture.d.ts +14 -0
  429. package/dist/view/cache/texture.js +292 -0
  430. package/dist/view/coordinator.d.ts +27 -0
  431. package/dist/view/coordinator.js +72 -0
  432. package/dist/view/feature-companion.d.ts +173 -0
  433. package/dist/view/feature-companion.js +108 -0
  434. package/dist/view/globe-subdivision.d.ts +78 -0
  435. package/dist/view/globe-subdivision.js +128 -0
  436. package/dist/view/index.d.ts +47 -0
  437. package/dist/view/index.js +20 -0
  438. package/dist/view/layer/attach.d.ts +20 -0
  439. package/dist/view/layer/attach.js +47 -0
  440. package/dist/view/layer/blend.d.ts +57 -0
  441. package/dist/view/layer/blend.js +14 -0
  442. package/dist/view/layer/custom-layer.d.ts +1 -0
  443. package/dist/view/layer/custom-layer.js +509 -0
  444. package/dist/view/layer/depth-state.d.ts +14 -0
  445. package/dist/view/layer/depth-state.js +44 -0
  446. package/dist/view/layer/display-list.d.ts +1 -0
  447. package/dist/view/layer/display-list.js +111 -0
  448. package/dist/view/layer/drape-planner.d.ts +139 -0
  449. package/dist/view/layer/drape-planner.js +726 -0
  450. package/dist/view/layer/frame-render.d.ts +57 -0
  451. package/dist/view/layer/frame-render.js +209 -0
  452. package/dist/view/layer/frame-state.d.ts +147 -0
  453. package/dist/view/layer/frame-state.js +484 -0
  454. package/dist/view/layer/gl-state.d.ts +77 -0
  455. package/dist/view/layer/gl-state.js +132 -0
  456. package/dist/view/layer/index.d.ts +6 -0
  457. package/dist/view/layer/index.js +5 -0
  458. package/dist/view/layer/render-scope.d.ts +30 -0
  459. package/dist/view/layer/render-scope.js +28 -0
  460. package/dist/view/layer/render.d.ts +87 -0
  461. package/dist/view/layer/render.js +187 -0
  462. package/dist/view/layer/renderers.d.ts +81 -0
  463. package/dist/view/layer/renderers.js +142 -0
  464. package/dist/view/layer/slot-manager.d.ts +26 -0
  465. package/dist/view/layer/slot-manager.js +133 -0
  466. package/dist/view/layer/slots.d.ts +33 -0
  467. package/dist/view/layer/slots.js +50 -0
  468. package/dist/view/layer/store-retained-bbox.d.ts +36 -0
  469. package/dist/view/layer/store-retained-bbox.js +188 -0
  470. package/dist/view/layer/store-retained-chunk.d.ts +97 -0
  471. package/dist/view/layer/store-retained-chunk.js +94 -0
  472. package/dist/view/layer/store-retained-classify.d.ts +34 -0
  473. package/dist/view/layer/store-retained-classify.js +88 -0
  474. package/dist/view/layer/store-retained-collect.d.ts +24 -0
  475. package/dist/view/layer/store-retained-collect.js +121 -0
  476. package/dist/view/layer/store-retained-coord-patch.d.ts +119 -0
  477. package/dist/view/layer/store-retained-coord-patch.js +168 -0
  478. package/dist/view/layer/store-retained-immediate.d.ts +63 -0
  479. package/dist/view/layer/store-retained-immediate.js +49 -0
  480. package/dist/view/layer/store-retained-invalidation.d.ts +96 -0
  481. package/dist/view/layer/store-retained-invalidation.js +192 -0
  482. package/dist/view/layer/store-retained.d.ts +198 -0
  483. package/dist/view/layer/store-retained.js +430 -0
  484. package/dist/view/layer/terrain-resolver.d.ts +1 -0
  485. package/dist/view/layer/terrain-resolver.js +174 -0
  486. package/dist/view/renderers/batch-manager.d.ts +61 -0
  487. package/dist/view/renderers/batch-manager.js +718 -0
  488. package/dist/view/renderers/draw-factors.d.ts +60 -0
  489. package/dist/view/renderers/draw-factors.js +35 -0
  490. package/dist/view/renderers/drawer.d.ts +1 -0
  491. package/dist/view/renderers/drawer.js +346 -0
  492. package/dist/view/renderers/image.d.ts +1 -0
  493. package/dist/view/renderers/image.js +255 -0
  494. package/dist/view/renderers/line/dash.d.ts +31 -0
  495. package/dist/view/renderers/line/dash.js +152 -0
  496. package/dist/view/renderers/line/line-geometry.d.ts +39 -0
  497. package/dist/view/renderers/line/line-geometry.js +460 -0
  498. package/dist/view/renderers/line/line-gl.d.ts +1 -0
  499. package/dist/view/renderers/line/line-gl.js +236 -0
  500. package/dist/view/renderers/line/line-shader.d.ts +1 -0
  501. package/dist/view/renderers/line/line-shader.js +364 -0
  502. package/dist/view/renderers/line/line-types.d.ts +43 -0
  503. package/dist/view/renderers/line/line-types.js +3 -0
  504. package/dist/view/renderers/line/line-uniforms.d.ts +1 -0
  505. package/dist/view/renderers/line/line-uniforms.js +390 -0
  506. package/dist/view/renderers/line/sdf-line.d.ts +92 -0
  507. package/dist/view/renderers/line/sdf-line.js +567 -0
  508. package/dist/view/renderers/point/billboard-depth.d.ts +10 -0
  509. package/dist/view/renderers/point/billboard-depth.js +56 -0
  510. package/dist/view/renderers/point/point-instance.d.ts +124 -0
  511. package/dist/view/renderers/point/point-instance.js +738 -0
  512. package/dist/view/renderers/point/point-sdf.d.ts +58 -0
  513. package/dist/view/renderers/point/point-sdf.js +170 -0
  514. package/dist/view/renderers/point/point-shape.d.ts +99 -0
  515. package/dist/view/renderers/point/point-shape.js +504 -0
  516. package/dist/view/renderers/point/point-style.d.ts +1 -0
  517. package/dist/view/renderers/point/point-style.js +46 -0
  518. package/dist/view/renderers/polygon/batch.d.ts +26 -0
  519. package/dist/view/renderers/polygon/batch.js +336 -0
  520. package/dist/view/renderers/polygon/earcut-input.d.ts +37 -0
  521. package/dist/view/renderers/polygon/earcut-input.js +55 -0
  522. package/dist/view/renderers/polygon/earcut-sliced.d.ts +69 -0
  523. package/dist/view/renderers/polygon/earcut-sliced.js +960 -0
  524. package/dist/view/renderers/polygon/fill.d.ts +74 -0
  525. package/dist/view/renderers/polygon/fill.js +251 -0
  526. package/dist/view/renderers/polygon/sdf-polygon.d.ts +62 -0
  527. package/dist/view/renderers/polygon/sdf-polygon.js +919 -0
  528. package/dist/view/renderers/polygon/terrain-cull.d.ts +3 -0
  529. package/dist/view/renderers/polygon/terrain-cull.js +14 -0
  530. package/dist/view/renderers/polygon/triangulator.d.ts +41 -0
  531. package/dist/view/renderers/polygon/triangulator.js +3 -0
  532. package/dist/view/renderers/retained.d.ts +43 -0
  533. package/dist/view/renderers/retained.js +3 -0
  534. package/dist/view/renderers/stroke.d.ts +121 -0
  535. package/dist/view/renderers/stroke.js +621 -0
  536. package/dist/view/shaders/frame.d.ts +8 -0
  537. package/dist/view/shaders/frame.js +37 -0
  538. package/dist/view/shaders/helpers.d.ts +238 -0
  539. package/dist/view/shaders/helpers.js +611 -0
  540. package/dist/view/shaders/initializer.d.ts +27 -0
  541. package/dist/view/shaders/initializer.js +125 -0
  542. package/dist/view/shaders/projection.d.ts +123 -0
  543. package/dist/view/shaders/projection.js +299 -0
  544. package/dist/view/shaders/quad-grid.d.ts +77 -0
  545. package/dist/view/shaders/quad-grid.js +128 -0
  546. package/dist/view/shaders/quad.d.ts +189 -0
  547. package/dist/view/shaders/quad.js +582 -0
  548. package/dist/view/shaders/retained-origin.d.ts +50 -0
  549. package/dist/view/shaders/retained-origin.js +67 -0
  550. package/dist/view/shaders/terrain-shade.d.ts +23 -0
  551. package/dist/view/shaders/terrain-shade.js +93 -0
  552. package/dist/view/style-rule.d.ts +166 -0
  553. package/dist/view/style-rule.js +300 -0
  554. package/dist/view/terrain/anchor.d.ts +135 -0
  555. package/dist/view/terrain/anchor.js +226 -0
  556. package/dist/view/terrain/context.d.ts +132 -0
  557. package/dist/view/terrain/context.js +437 -0
  558. package/dist/view/terrain/dem-atlas.d.ts +97 -0
  559. package/dist/view/terrain/dem-atlas.js +534 -0
  560. package/dist/view/terrain/detect.d.ts +126 -0
  561. package/dist/view/terrain/detect.js +198 -0
  562. package/dist/view/terrain/drape/bin-store.d.ts +179 -0
  563. package/dist/view/terrain/drape/bin-store.js +529 -0
  564. package/dist/view/terrain/drape/binning.d.ts +259 -0
  565. package/dist/view/terrain/drape/binning.js +604 -0
  566. package/dist/view/terrain/drape/edge-constrain.d.ts +37 -0
  567. package/dist/view/terrain/drape/edge-constrain.js +175 -0
  568. package/dist/view/terrain/drape/geometry.d.ts +95 -0
  569. package/dist/view/terrain/drape/geometry.js +260 -0
  570. package/dist/view/terrain/drape/mesh.d.ts +50 -0
  571. package/dist/view/terrain/drape/mesh.js +86 -0
  572. package/dist/view/terrain/drape/pass.d.ts +122 -0
  573. package/dist/view/terrain/drape/pass.js +379 -0
  574. package/dist/view/terrain/drape/quad-glyphs.d.ts +64 -0
  575. package/dist/view/terrain/drape/quad-glyphs.js +117 -0
  576. package/dist/view/terrain/drape/quad.d.ts +249 -0
  577. package/dist/view/terrain/drape/quad.js +835 -0
  578. package/dist/view/terrain/drape/renderer.d.ts +184 -0
  579. package/dist/view/terrain/drape/renderer.js +706 -0
  580. package/dist/view/terrain/drape/shared.d.ts +80 -0
  581. package/dist/view/terrain/drape/shared.js +173 -0
  582. package/dist/view/terrain/drape/stitch.d.ts +155 -0
  583. package/dist/view/terrain/drape/stitch.js +228 -0
  584. package/dist/view/terrain/ground.d.ts +72 -0
  585. package/dist/view/terrain/ground.js +151 -0
  586. package/dist/view/terrain/metrics.d.ts +180 -0
  587. package/dist/view/terrain/metrics.js +231 -0
  588. package/dist/view/terrain/occlusion.d.ts +11 -0
  589. package/dist/view/terrain/occlusion.js +129 -0
  590. package/dist/view/terrain/polygon.d.ts +86 -0
  591. package/dist/view/terrain/polygon.js +301 -0
  592. package/dist/view/terrain/shade.d.ts +48 -0
  593. package/dist/view/terrain/shade.js +45 -0
  594. package/dist/view/terrain/state.d.ts +99 -0
  595. package/dist/view/terrain/state.js +186 -0
  596. package/dist/view/terrain/tessellation.d.ts +265 -0
  597. package/dist/view/terrain/tessellation.js +924 -0
  598. package/dist/view/terrain/tiling.d.ts +56 -0
  599. package/dist/view/terrain/tiling.js +155 -0
  600. package/dist/view/terrain/upstream-terrain.d.ts +82 -0
  601. package/dist/view/terrain/upstream-terrain.js +116 -0
  602. package/dist/view/ui/auxiliary-handles.d.ts +151 -0
  603. package/dist/view/ui/auxiliary-handles.js +22 -0
  604. package/dist/view/ui/bounds.d.ts +53 -0
  605. package/dist/view/ui/bounds.js +149 -0
  606. package/dist/view/ui/box-selection.d.ts +1 -0
  607. package/dist/view/ui/box-selection.js +83 -0
  608. package/dist/view/ui/handle-test.d.ts +1 -0
  609. package/dist/view/ui/handle-test.js +437 -0
  610. package/dist/view/ui/handle-thinning.d.ts +122 -0
  611. package/dist/view/ui/handle-thinning.js +430 -0
  612. package/dist/view/ui/handles.d.ts +25 -0
  613. package/dist/view/ui/handles.js +673 -0
  614. package/dist/view/ui/helper.d.ts +19 -0
  615. package/dist/view/ui/helper.js +76 -0
  616. package/dist/view/ui/index.d.ts +15 -0
  617. package/dist/view/ui/index.js +15 -0
  618. package/dist/view/ui/selection-scope.d.ts +25 -0
  619. package/dist/view/ui/selection-scope.js +34 -0
  620. package/dist/view/ui/selection-ui/bounding-box.d.ts +44 -0
  621. package/dist/view/ui/selection-ui/bounding-box.js +240 -0
  622. package/dist/view/ui/selection-ui/extension-registry.d.ts +76 -0
  623. package/dist/view/ui/selection-ui/extension-registry.js +78 -0
  624. package/dist/view/ui/selection-ui/index.d.ts +12 -0
  625. package/dist/view/ui/selection-ui/index.js +12 -0
  626. package/dist/view/ui/selection-ui/renderer.d.ts +29 -0
  627. package/dist/view/ui/selection-ui/renderer.js +227 -0
  628. package/dist/view/ui/selection-ui/types.d.ts +55 -0
  629. package/dist/view/ui/selection-ui/types.js +3 -0
  630. package/dist/view/ui/selection-ui-drawer.d.ts +52 -0
  631. package/dist/view/ui/selection-ui-drawer.js +329 -0
  632. package/dist/view/ui/tentative.d.ts +1 -0
  633. package/dist/view/ui/tentative.js +320 -0
  634. package/dist/view/viewport.d.ts +119 -0
  635. package/dist/view/viewport.js +254 -0
  636. package/package.json +113 -0
@@ -0,0 +1,175 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Resolving T-junctions with neighboring tiles (edge constraints)
5
+ *
6
+ * At a terrain tile boundary the neighbors look the DEM up at different resolutions, so
7
+ * vertices at the same position do not land at the same height and a crack opens. Constraining
8
+ * the boundary vertices onto "the polyline of the coarser side" closes the T-junction whatever
9
+ * the zoom difference is.
10
+ *
11
+ * The analytic drape of polygons and lines (renderer.ts) and the drape of textured quads
12
+ * (quad.ts) share this constraint. Constraining only one of them results in the disagreement
13
+ * "the polygons close but the image cracks" at the same boundary.
14
+ */
15
+ import { TILE_EXTENT } from './mesh.js';
16
+ import { toFloat32Matrix } from './shared.js';
17
+ /** The order of the edges (used to assemble the uniform names) */
18
+ export const EDGE_NAMES = ['top', 'bottom', 'left', 'right'];
19
+ /**
20
+ * The DEM texture unit per edge (one's own DEM is unit 0)
21
+ *
22
+ * 6 is not used. The DEM atlas (TERRAIN_ATLAS_TEXTURE_UNIT in state.ts) is bound to 6 at the
23
+ * head of the frame and stays there, and every renderer of the vertex displacement path reads
24
+ * it as u_dem_atlas as is. Overwriting it here would make whatever is drawn after the drape
25
+ * rendering (a preview being drawn, dashed lines and so on) look elevations up in a broken
26
+ * texture and fly off screen. 1 to 4 are used by the data textures (renderer.ts) and the
27
+ * contents of the quads (quad.ts).
28
+ */
29
+ export const EDGE_UNITS = { top: 5, bottom: 7, left: 8, right: 9 };
30
+ /** The mapping put into an edge with no coarse neighbor (unit scale, no translation) */
31
+ const IDENTITY_EDGE_TRANSFORM = [1, 0, 0];
32
+ /** The uniform declarations for a single edge */
33
+ const edgeUniformDecl = (edge) => `
34
+ uniform sampler2D u_edge_dem_${edge};
35
+ uniform mat4 u_edge_dem_matrix_${edge};
36
+ uniform vec4 u_edge_dem_unpack_${edge};
37
+ // (dim, scale, translation x, translation y)
38
+ uniform vec4 u_edge_dem_frame_${edge};`;
39
+ /**
40
+ * The GLSL of the edge constraint (injected into the vertex shader)
41
+ *
42
+ * It goes after TERRAIN_SAMPLE_GLSL (because it uses u_terrain_exaggeration and the upstream DEM
43
+ * functions it carries). The caller
44
+ * obtains the constrained elevation with `drape_edge_constrained(a_pos, ele)`.
45
+ */
46
+ export const EDGE_CONSTRAIN_GLSL = `
47
+ // The constraint step per edge (top, bottom, left, right). 0 means no constraint
48
+ uniform vec4 u_edge_step;
49
+ ${EDGE_NAMES.map(edgeUniformDecl).join('')}
50
+
51
+ // Looks the elevation of this position up in the DEM of the coarser side
52
+ //
53
+ // One's own tile coordinates are mapped into the coarser side's tile coordinates first, and
54
+ // then read with the coarser side's DEM matrix and the upstream layout (upstream-terrain.ts). The
55
+ // mapping is a power-of-2 scale and a translation by an integer multiple of one mesh cell, so
56
+ // no error appears even in float and the nodes of the step land exactly on the coarser side's
57
+ // mesh nodes. In other words the value obtained here is bit-for-bit the same as the value the
58
+ // coarser side looks up at its own vertex.
59
+ float drape_edge_elevation(sampler2D dem, mat4 mtx, vec4 unpack, vec4 frame, vec2 pos) {
60
+ vec2 q = pos * frame.y + frame.zw;
61
+ vec2 coord = upstream_dem_coord((mtx * vec4(q, 0.0, 1.0)).xy, frame.x);
62
+ return upstream_dem_bilinear(dem, unpack, coord) * u_terrain_exaggeration;
63
+ }
64
+
65
+ // Constrains the elevation onto the polyline of the coarser side (resolving the T-junction)
66
+ //
67
+ // The boundary is a straight line in tile coordinates, so only the elevation has to move. It
68
+ // is stepped at the coarser side's node spacing step, and the value linearly interpolated
69
+ // between the elevations at its two ends is used. This puts 2^dz vertices of the finer side on
70
+ // one segment of the coarser side, and the gap disappears whatever the level difference is.
71
+ //
72
+ // The elevation of a node is always taken from the coarser side's DEM. Taking it from one's
73
+ // own DEM would give not the coarser side's polyline but "a polyline stepping one's own DEM
74
+ // coarsely", which stays apart by the difference in DEM resolution (this is what is behind the
75
+ // thin line remaining at the tile boundary).
76
+ float drape_constrain(
77
+ sampler2D dem, mat4 mtx, vec4 unpack, vec4 frame,
78
+ vec2 pos, float along, float step, bool horizontal
79
+ ) {
80
+ float t0 = floor(along / step) * step;
81
+ float t1 = min(t0 + step, ${TILE_EXTENT}.0);
82
+ vec2 p0 = horizontal ? vec2(t0, pos.y) : vec2(pos.x, t0);
83
+ vec2 p1 = horizontal ? vec2(t1, pos.y) : vec2(pos.x, t1);
84
+ float e0 = drape_edge_elevation(dem, mtx, unpack, frame, p0);
85
+ float e1 = drape_edge_elevation(dem, mtx, unpack, frame, p1);
86
+ float w = t1 > t0 ? (along - t0) / (t1 - t0) : 0.0;
87
+ return mix(e0, e1, w);
88
+ }
89
+
90
+ // A boundary vertex is constrained onto the coarser side's polyline only when the neighbor is
91
+ // coarser.
92
+ //
93
+ // The four corners belong to two edges. Whichever polyline they are put on, they cannot be
94
+ // made to agree with all three or more adjoining tiles (because each has its own DEM), so an
95
+ // order that looks at the top and bottom edges first is fixed. What disagrees is only the
96
+ // single point at the corner, and it closes within one mesh cell from there.
97
+ float drape_edge_constrained(vec2 pos, float ele) {
98
+ if (pos.y <= 0.0 && u_edge_step.x > 0.0) {
99
+ return drape_constrain(
100
+ u_edge_dem_top, u_edge_dem_matrix_top, u_edge_dem_unpack_top, u_edge_dem_frame_top,
101
+ pos, pos.x, u_edge_step.x, true);
102
+ }
103
+ if (pos.y >= ${TILE_EXTENT}.0 && u_edge_step.y > 0.0) {
104
+ return drape_constrain(
105
+ u_edge_dem_bottom, u_edge_dem_matrix_bottom, u_edge_dem_unpack_bottom,
106
+ u_edge_dem_frame_bottom,
107
+ pos, pos.x, u_edge_step.y, true);
108
+ }
109
+ if (pos.x <= 0.0 && u_edge_step.z > 0.0) {
110
+ return drape_constrain(
111
+ u_edge_dem_left, u_edge_dem_matrix_left, u_edge_dem_unpack_left, u_edge_dem_frame_left,
112
+ pos, pos.y, u_edge_step.z, false);
113
+ }
114
+ if (pos.x >= ${TILE_EXTENT}.0 && u_edge_step.w > 0.0) {
115
+ return drape_constrain(
116
+ u_edge_dem_right, u_edge_dem_matrix_right, u_edge_dem_unpack_right,
117
+ u_edge_dem_frame_right,
118
+ pos, pos.y, u_edge_step.w, false);
119
+ }
120
+ return ele;
121
+ }
122
+ `;
123
+ /** The names of the uniforms the edge constraint uses (for getUniformLocation) */
124
+ export const EDGE_CONSTRAIN_UNIFORMS = [
125
+ 'u_edge_step',
126
+ ...EDGE_NAMES.flatMap((edge) => [
127
+ `u_edge_dem_${edge}`,
128
+ `u_edge_dem_matrix_${edge}`,
129
+ `u_edge_dem_unpack_${edge}`,
130
+ `u_edge_dem_frame_${edge}`,
131
+ ]),
132
+ ];
133
+ /**
134
+ * Writes the uniforms of the edge constraint
135
+ *
136
+ * The step and the DEM are both written from one and the same value (the result of
137
+ * resolveTileEdges). They all come out of the terrain tile state at one and the same instant,
138
+ * so the inconsistency "the DEM is new but the step is old" cannot occur. An edge with no
139
+ * coarse neighbor (an edge that is not constrained) gets one's own DEM at unit scale with a
140
+ * translation of 0. It is never referenced because the step is 0, but leaving an unbound
141
+ * sampler makes the rendering itself fail in some implementations.
142
+ */
143
+ export function applyEdgeConstrainUniforms(gl, set, edges, own) {
144
+ if (set.u_edge_step) {
145
+ gl.uniform4f(set.u_edge_step, edges.top?.step ?? 0, edges.bottom?.step ?? 0, edges.left?.step ?? 0, edges.right?.step ?? 0);
146
+ }
147
+ for (const edge of EDGE_NAMES) {
148
+ bindEdgeTerrain(gl, set, edge, edges[edge], own);
149
+ }
150
+ }
151
+ /** Binds "the coarser side's DEM" for a single edge */
152
+ function bindEdgeTerrain(gl, set, edge, source, own) {
153
+ const terrain = source ? source.terrain : own;
154
+ const transform = source
155
+ ? [source.transform.scale, source.transform.offsetX, source.transform.offsetY]
156
+ : IDENTITY_EDGE_TRANSFORM;
157
+ const unit = EDGE_UNITS[edge];
158
+ gl.activeTexture(gl.TEXTURE0 + unit);
159
+ gl.bindTexture(gl.TEXTURE_2D, terrain.texture);
160
+ const sampler = set[`u_edge_dem_${edge}`];
161
+ if (sampler)
162
+ gl.uniform1i(sampler, unit);
163
+ const matrix = set[`u_edge_dem_matrix_${edge}`];
164
+ if (matrix)
165
+ gl.uniformMatrix4fv(matrix, false, toFloat32Matrix(terrain.matrix));
166
+ const unpack = set[`u_edge_dem_unpack_${edge}`];
167
+ if (unpack) {
168
+ const u = terrain.unpack;
169
+ gl.uniform4f(unpack, u[0], u[1], u[2], u[3]);
170
+ }
171
+ const frame = set[`u_edge_dem_frame_${edge}`];
172
+ if (frame) {
173
+ gl.uniform4f(frame, terrain.dim, transform[0], transform[1], transform[2]);
174
+ }
175
+ }
@@ -0,0 +1,95 @@
1
+ /**
2
+ * The geometry of the analytic drape (a cache of Mercator coordinates)
3
+ *
4
+ * The binning runs per tile. Converting longitude/latitude into Mercator per tile would mean
5
+ * applying the logarithmic transform of the latitude over and over, and for a dataset on
6
+ * the order of a million vertices such as administrative boundaries it throws away tens of
7
+ * milliseconds on every tile. The conversion is done once here and kept, so that descending to
8
+ * within-tile coordinates takes only a multiplication and a subtraction.
9
+ *
10
+ * In addition, the edges are cut into chunks (blocks) of a fixed number and given bounding
11
+ * boxes. Only a tiny part of a long outline is involved in a single tile, so dropping whole
12
+ * blocks shrinks the amount scanned down to the range that actually matters.
13
+ *
14
+ * The precision is held in Float64. Mercator world coordinates are 0..1, and in Float32 a
15
+ * rounding of several pixels appears within a z16 tile (a relative error of 1.2e-7 amounts to
16
+ * 0.4% of the tile width 1.5e-5).
17
+ */
18
+ import type { Coordinate } from '../../../store/types.js';
19
+ /** The number of edges in one block */
20
+ export declare const DRAPE_BLOCK_EDGES = 64;
21
+ /** The geometry of a single path */
22
+ export interface DrapeGeometryPath {
23
+ /** An interleaved array of Mercator coordinates (x, y) */
24
+ readonly xy: Float64Array;
25
+ /** The number of edges (the same as the vertex count for a closed path, the vertex count -
26
+ * 1 for an open one) */
27
+ readonly edgeCount: number;
28
+ /** Whether it is closed (the rings of a polygon are closed) */
29
+ readonly closed: boolean;
30
+ /** The bounding box of each block (minX, minY, maxX, maxY) */
31
+ readonly blocks: Float64Array;
32
+ }
33
+ /** The geometry of a single feature */
34
+ export interface DrapeGeometry {
35
+ readonly paths: readonly DrapeGeometryPath[];
36
+ readonly edgeCount: number;
37
+ readonly minX: number;
38
+ readonly minY: number;
39
+ readonly maxX: number;
40
+ readonly maxY: number;
41
+ }
42
+ /** Longitude -> Mercator x */
43
+ export declare function drapeMercatorX(lng: number): number;
44
+ /** Latitude -> Mercator y */
45
+ export declare function drapeMercatorY(lat: number): number;
46
+ /** A Mercator bounding box */
47
+ export interface DrapeBounds {
48
+ readonly minX: number;
49
+ readonly minY: number;
50
+ readonly maxX: number;
51
+ readonly maxY: number;
52
+ }
53
+ /**
54
+ * Computes the bounding box alone (with a cache)
55
+ *
56
+ * This is all that is needed to narrow tiles down. The minimum and maximum of the
57
+ * longitude/latitude are taken first and converted into Mercator afterwards, so the logarithm
58
+ * and the tangent are evaluated only four times (converting every vertex takes 76 ms for 1.1
59
+ * million vertices, and that single hit becomes a stutter during a zoom gesture). The Mercator
60
+ * conversion is monotonic in longitude and in latitude separately, so the rectangle obtained
61
+ * in this order agrees with the one obtained by converting every vertex.
62
+ */
63
+ export declare function drapeBoundsOf(key: object, paths: ReadonlyArray<ReadonlyArray<Coordinate>>): DrapeBounds;
64
+ /**
65
+ * Builds the geometry (with a cache)
66
+ *
67
+ * @param key The cache key (it must be identical as long as it points at the same coordinates)
68
+ * @param paths The array of paths. For a polygon, rings with the closing point dropped; for a
69
+ * line, as it is
70
+ * @param closed Whether to treat them as the rings of a polygon
71
+ */
72
+ export declare function drapeGeometryOf(key: object, paths: ReadonlyArray<ReadonlyArray<Coordinate>>, closed: boolean): DrapeGeometry;
73
+ /**
74
+ * Builds the geometry (a pure function that uses no cache)
75
+ */
76
+ export declare function buildDrapeGeometry(paths: ReadonlyArray<ReadonlyArray<Coordinate>>, closed: boolean): DrapeGeometry;
77
+ /**
78
+ * Quantized geometry for coarse tiles (LOD)
79
+ *
80
+ * Once the pitch is raised, the terrain tiles in the distance become very coarse (measured:
81
+ * a view at map zoom 13.75 with pitch 70 contained one z8 tile, and that single tile contained
82
+ * all 780,000 edges of the 8,172 administrative boundaries). Solving that as is is worth
83
+ * neither the cost of the index nor the memory, and yet that tile is drawn only in a strip on
84
+ * the horizon side of the screen.
85
+ *
86
+ * So the vertices are rounded to a grid that matches the resolution of the tile. Thinning by
87
+ * distance would thin a boundary shared by adjoining polygons separately and open a gap, but
88
+ * rounding to a grid is decided with respect to space, so boundaries that share the same
89
+ * coordinates round to the same point. A polygon left with fewer than 3 points after the
90
+ * rounding is dropped (its size is less than a pixel; the wide-area polygon laid underneath
91
+ * simply shows through).
92
+ *
93
+ * @param level The fineness of the grid. The grid spacing is 2^-level (in Mercator units)
94
+ */
95
+ export declare function drapeQuantizedGeometry(geometry: DrapeGeometry, level: number): DrapeGeometry;
@@ -0,0 +1,260 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /** The number of edges in one block */
4
+ export const DRAPE_BLOCK_EDGES = 64;
5
+ /** Longitude -> Mercator x */
6
+ export function drapeMercatorX(lng) {
7
+ return (lng + 180) / 360;
8
+ }
9
+ /** Latitude -> Mercator y */
10
+ export function drapeMercatorY(lat) {
11
+ const latRad = (lat * Math.PI) / 180;
12
+ return (1 - Math.log(Math.tan(latRad) + 1 / Math.cos(latRad)) / Math.PI) / 2;
13
+ }
14
+ /**
15
+ * The geometry cache
16
+ *
17
+ * The key is decided by the caller. For a feature in the Store the instance is replaced on
18
+ * every edit, so the feature itself is the key; for a dataset the replacement
19
+ * happens per `setFeatures` and the coordinate arrays are not reused, so the coordinate array
20
+ * is the key (when applying a style rule rebuilds only the feature instances, the same
21
+ * coordinate arrays remain, so merely changing a color does not require converting a million
22
+ * vertices again).
23
+ */
24
+ const cache = new WeakMap();
25
+ /** A cache of bounding boxes alone (it allows narrowing tiles down without building the
26
+ * geometry) */
27
+ const boundsCache = new WeakMap();
28
+ /**
29
+ * Computes the bounding box alone (with a cache)
30
+ *
31
+ * This is all that is needed to narrow tiles down. The minimum and maximum of the
32
+ * longitude/latitude are taken first and converted into Mercator afterwards, so the logarithm
33
+ * and the tangent are evaluated only four times (converting every vertex takes 76 ms for 1.1
34
+ * million vertices, and that single hit becomes a stutter during a zoom gesture). The Mercator
35
+ * conversion is monotonic in longitude and in latitude separately, so the rectangle obtained
36
+ * in this order agrees with the one obtained by converting every vertex.
37
+ */
38
+ export function drapeBoundsOf(key, paths) {
39
+ const hit = boundsCache.get(key);
40
+ if (hit)
41
+ return hit;
42
+ let minLng = Number.POSITIVE_INFINITY;
43
+ let minLat = Number.POSITIVE_INFINITY;
44
+ let maxLng = Number.NEGATIVE_INFINITY;
45
+ let maxLat = Number.NEGATIVE_INFINITY;
46
+ for (const path of paths) {
47
+ for (const point of path) {
48
+ if (point[0] < minLng)
49
+ minLng = point[0];
50
+ if (point[0] > maxLng)
51
+ maxLng = point[0];
52
+ if (point[1] < minLat)
53
+ minLat = point[1];
54
+ if (point[1] > maxLat)
55
+ maxLat = point[1];
56
+ }
57
+ }
58
+ const bounds = minLng > maxLng
59
+ ? { minX: 0, minY: 0, maxX: -1, maxY: -1 }
60
+ : {
61
+ minX: drapeMercatorX(minLng),
62
+ // Mercator y decreases as the latitude increases
63
+ minY: drapeMercatorY(maxLat),
64
+ maxX: drapeMercatorX(maxLng),
65
+ maxY: drapeMercatorY(minLat),
66
+ };
67
+ boundsCache.set(key, bounds);
68
+ return bounds;
69
+ }
70
+ /**
71
+ * Builds the geometry (with a cache)
72
+ *
73
+ * @param key The cache key (it must be identical as long as it points at the same coordinates)
74
+ * @param paths The array of paths. For a polygon, rings with the closing point dropped; for a
75
+ * line, as it is
76
+ * @param closed Whether to treat them as the rings of a polygon
77
+ */
78
+ export function drapeGeometryOf(key, paths, closed) {
79
+ const hit = cache.get(key);
80
+ if (hit)
81
+ return hit;
82
+ const built = buildDrapeGeometry(paths, closed);
83
+ cache.set(key, built);
84
+ return built;
85
+ }
86
+ /**
87
+ * Builds the geometry (a pure function that uses no cache)
88
+ */
89
+ export function buildDrapeGeometry(paths, closed) {
90
+ const converted = [];
91
+ for (const path of paths) {
92
+ const count = path.length;
93
+ if (count < 2)
94
+ continue;
95
+ const xy = new Float64Array(count * 2);
96
+ for (let i = 0; i < count; i++) {
97
+ xy[i * 2] = drapeMercatorX(path[i][0]);
98
+ xy[i * 2 + 1] = drapeMercatorY(path[i][1]);
99
+ }
100
+ converted.push(xy);
101
+ }
102
+ return buildFromMercatorPaths(converted, closed);
103
+ }
104
+ /**
105
+ * Assembles the geometry from paths in Mercator coordinates
106
+ */
107
+ function buildFromMercatorPaths(paths, closed) {
108
+ const out = [];
109
+ let minX = Number.POSITIVE_INFINITY;
110
+ let minY = Number.POSITIVE_INFINITY;
111
+ let maxX = Number.NEGATIVE_INFINITY;
112
+ let maxY = Number.NEGATIVE_INFINITY;
113
+ let edgeCount = 0;
114
+ for (const xy of paths) {
115
+ const count = xy.length / 2;
116
+ if (count < 2)
117
+ continue;
118
+ for (let i = 0; i < count; i++) {
119
+ const x = xy[i * 2];
120
+ const y = xy[i * 2 + 1];
121
+ if (x < minX)
122
+ minX = x;
123
+ if (x > maxX)
124
+ maxX = x;
125
+ if (y < minY)
126
+ minY = y;
127
+ if (y > maxY)
128
+ maxY = y;
129
+ }
130
+ const edges = closed ? count : count - 1;
131
+ const blockCount = Math.ceil(edges / DRAPE_BLOCK_EDGES);
132
+ const blocks = new Float64Array(blockCount * 4);
133
+ for (let b = 0; b < blockCount; b++) {
134
+ const from = b * DRAPE_BLOCK_EDGES;
135
+ const to = Math.min(edges, from + DRAPE_BLOCK_EDGES);
136
+ let bx0 = Number.POSITIVE_INFINITY;
137
+ let by0 = Number.POSITIVE_INFINITY;
138
+ let bx1 = Number.NEGATIVE_INFINITY;
139
+ let by1 = Number.NEGATIVE_INFINITY;
140
+ // Edge e is vertices e and e+1 (on a closed path only the last one wraps back to 0)
141
+ for (let e = from; e <= to; e++) {
142
+ const v = e < count ? e : 0;
143
+ const x = xy[v * 2];
144
+ const y = xy[v * 2 + 1];
145
+ if (x < bx0)
146
+ bx0 = x;
147
+ if (x > bx1)
148
+ bx1 = x;
149
+ if (y < by0)
150
+ by0 = y;
151
+ if (y > by1)
152
+ by1 = y;
153
+ }
154
+ blocks[b * 4] = bx0;
155
+ blocks[b * 4 + 1] = by0;
156
+ blocks[b * 4 + 2] = bx1;
157
+ blocks[b * 4 + 3] = by1;
158
+ }
159
+ out.push({ xy, edgeCount: edges, closed, blocks });
160
+ edgeCount += edges;
161
+ }
162
+ if (out.length === 0) {
163
+ return { paths: [], edgeCount: 0, minX: 0, minY: 0, maxX: -1, maxY: -1 };
164
+ }
165
+ return { paths: out, edgeCount, minX, minY, maxX, maxY };
166
+ }
167
+ /**
168
+ * Quantized geometry for coarse tiles (LOD)
169
+ *
170
+ * Once the pitch is raised, the terrain tiles in the distance become very coarse (measured:
171
+ * a view at map zoom 13.75 with pitch 70 contained one z8 tile, and that single tile contained
172
+ * all 780,000 edges of the 8,172 administrative boundaries). Solving that as is is worth
173
+ * neither the cost of the index nor the memory, and yet that tile is drawn only in a strip on
174
+ * the horizon side of the screen.
175
+ *
176
+ * So the vertices are rounded to a grid that matches the resolution of the tile. Thinning by
177
+ * distance would thin a boundary shared by adjoining polygons separately and open a gap, but
178
+ * rounding to a grid is decided with respect to space, so boundaries that share the same
179
+ * coordinates round to the same point. A polygon left with fewer than 3 points after the
180
+ * rounding is dropped (its size is less than a pixel; the wide-area polygon laid underneath
181
+ * simply shows through).
182
+ *
183
+ * @param level The fineness of the grid. The grid spacing is 2^-level (in Mercator units)
184
+ */
185
+ export function drapeQuantizedGeometry(geometry, level) {
186
+ let cache = quantizedCache.get(geometry);
187
+ if (!cache) {
188
+ cache = new Map();
189
+ quantizedCache.set(geometry, cache);
190
+ }
191
+ const hit = cache.get(level);
192
+ if (hit)
193
+ return hit;
194
+ const step = 2 ** -level;
195
+ const paths = [];
196
+ for (const path of geometry.paths) {
197
+ const source = path.xy;
198
+ const count = source.length / 2;
199
+ const out = [];
200
+ let lastX = Number.NaN;
201
+ let lastY = Number.NaN;
202
+ for (let i = 0; i < count; i++) {
203
+ const qx = Math.round(source[i * 2] / step) * step;
204
+ const qy = Math.round(source[i * 2 + 1] / step) * step;
205
+ if (qx === lastX && qy === lastY)
206
+ continue;
207
+ out.push(qx, qy);
208
+ lastX = qx;
209
+ lastY = qy;
210
+ }
211
+ if (path.closed) {
212
+ // The convention is to hold no closing point, so a tail coinciding with the head is
213
+ // dropped
214
+ while (out.length >= 6 && out[out.length - 2] === out[0] && out[out.length - 1] === out[1]) {
215
+ out.length -= 2;
216
+ }
217
+ if (out.length / 2 < 3) {
218
+ // A polygon collapsed by the rounding is replaced with a square of one grid cell.
219
+ // Dropping it would leave the fill missing just there and produce spotty white
220
+ // blotches (confirmed hands-on, the city center at z8.7; it was pronounced in areas
221
+ // where small polygons at the chome level line up).
222
+ // The error stays within one grid cell (1/256 of a tile = about 2 pixels on screen)
223
+ const box = squareAt(source, step);
224
+ if (box)
225
+ paths.push(box);
226
+ continue;
227
+ }
228
+ }
229
+ else if (out.length / 2 < 2) {
230
+ continue;
231
+ }
232
+ paths.push(new Float64Array(out));
233
+ }
234
+ const built = buildFromMercatorPaths(paths, geometry.paths[0]?.closed ?? true);
235
+ cache.set(level, built);
236
+ return built;
237
+ }
238
+ /** The cache of quantized geometry (original geometry -> fineness -> geometry) */
239
+ const quantizedCache = new WeakMap();
240
+ /**
241
+ * The square of one grid cell put in place of a collapsed polygon
242
+ *
243
+ * Its top left is the center of the original polygon rounded to the grid. The purpose is to
244
+ * avoid leaving the fill missing, so its winding is the same as the outer ring (whether it is
245
+ * clockwise has no effect on the inside/outside test).
246
+ */
247
+ function squareAt(source, step) {
248
+ const count = source.length / 2;
249
+ if (count === 0)
250
+ return null;
251
+ let sx = 0;
252
+ let sy = 0;
253
+ for (let i = 0; i < count; i++) {
254
+ sx += source[i * 2];
255
+ sy += source[i * 2 + 1];
256
+ }
257
+ const cx = Math.round(sx / count / step) * step;
258
+ const cy = Math.round(sy / count / step) * step;
259
+ return new Float64Array([cx, cy, cx + step, cy, cx + step, cy + step, cx, cy + step]);
260
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Reconstruction of the terrain mesh
3
+ *
4
+ * The vertices and triangles are built with "the same rules" as the regular mesh MapLibre uses
5
+ * to draw the terrain. The point is to make both the coordinates and the direction of the
6
+ * diagonals the same, which makes our own polygons agree exactly with MapLibre's terrain
7
+ * surface (sampling the same DEM with two different triangulations necessarily disagrees on a
8
+ * slope).
9
+ *
10
+ * The rules match `Terrain.getTerrainMesh` of MapLibre 6.6.
11
+ *
12
+ * - The vertices lay out (x * delta, y * delta) for x, y = 0..meshSize in row-major order
13
+ * (delta = EXTENT / meshSize)
14
+ * - The triangles are two per cell, (x, y) -> (x, y+1) -> (x+1, y+1) and
15
+ * (x, y) -> (x+1, y+1) -> (x+1, y). The diagonal is the main diagonal joining (x, y) and
16
+ * (x+1, y+1)
17
+ *
18
+ * No skirt (a hem at the tile boundary) is built. A prototype was verified hands-on, but the
19
+ * wall of the hem stands on the same surface as MapLibre's own skirt, so it is not hidden by
20
+ * depth and showed up as a thick band along the tile boundary. The gap at a tile boundary is
21
+ * closed not by covering it with a hem but by having adjoining tiles share the same polyline
22
+ * at the boundary (drape/stitch.ts and drape_constrain in the vertex shader).
23
+ */
24
+ /** The EXTENT of MapLibre's tile coordinate system */
25
+ export declare const TILE_EXTENT = 8192;
26
+ /** The GPU resources of one terrain mesh */
27
+ export interface TerrainMeshBuffers {
28
+ readonly vao: WebGLVertexArrayObject;
29
+ readonly vertexBuffer: WebGLBuffer;
30
+ readonly indexBuffer: WebGLBuffer;
31
+ readonly indexCount: number;
32
+ readonly meshSize: number;
33
+ }
34
+ /**
35
+ * Builds the vertices and indices of the mesh (a pure function)
36
+ */
37
+ export declare function buildTerrainMeshArrays(meshSize: number): {
38
+ vertices: Int16Array;
39
+ indices: Uint32Array;
40
+ };
41
+ /**
42
+ * Uploads the mesh to the GPU
43
+ *
44
+ * One mesh is enough regardless of the tile (the tile coordinate system is common).
45
+ */
46
+ export declare function createTerrainMeshBuffers(gl: WebGL2RenderingContext, meshSize: number): TerrainMeshBuffers | null;
47
+ /**
48
+ * Releases the GPU resources of the mesh
49
+ */
50
+ export declare function disposeTerrainMeshBuffers(gl: WebGL2RenderingContext, mesh: TerrainMeshBuffers): void;
@@ -0,0 +1,86 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Reconstruction of the terrain mesh
5
+ *
6
+ * The vertices and triangles are built with "the same rules" as the regular mesh MapLibre uses
7
+ * to draw the terrain. The point is to make both the coordinates and the direction of the
8
+ * diagonals the same, which makes our own polygons agree exactly with MapLibre's terrain
9
+ * surface (sampling the same DEM with two different triangulations necessarily disagrees on a
10
+ * slope).
11
+ *
12
+ * The rules match `Terrain.getTerrainMesh` of MapLibre 6.6.
13
+ *
14
+ * - The vertices lay out (x * delta, y * delta) for x, y = 0..meshSize in row-major order
15
+ * (delta = EXTENT / meshSize)
16
+ * - The triangles are two per cell, (x, y) -> (x, y+1) -> (x+1, y+1) and
17
+ * (x, y) -> (x+1, y+1) -> (x+1, y). The diagonal is the main diagonal joining (x, y) and
18
+ * (x+1, y+1)
19
+ *
20
+ * No skirt (a hem at the tile boundary) is built. A prototype was verified hands-on, but the
21
+ * wall of the hem stands on the same surface as MapLibre's own skirt, so it is not hidden by
22
+ * depth and showed up as a thick band along the tile boundary. The gap at a tile boundary is
23
+ * closed not by covering it with a hem but by having adjoining tiles share the same polyline
24
+ * at the boundary (drape/stitch.ts and drape_constrain in the vertex shader).
25
+ */
26
+ /** The EXTENT of MapLibre's tile coordinate system */
27
+ export const TILE_EXTENT = 8192;
28
+ /**
29
+ * Builds the vertices and indices of the mesh (a pure function)
30
+ */
31
+ export function buildTerrainMeshArrays(meshSize) {
32
+ const delta = TILE_EXTENT / meshSize;
33
+ const side = meshSize + 1;
34
+ const vertices = new Int16Array(side * side * 2);
35
+ let v = 0;
36
+ for (let y = 0; y <= meshSize; y++) {
37
+ for (let x = 0; x <= meshSize; x++) {
38
+ vertices[v++] = x * delta;
39
+ vertices[v++] = y * delta;
40
+ }
41
+ }
42
+ const indices = [];
43
+ const meshSize2 = meshSize * meshSize;
44
+ for (let rowBase = 0; rowBase < meshSize2; rowBase += meshSize + 1) {
45
+ for (let x = 0; x < meshSize; x++) {
46
+ indices.push(x + rowBase);
47
+ indices.push(meshSize + x + rowBase + 1);
48
+ indices.push(meshSize + x + rowBase + 2);
49
+ indices.push(x + rowBase);
50
+ indices.push(meshSize + x + rowBase + 2);
51
+ indices.push(x + rowBase + 1);
52
+ }
53
+ }
54
+ return { vertices, indices: new Uint32Array(indices) };
55
+ }
56
+ /**
57
+ * Uploads the mesh to the GPU
58
+ *
59
+ * One mesh is enough regardless of the tile (the tile coordinate system is common).
60
+ */
61
+ export function createTerrainMeshBuffers(gl, meshSize) {
62
+ const { vertices, indices } = buildTerrainMeshArrays(meshSize);
63
+ const vao = gl.createVertexArray();
64
+ const vertexBuffer = gl.createBuffer();
65
+ const indexBuffer = gl.createBuffer();
66
+ if (!vao || !vertexBuffer || !indexBuffer)
67
+ return null;
68
+ gl.bindVertexArray(vao);
69
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
70
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
71
+ gl.enableVertexAttribArray(0);
72
+ // The integer attribute is read as a float (the shader side is a vec2)
73
+ gl.vertexAttribPointer(0, 2, gl.SHORT, false, 4, 0);
74
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
75
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
76
+ gl.bindVertexArray(null);
77
+ return { vao, vertexBuffer, indexBuffer, indexCount: indices.length, meshSize };
78
+ }
79
+ /**
80
+ * Releases the GPU resources of the mesh
81
+ */
82
+ export function disposeTerrainMeshBuffers(gl, mesh) {
83
+ gl.deleteVertexArray(mesh.vao);
84
+ gl.deleteBuffer(mesh.vertexBuffer);
85
+ gl.deleteBuffer(mesh.indexBuffer);
86
+ }