@math.gl/geometry 5.0.0-alpha.2 → 5.0.0-alpha.20

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 (381) hide show
  1. package/LICENSE +97 -49
  2. package/README.md +16 -1
  3. package/THIRD-PARTY-NOTICES.md +18 -0
  4. package/dist/culling/constants.d.ts +3 -0
  5. package/dist/culling/constants.d.ts.map +1 -0
  6. package/dist/culling/constants.js +5 -0
  7. package/dist/culling/constants.js.map +1 -0
  8. package/dist/culling/index.cjs +2014 -0
  9. package/dist/culling/index.cjs.map +6 -0
  10. package/dist/culling/index.d.ts +29 -0
  11. package/dist/culling/index.d.ts.map +1 -0
  12. package/dist/culling/index.js +23 -0
  13. package/dist/culling/index.js.map +1 -0
  14. package/dist/culling/lib/algorithms/bounding-box-from-points.d.ts +15 -0
  15. package/dist/culling/lib/algorithms/bounding-box-from-points.d.ts.map +1 -0
  16. package/dist/culling/lib/algorithms/bounding-box-from-points.js +137 -0
  17. package/dist/culling/lib/algorithms/bounding-box-from-points.js.map +1 -0
  18. package/dist/culling/lib/algorithms/bounding-sphere-from-points.d.ts +14 -0
  19. package/dist/culling/lib/algorithms/bounding-sphere-from-points.d.ts.map +1 -0
  20. package/dist/culling/lib/algorithms/bounding-sphere-from-points.js +146 -0
  21. package/dist/culling/lib/algorithms/bounding-sphere-from-points.js.map +1 -0
  22. package/dist/culling/lib/algorithms/compute-eigen-decomposition.d.ts +37 -0
  23. package/dist/culling/lib/algorithms/compute-eigen-decomposition.d.ts.map +1 -0
  24. package/dist/culling/lib/algorithms/compute-eigen-decomposition.js +137 -0
  25. package/dist/culling/lib/algorithms/compute-eigen-decomposition.js.map +1 -0
  26. package/dist/culling/lib/algorithms/oriented-bounding-box-quaternion.d.ts +7 -0
  27. package/dist/culling/lib/algorithms/oriented-bounding-box-quaternion.d.ts.map +1 -0
  28. package/dist/culling/lib/algorithms/oriented-bounding-box-quaternion.js +26 -0
  29. package/dist/culling/lib/algorithms/oriented-bounding-box-quaternion.js.map +1 -0
  30. package/dist/culling/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +56 -0
  31. package/dist/culling/lib/bounding-volumes/axis-aligned-bounding-box.d.ts.map +1 -0
  32. package/dist/culling/lib/bounding-volumes/axis-aligned-bounding-box.js +116 -0
  33. package/dist/culling/lib/bounding-volumes/axis-aligned-bounding-box.js.map +1 -0
  34. package/dist/culling/lib/bounding-volumes/bounding-sphere.d.ts +40 -0
  35. package/dist/culling/lib/bounding-volumes/bounding-sphere.d.ts.map +1 -0
  36. package/dist/culling/lib/bounding-volumes/bounding-sphere.js +123 -0
  37. package/dist/culling/lib/bounding-volumes/bounding-sphere.js.map +1 -0
  38. package/dist/culling/lib/bounding-volumes/bounding-volume.d.ts +30 -0
  39. package/dist/culling/lib/bounding-volumes/bounding-volume.d.ts.map +1 -0
  40. package/dist/culling/lib/bounding-volumes/bounding-volume.js +7 -0
  41. package/dist/culling/lib/bounding-volumes/bounding-volume.js.map +1 -0
  42. package/dist/culling/lib/bounding-volumes/oriented-bounding-box.d.ts +62 -0
  43. package/dist/culling/lib/bounding-volumes/oriented-bounding-box.d.ts.map +1 -0
  44. package/dist/culling/lib/bounding-volumes/oriented-bounding-box.js +230 -0
  45. package/dist/culling/lib/bounding-volumes/oriented-bounding-box.js.map +1 -0
  46. package/dist/culling/lib/culling-volume.d.ts +46 -0
  47. package/dist/culling/lib/culling-volume.d.ts.map +1 -0
  48. package/dist/culling/lib/culling-volume.js +126 -0
  49. package/dist/culling/lib/culling-volume.js.map +1 -0
  50. package/dist/culling/lib/perspective-frustum.d.ts +153 -0
  51. package/dist/culling/lib/perspective-frustum.d.ts.map +1 -0
  52. package/dist/culling/lib/perspective-frustum.js +191 -0
  53. package/dist/culling/lib/perspective-frustum.js.map +1 -0
  54. package/dist/culling/lib/perspective-off-center-frustum.d.ts +158 -0
  55. package/dist/culling/lib/perspective-off-center-frustum.d.ts.map +1 -0
  56. package/dist/culling/lib/perspective-off-center-frustum.js +276 -0
  57. package/dist/culling/lib/perspective-off-center-frustum.js.map +1 -0
  58. package/dist/culling/lib/plane.d.ts +35 -0
  59. package/dist/culling/lib/plane.d.ts.map +1 -0
  60. package/dist/culling/lib/plane.js +90 -0
  61. package/dist/culling/lib/plane.js.map +1 -0
  62. package/dist/culling/lib/ray.d.ts +13 -0
  63. package/dist/culling/lib/ray.d.ts.map +1 -0
  64. package/dist/culling/lib/ray.js +30 -0
  65. package/dist/culling/lib/ray.js.map +1 -0
  66. package/dist/culling/lib/shapes/box-shape.d.ts +19 -0
  67. package/dist/culling/lib/shapes/box-shape.d.ts.map +1 -0
  68. package/dist/culling/lib/shapes/box-shape.js +69 -0
  69. package/dist/culling/lib/shapes/box-shape.js.map +1 -0
  70. package/dist/culling/lib/shapes/capsule-shape.d.ts +23 -0
  71. package/dist/culling/lib/shapes/capsule-shape.d.ts.map +1 -0
  72. package/dist/culling/lib/shapes/capsule-shape.js +151 -0
  73. package/dist/culling/lib/shapes/capsule-shape.js.map +1 -0
  74. package/dist/culling/lib/shapes/cylinder-shape.d.ts +22 -0
  75. package/dist/culling/lib/shapes/cylinder-shape.d.ts.map +1 -0
  76. package/dist/culling/lib/shapes/cylinder-shape.js +99 -0
  77. package/dist/culling/lib/shapes/cylinder-shape.js.map +1 -0
  78. package/dist/culling/lib/shapes/implicit-shape.d.ts +56 -0
  79. package/dist/culling/lib/shapes/implicit-shape.d.ts.map +1 -0
  80. package/dist/culling/lib/shapes/implicit-shape.js +142 -0
  81. package/dist/culling/lib/shapes/implicit-shape.js.map +1 -0
  82. package/dist/culling/lib/shapes/plane-shape.d.ts +27 -0
  83. package/dist/culling/lib/shapes/plane-shape.d.ts.map +1 -0
  84. package/dist/culling/lib/shapes/plane-shape.js +71 -0
  85. package/dist/culling/lib/shapes/plane-shape.js.map +1 -0
  86. package/dist/culling/lib/shapes/sphere-shape.d.ts +18 -0
  87. package/dist/culling/lib/shapes/sphere-shape.d.ts.map +1 -0
  88. package/dist/culling/lib/shapes/sphere-shape.js +43 -0
  89. package/dist/culling/lib/shapes/sphere-shape.js.map +1 -0
  90. package/dist/culling/oriented-box-2d.cjs +73 -0
  91. package/dist/culling/oriented-box-2d.cjs.map +6 -0
  92. package/dist/culling/oriented-box-2d.d.ts +22 -0
  93. package/dist/culling/oriented-box-2d.d.ts.map +1 -0
  94. package/dist/culling/oriented-box-2d.js +86 -0
  95. package/dist/culling/oriented-box-2d.js.map +1 -0
  96. package/dist/culling/queries.cjs +161 -0
  97. package/dist/culling/queries.cjs.map +6 -0
  98. package/dist/culling/queries.d.ts +20 -0
  99. package/dist/culling/queries.d.ts.map +1 -0
  100. package/dist/culling/queries.js +139 -0
  101. package/dist/culling/queries.js.map +1 -0
  102. package/dist/curves/bezier-curves.d.ts +18 -0
  103. package/dist/curves/bezier-curves.d.ts.map +1 -0
  104. package/dist/curves/bezier-curves.js +54 -0
  105. package/dist/curves/bezier-curves.js.map +1 -0
  106. package/dist/curves/catmull-rom-curve.d.ts +15 -0
  107. package/dist/curves/catmull-rom-curve.d.ts.map +1 -0
  108. package/dist/curves/catmull-rom-curve.js +77 -0
  109. package/dist/curves/catmull-rom-curve.js.map +1 -0
  110. package/dist/curves/curve-arc-length.d.ts +17 -0
  111. package/dist/curves/curve-arc-length.d.ts.map +1 -0
  112. package/dist/curves/curve-arc-length.js +58 -0
  113. package/dist/curves/curve-arc-length.js.map +1 -0
  114. package/dist/curves/curve.d.ts +23 -0
  115. package/dist/curves/curve.d.ts.map +1 -0
  116. package/dist/curves/curve.js +77 -0
  117. package/dist/curves/curve.js.map +1 -0
  118. package/dist/curves/hermite-curve.d.ts +9 -0
  119. package/dist/curves/hermite-curve.d.ts.map +1 -0
  120. package/dist/curves/hermite-curve.js +24 -0
  121. package/dist/curves/hermite-curve.js.map +1 -0
  122. package/dist/curves/index.cjs +293 -0
  123. package/dist/curves/index.cjs.map +6 -0
  124. package/dist/curves/index.d.ts +8 -0
  125. package/dist/curves/index.d.ts.map +1 -0
  126. package/dist/curves/index.js +9 -0
  127. package/dist/curves/index.js.map +1 -0
  128. package/dist/geometries/box-geometry.js +1 -1
  129. package/dist/geometries/box-geometry.js.map +1 -1
  130. package/dist/geometries/capsule-geometry.js +1 -1
  131. package/dist/geometries/capsule-geometry.js.map +1 -1
  132. package/dist/geometries/cylinder-geometry.js +1 -1
  133. package/dist/geometries/cylinder-geometry.js.map +1 -1
  134. package/dist/geometries/geometry-helpers.js +1 -1
  135. package/dist/geometries/geometry-helpers.js.map +1 -1
  136. package/dist/geometries/ico-sphere-geometry.js +1 -1
  137. package/dist/geometries/ico-sphere-geometry.js.map +1 -1
  138. package/dist/geometries/plane-geometry.js +1 -1
  139. package/dist/geometries/plane-geometry.js.map +1 -1
  140. package/dist/geometries/primitive-mesh-builder.d.ts +24 -0
  141. package/dist/geometries/primitive-mesh-builder.d.ts.map +1 -0
  142. package/dist/geometries/primitive-mesh-builder.js +74 -0
  143. package/dist/geometries/primitive-mesh-builder.js.map +1 -0
  144. package/dist/geometries/prism-geometry.d.ts +13 -0
  145. package/dist/geometries/prism-geometry.d.ts.map +1 -0
  146. package/dist/geometries/prism-geometry.js +34 -0
  147. package/dist/geometries/prism-geometry.js.map +1 -0
  148. package/dist/geometries/ring-geometry.d.ts +15 -0
  149. package/dist/geometries/ring-geometry.d.ts.map +1 -0
  150. package/dist/geometries/ring-geometry.js +64 -0
  151. package/dist/geometries/ring-geometry.js.map +1 -0
  152. package/dist/geometries/sphere-geometry.js +1 -1
  153. package/dist/geometries/sphere-geometry.js.map +1 -1
  154. package/dist/geometries/surface-of-revolution.js +1 -1
  155. package/dist/geometries/surface-of-revolution.js.map +1 -1
  156. package/dist/geometries/truncated-cone-geometry.js +1 -1
  157. package/dist/geometries/truncated-cone-geometry.js.map +1 -1
  158. package/dist/index.cjs +290 -9
  159. package/dist/index.cjs.map +3 -3
  160. package/dist/index.d.ts +6 -0
  161. package/dist/index.d.ts.map +1 -1
  162. package/dist/index.js +4 -1
  163. package/dist/index.js.map +1 -1
  164. package/dist/lib/geometry-utils.js +1 -1
  165. package/dist/lib/geometry-utils.js.map +1 -1
  166. package/dist/lib/geometry.d.ts +1 -1
  167. package/dist/lib/geometry.d.ts.map +1 -1
  168. package/dist/lib/geometry.js +1 -1
  169. package/dist/lib/geometry.js.map +1 -1
  170. package/dist/lib/hinge-tree.d.ts +33 -0
  171. package/dist/lib/hinge-tree.d.ts.map +1 -0
  172. package/dist/lib/hinge-tree.js +144 -0
  173. package/dist/lib/hinge-tree.js.map +1 -0
  174. package/dist/parametric/lathe-geometry.d.ts +14 -0
  175. package/dist/parametric/lathe-geometry.d.ts.map +1 -0
  176. package/dist/parametric/lathe-geometry.js +48 -0
  177. package/dist/parametric/lathe-geometry.js.map +1 -0
  178. package/dist/parametric/parametric-geometry.d.ts +20 -0
  179. package/dist/parametric/parametric-geometry.d.ts.map +1 -0
  180. package/dist/parametric/parametric-geometry.js +88 -0
  181. package/dist/parametric/parametric-geometry.js.map +1 -0
  182. package/dist/parametric/torus-geometry.d.ts +19 -0
  183. package/dist/parametric/torus-geometry.d.ts.map +1 -0
  184. package/dist/parametric/torus-geometry.js +89 -0
  185. package/dist/parametric/torus-geometry.js.map +1 -0
  186. package/dist/parametric.cjs +328 -0
  187. package/dist/parametric.cjs.map +6 -0
  188. package/dist/parametric.d.ts +7 -0
  189. package/dist/parametric.d.ts.map +1 -0
  190. package/dist/parametric.js +7 -0
  191. package/dist/parametric.js.map +1 -0
  192. package/dist/polygon/cut-by-grid.d.ts +24 -0
  193. package/dist/polygon/cut-by-grid.d.ts.map +1 -0
  194. package/dist/polygon/cut-by-grid.js +221 -0
  195. package/dist/polygon/cut-by-grid.js.map +1 -0
  196. package/dist/polygon/cut-by-mercator-bounds.d.ts +17 -0
  197. package/dist/polygon/cut-by-mercator-bounds.d.ts.map +1 -0
  198. package/dist/polygon/cut-by-mercator-bounds.js +149 -0
  199. package/dist/polygon/cut-by-mercator-bounds.js.map +1 -0
  200. package/dist/polygon/earcut.d.ts +13 -0
  201. package/dist/polygon/earcut.d.ts.map +1 -0
  202. package/dist/polygon/earcut.js +627 -0
  203. package/dist/polygon/earcut.js.map +1 -0
  204. package/dist/polygon/index.cjs +1437 -0
  205. package/dist/polygon/index.cjs.map +6 -0
  206. package/dist/polygon/index.d.ts +12 -0
  207. package/dist/polygon/index.d.ts.map +1 -0
  208. package/dist/polygon/index.js +12 -0
  209. package/dist/polygon/index.js.map +1 -0
  210. package/dist/polygon/lineclip.d.ts +31 -0
  211. package/dist/polygon/lineclip.d.ts.map +1 -0
  212. package/dist/polygon/lineclip.js +184 -0
  213. package/dist/polygon/lineclip.js.map +1 -0
  214. package/dist/polygon/polygon-utils.d.ts +103 -0
  215. package/dist/polygon/polygon-utils.d.ts.map +1 -0
  216. package/dist/polygon/polygon-utils.js +155 -0
  217. package/dist/polygon/polygon-utils.js.map +1 -0
  218. package/dist/polygon/polygon.d.ts +41 -0
  219. package/dist/polygon/polygon.d.ts.map +1 -0
  220. package/dist/polygon/polygon.js +76 -0
  221. package/dist/polygon/polygon.js.map +1 -0
  222. package/dist/polygon/subdivide-polyline.d.ts +56 -0
  223. package/dist/polygon/subdivide-polyline.d.ts.map +1 -0
  224. package/dist/polygon/subdivide-polyline.js +141 -0
  225. package/dist/polygon/subdivide-polyline.js.map +1 -0
  226. package/dist/polygon/subdivide-triangle-mesh.d.ts +68 -0
  227. package/dist/polygon/subdivide-triangle-mesh.d.ts.map +1 -0
  228. package/dist/polygon/subdivide-triangle-mesh.js +228 -0
  229. package/dist/polygon/subdivide-triangle-mesh.js.map +1 -0
  230. package/dist/polygon/utils.d.ts +5 -0
  231. package/dist/polygon/utils.d.ts.map +1 -0
  232. package/dist/polygon/utils.js +38 -0
  233. package/dist/polygon/utils.js.map +1 -0
  234. package/dist/spatial-index/box-index.cjs +328 -0
  235. package/dist/spatial-index/box-index.cjs.map +6 -0
  236. package/dist/spatial-index/box-index.d.ts +65 -0
  237. package/dist/spatial-index/box-index.d.ts.map +1 -0
  238. package/dist/spatial-index/box-index.js +263 -0
  239. package/dist/spatial-index/box-index.js.map +1 -0
  240. package/dist/spatial-index/index.cjs +494 -0
  241. package/dist/spatial-index/index.cjs.map +6 -0
  242. package/dist/spatial-index/index.d.ts +5 -0
  243. package/dist/spatial-index/index.d.ts.map +1 -0
  244. package/dist/spatial-index/index.js +6 -0
  245. package/dist/spatial-index/index.js.map +1 -0
  246. package/dist/spatial-index/triangle-bvh.d.ts +53 -0
  247. package/dist/spatial-index/triangle-bvh.d.ts.map +1 -0
  248. package/dist/spatial-index/triangle-bvh.js +102 -0
  249. package/dist/spatial-index/triangle-bvh.js.map +1 -0
  250. package/dist/utils/attribute-compression.d.ts +50 -0
  251. package/dist/utils/attribute-compression.d.ts.map +1 -0
  252. package/dist/utils/attribute-compression.js +186 -0
  253. package/dist/utils/attribute-compression.js.map +1 -0
  254. package/dist/utils/attribute-iterator.d.ts +8 -0
  255. package/dist/utils/attribute-iterator.d.ts.map +1 -0
  256. package/dist/utils/attribute-iterator.js +25 -0
  257. package/dist/utils/attribute-iterator.js.map +1 -0
  258. package/dist/utils/compute-vertex-normals.d.ts +4 -0
  259. package/dist/utils/compute-vertex-normals.d.ts.map +1 -0
  260. package/dist/utils/compute-vertex-normals.js +54 -0
  261. package/dist/utils/compute-vertex-normals.js.map +1 -0
  262. package/dist/utils/constants.d.ts +52 -0
  263. package/dist/utils/constants.d.ts.map +1 -0
  264. package/dist/utils/constants.js +39 -0
  265. package/dist/utils/constants.js.map +1 -0
  266. package/dist/utils/coordinates.d.ts +3 -0
  267. package/dist/utils/coordinates.d.ts.map +1 -0
  268. package/dist/utils/coordinates.js +8 -0
  269. package/dist/utils/coordinates.js.map +1 -0
  270. package/dist/utils/geometry.d.ts +20 -0
  271. package/dist/utils/geometry.d.ts.map +1 -0
  272. package/dist/utils/geometry.js +31 -0
  273. package/dist/utils/geometry.js.map +1 -0
  274. package/dist/utils/gl-type.d.ts +17 -0
  275. package/dist/utils/gl-type.d.ts.map +1 -0
  276. package/dist/utils/gl-type.js +69 -0
  277. package/dist/utils/gl-type.js.map +1 -0
  278. package/dist/utils/index.cjs +965 -0
  279. package/dist/utils/index.cjs.map +6 -0
  280. package/dist/utils/index.d.ts +18 -0
  281. package/dist/utils/index.d.ts.map +1 -0
  282. package/dist/utils/index.js +16 -0
  283. package/dist/utils/index.js.map +1 -0
  284. package/dist/utils/interpolate-packed-attributes.cjs +176 -0
  285. package/dist/utils/interpolate-packed-attributes.cjs.map +6 -0
  286. package/dist/utils/interpolate-packed-attributes.d.ts +43 -0
  287. package/dist/utils/interpolate-packed-attributes.d.ts.map +1 -0
  288. package/dist/utils/interpolate-packed-attributes.js +192 -0
  289. package/dist/utils/interpolate-packed-attributes.js.map +1 -0
  290. package/dist/utils/mesh-processing.d.ts +18 -0
  291. package/dist/utils/mesh-processing.d.ts.map +1 -0
  292. package/dist/utils/mesh-processing.js +300 -0
  293. package/dist/utils/mesh-processing.js.map +1 -0
  294. package/dist/utils/primitive-iterator.d.ts +21 -0
  295. package/dist/utils/primitive-iterator.d.ts.map +1 -0
  296. package/dist/utils/primitive-iterator.js +117 -0
  297. package/dist/utils/primitive-iterator.js.map +1 -0
  298. package/dist/utils/rgb565.d.ts +5 -0
  299. package/dist/utils/rgb565.d.ts.map +1 -0
  300. package/dist/utils/rgb565.js +24 -0
  301. package/dist/utils/rgb565.js.map +1 -0
  302. package/dist/utils/typed-array-utils.d.ts +3 -0
  303. package/dist/utils/typed-array-utils.d.ts.map +1 -0
  304. package/dist/utils/typed-array-utils.js +16 -0
  305. package/dist/utils/typed-array-utils.js.map +1 -0
  306. package/package.json +57 -4
  307. package/src/culling/constants.ts +6 -0
  308. package/src/culling/index.ts +45 -0
  309. package/src/culling/lib/algorithms/bounding-box-from-points.ts +174 -0
  310. package/src/culling/lib/algorithms/bounding-sphere-from-points.ts +175 -0
  311. package/src/culling/lib/algorithms/compute-eigen-decomposition.ts +171 -0
  312. package/src/culling/lib/algorithms/oriented-bounding-box-quaternion.ts +32 -0
  313. package/src/culling/lib/bounding-volumes/axis-aligned-bounding-box.ts +153 -0
  314. package/src/culling/lib/bounding-volumes/bounding-sphere.ts +154 -0
  315. package/src/culling/lib/bounding-volumes/bounding-volume.ts +38 -0
  316. package/src/culling/lib/bounding-volumes/oriented-bounding-box.ts +320 -0
  317. package/src/culling/lib/culling-volume.ts +163 -0
  318. package/src/culling/lib/perspective-frustum.ts +288 -0
  319. package/src/culling/lib/perspective-off-center-frustum.ts +381 -0
  320. package/src/culling/lib/plane.ts +118 -0
  321. package/src/culling/lib/ray.ts +33 -0
  322. package/src/culling/lib/shapes/box-shape.ts +78 -0
  323. package/src/culling/lib/shapes/capsule-shape.ts +232 -0
  324. package/src/culling/lib/shapes/cylinder-shape.ts +133 -0
  325. package/src/culling/lib/shapes/implicit-shape.ts +209 -0
  326. package/src/culling/lib/shapes/plane-shape.ts +78 -0
  327. package/src/culling/lib/shapes/sphere-shape.ts +60 -0
  328. package/src/culling/oriented-box-2d.ts +165 -0
  329. package/src/culling/queries.ts +155 -0
  330. package/src/curves/bezier-curves.ts +62 -0
  331. package/src/curves/catmull-rom-curve.ts +89 -0
  332. package/src/curves/curve-arc-length.ts +70 -0
  333. package/src/curves/curve.ts +96 -0
  334. package/src/curves/hermite-curve.ts +34 -0
  335. package/src/curves/index.ts +15 -0
  336. package/src/geometries/box-geometry.ts +1 -1
  337. package/src/geometries/capsule-geometry.ts +1 -1
  338. package/src/geometries/cylinder-geometry.ts +1 -1
  339. package/src/geometries/geometry-helpers.ts +1 -1
  340. package/src/geometries/ico-sphere-geometry.ts +1 -1
  341. package/src/geometries/plane-geometry.ts +1 -1
  342. package/src/geometries/primitive-mesh-builder.ts +84 -0
  343. package/src/geometries/prism-geometry.ts +57 -0
  344. package/src/geometries/ring-geometry.ts +102 -0
  345. package/src/geometries/sphere-geometry.ts +1 -1
  346. package/src/geometries/surface-of-revolution.ts +1 -1
  347. package/src/geometries/truncated-cone-geometry.ts +1 -1
  348. package/src/index.ts +10 -1
  349. package/src/lib/geometry-utils.ts +2 -2
  350. package/src/lib/geometry.ts +2 -2
  351. package/src/lib/hinge-tree.ts +170 -0
  352. package/src/parametric/lathe-geometry.ts +70 -0
  353. package/src/parametric/parametric-geometry.ts +118 -0
  354. package/src/parametric/torus-geometry.ts +118 -0
  355. package/src/parametric.ts +9 -0
  356. package/src/polygon/cut-by-grid.ts +313 -0
  357. package/src/polygon/cut-by-mercator-bounds.ts +204 -0
  358. package/src/polygon/earcut.ts +798 -0
  359. package/src/polygon/index.ts +35 -0
  360. package/src/polygon/lineclip.ts +218 -0
  361. package/src/polygon/polygon-utils.ts +273 -0
  362. package/src/polygon/polygon.ts +105 -0
  363. package/src/polygon/subdivide-polyline.ts +223 -0
  364. package/src/polygon/subdivide-triangle-mesh.ts +322 -0
  365. package/src/polygon/utils.ts +50 -0
  366. package/src/spatial-index/box-index.ts +343 -0
  367. package/src/spatial-index/index.ts +18 -0
  368. package/src/spatial-index/triangle-bvh.ts +162 -0
  369. package/src/utils/attribute-compression.ts +234 -0
  370. package/src/utils/attribute-iterator.ts +28 -0
  371. package/src/utils/compute-vertex-normals.ts +63 -0
  372. package/src/utils/constants.ts +42 -0
  373. package/src/utils/coordinates.ts +8 -0
  374. package/src/utils/geometry.ts +49 -0
  375. package/src/utils/gl-type.ts +87 -0
  376. package/src/utils/index.ts +55 -0
  377. package/src/utils/interpolate-packed-attributes.ts +284 -0
  378. package/src/utils/mesh-processing.ts +377 -0
  379. package/src/utils/primitive-iterator.ts +145 -0
  380. package/src/utils/rgb565.ts +26 -0
  381. package/src/utils/typed-array-utils.ts +16 -0
@@ -0,0 +1,223 @@
1
+ // math.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // SPDX-FileCopyrightText: Copyright (c) vis.gl contributors
4
+
5
+ /** A constant-speed source edge, sampled at fractions of its declared length.
6
+ * Endpoints must match the factory inputs exactly. Samples are copied before use.
7
+ */
8
+ export type PolylineEdgeSampler = {
9
+ readonly length: number;
10
+ sample: (fraction: number) => ArrayLike<number>;
11
+ };
12
+
13
+ /** Configuration for sampling source edges through a nonlinear transform. */
14
+ export type SubdividePolylineOptions = {
15
+ /** Maps a source position to target coordinates; null or nonfinite output rejects the geometry.
16
+ * Must be deterministic. A fresh array is passed on every invocation.
17
+ */
18
+ transform: (position: readonly number[]) => ArrayLike<number> | null;
19
+ /** Positive error tolerance in target-coordinate units, measured across all output components. */
20
+ tolerance: number;
21
+ /** Optional factory, called once per original edge with independent endpoint copies.
22
+ * Without it, source coordinates interpolate linearly. Must be deterministic.
23
+ */
24
+ createEdgeSampler?: (
25
+ start: readonly number[],
26
+ end: readonly number[],
27
+ segmentIndex: number
28
+ ) => PolylineEdgeSampler;
29
+ /** Number of source components per vertex. Default 2. */
30
+ size?: 2 | 3;
31
+ /** Number of target components per vertex. Defaults to size. */
32
+ targetSize?: 2 | 3;
33
+ /** Positive maximum leaf length: Euclidean source distance by default, or the
34
+ * custom sampler's declared length multiplied by its fraction interval.
35
+ */
36
+ maxSegmentLength?: number;
37
+ /** Maximum bisection depth per input edge. Default 16; maximum 30. */
38
+ maxDepth?: number;
39
+ /** Maximum output vertex count for the entire polyline. Default 65536. */
40
+ maxVertices?: number;
41
+ };
42
+
43
+ /** Subdivided source and target coordinates with attribution for interpolating other data. */
44
+ export type SubdividedPolyline = {
45
+ /** Flat source positions, including inserted vertices. Input storage is never modified. */
46
+ sourcePositions: Float64Array;
47
+ /** Flat transformed positions, in the transform's target units. */
48
+ positions: Float64Array;
49
+ /** Input edge index for each output vertex. Edge i connects input vertices i and i + 1.
50
+ * Shared endpoints belong to the preceding edge; a lone input vertex uses index 0.
51
+ */
52
+ segmentIndices: Uint32Array;
53
+ /** Fraction along the attributed input edge. The first vertex uses 0; endpoints use 1. */
54
+ segmentFractions: Float64Array;
55
+ };
56
+
57
+ type Sample = {source: number[]; target: number[]; fraction: number};
58
+
59
+ /** Adaptively subdivides a flat polyline by sampling a supplied coordinate transform.
60
+ * Each leaf edge checks its quarter, midpoint and three-quarter positions against linear
61
+ * interpolation of its target endpoints. This is a sampled criterion, not a guaranteed
62
+ * bound for arbitrary transforms. Source components interpolate linearly unless a custom
63
+ * constant-speed source-edge sampler is supplied.
64
+ * Explicitly closed rings stay closed. Split seams and clip invalid domains before calling.
65
+ * @throws RangeError For invalid options/coordinates, rejected transform samples, or exhausted limits.
66
+ * Exceptions thrown by the transform itself propagate unchanged.
67
+ */
68
+ export function subdividePolyline(
69
+ input: ArrayLike<number>,
70
+ options: SubdividePolylineOptions
71
+ ): SubdividedPolyline {
72
+ const {
73
+ transform,
74
+ tolerance,
75
+ createEdgeSampler,
76
+ size = 2,
77
+ targetSize = size,
78
+ maxSegmentLength = Infinity,
79
+ maxDepth = 16,
80
+ maxVertices = 65536
81
+ } = options;
82
+ if (
83
+ typeof transform !== 'function' ||
84
+ (createEdgeSampler !== undefined && typeof createEdgeSampler !== 'function') ||
85
+ !Number.isFinite(tolerance) ||
86
+ tolerance <= 0 ||
87
+ (size !== 2 && size !== 3) ||
88
+ (targetSize !== 2 && targetSize !== 3) ||
89
+ !(maxSegmentLength > 0) ||
90
+ (!Number.isFinite(maxSegmentLength) && maxSegmentLength !== Infinity) ||
91
+ !Number.isInteger(maxDepth) ||
92
+ maxDepth < 0 ||
93
+ maxDepth > 30 ||
94
+ !Number.isSafeInteger(maxVertices) ||
95
+ maxVertices < 1 ||
96
+ maxVertices > 0xffffffff ||
97
+ !Number.isSafeInteger(input.length) ||
98
+ input.length < 0 ||
99
+ input.length % size !== 0
100
+ ) {
101
+ throw new RangeError('Invalid polyline subdivision options or input length');
102
+ }
103
+ const vertexCount = input.length / size;
104
+ if (vertexCount > maxVertices) throw new RangeError('Polyline exceeds maxVertices');
105
+ const sources: number[] = [];
106
+ for (let i = 0; i < input.length; i++) {
107
+ const value = input[i];
108
+ if (!Number.isFinite(value)) throw new RangeError('Source positions must be finite');
109
+ sources.push(value);
110
+ }
111
+ const sourcePositions: number[] = [];
112
+ const positions: number[] = [];
113
+ const segmentIndices: number[] = [];
114
+ const segmentFractions: number[] = [];
115
+
116
+ function sample(source: number[], fraction: number): Sample {
117
+ const projected = transform(source.slice());
118
+ if (!projected || projected.length !== targetSize) {
119
+ throw new RangeError('Transform must return a position with targetSize components');
120
+ }
121
+ const target = Array.from(projected);
122
+ if (!target.every(Number.isFinite))
123
+ throw new RangeError('Transform returned nonfinite coordinates');
124
+ return {source, target, fraction};
125
+ }
126
+
127
+ function append(point: Sample, segment: number): void {
128
+ if (segmentIndices.length >= maxVertices) {
129
+ throw new RangeError('Polyline subdivision exceeded maxVertices');
130
+ }
131
+ for (const value of point.source) sourcePositions.push(value);
132
+ for (const value of point.target) positions.push(value);
133
+ segmentIndices.push(segment);
134
+ segmentFractions.push(point.fraction);
135
+ }
136
+
137
+ function sampledSource(sampler: PolylineEdgeSampler, fraction: number): number[] {
138
+ const value = sampler.sample(fraction);
139
+ if (!value || value.length !== size) throw new RangeError('Invalid source-edge sample size');
140
+ const source = Array.from(value);
141
+ if (!source.every(Number.isFinite)) throw new RangeError('Nonfinite source-edge sample');
142
+ return source;
143
+ }
144
+
145
+ function interpolate(
146
+ a: Sample,
147
+ b: Sample,
148
+ fraction: number,
149
+ sampler?: PolylineEdgeSampler
150
+ ): Sample {
151
+ const originalFraction = a.fraction * (1 - fraction) + b.fraction * fraction;
152
+ // Always sample the original edge, never a new curve fitted to recursive endpoints.
153
+ const source = sampler
154
+ ? sampledSource(sampler, originalFraction)
155
+ : a.source.map((value, i) => value * (1 - fraction) + b.source[i] * fraction);
156
+ return sample(source, originalFraction);
157
+ }
158
+
159
+ function subdivide(
160
+ a: Sample,
161
+ b: Sample,
162
+ segment: number,
163
+ depth: number,
164
+ sampler?: PolylineEdgeSampler
165
+ ): void {
166
+ let error = 0;
167
+ let midpoint: Sample;
168
+ for (const fraction of [0.25, 0.5, 0.75]) {
169
+ const point = interpolate(a, b, fraction, sampler);
170
+ if (fraction === 0.5) midpoint = point;
171
+ const delta = point.target.map(
172
+ (value, i) => value - (a.target[i] * (1 - fraction) + b.target[i] * fraction)
173
+ );
174
+ error = Math.max(error, Math.hypot(...delta));
175
+ }
176
+ const sourceLength = sampler
177
+ ? sampler.length * (b.fraction - a.fraction)
178
+ : Math.hypot(...a.source.map((value, i) => value - b.source[i]));
179
+ if (error <= tolerance && sourceLength <= maxSegmentLength) {
180
+ append(b, segment);
181
+ return;
182
+ }
183
+ if (depth >= maxDepth) {
184
+ throw new RangeError(`Polyline subdivision exceeded maxDepth on input edge ${segment}`);
185
+ }
186
+ subdivide(a, midpoint!, segment, depth + 1, sampler);
187
+ subdivide(midpoint!, b, segment, depth + 1, sampler);
188
+ }
189
+
190
+ if (vertexCount) {
191
+ let previous = sample(sources.slice(0, size), 0);
192
+ append(previous, 0);
193
+ for (let i = 1; i < vertexCount; i++) {
194
+ const next = sample(sources.slice(i * size, (i + 1) * size), 1);
195
+ const start = {...previous, fraction: 0};
196
+ const sampler = createEdgeSampler?.(start.source.slice(), next.source.slice(), i - 1);
197
+ if (createEdgeSampler) {
198
+ if (
199
+ !sampler ||
200
+ typeof sampler.sample !== 'function' ||
201
+ !Number.isFinite(sampler.length) ||
202
+ sampler.length < 0
203
+ ) {
204
+ throw new RangeError('Invalid source-edge sampler');
205
+ }
206
+ for (const endpoint of [start, next]) {
207
+ const sampled = sampledSource(sampler, endpoint.fraction);
208
+ if (sampled.some((value, component) => value !== endpoint.source[component])) {
209
+ throw new RangeError('Source-edge sampler endpoints must match input');
210
+ }
211
+ }
212
+ }
213
+ subdivide(start, next, i - 1, 0, sampler);
214
+ previous = next;
215
+ }
216
+ }
217
+ return {
218
+ sourcePositions: new Float64Array(sourcePositions),
219
+ positions: new Float64Array(positions),
220
+ segmentIndices: new Uint32Array(segmentIndices),
221
+ segmentFractions: new Float64Array(segmentFractions)
222
+ };
223
+ }
@@ -0,0 +1,322 @@
1
+ // math.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // SPDX-FileCopyrightText: Copyright (c) vis.gl contributors
4
+
5
+ /** A flat, indexed triangle mesh. Vertices at attribute seams must have distinct indices. */
6
+ export type TriangleMesh = {
7
+ /** Flat source positions. */
8
+ positions: ArrayLike<number>;
9
+ /** Three vertex indices per triangle, with consistent winding. */
10
+ indices: ArrayLike<number>;
11
+ };
12
+
13
+ /** Controls adaptive subdivision through an application-supplied coordinate transform. */
14
+ type SubdivisionOptions = {
15
+ /** Deterministic source-to-target conversion. Each invocation receives a fresh source array.
16
+ * Null and nonfinite output reject the mesh; callback exceptions propagate unchanged.
17
+ */
18
+ transform: (position: readonly number[]) => ArrayLike<number> | null;
19
+ /** Source dimension: 2 or 3. Default 2. */
20
+ size?: 2 | 3;
21
+ /** Target dimension: 2 or 3. Defaults to size. */
22
+ targetSize?: 2 | 3;
23
+ /** Maximum global refinement passes, from 0 through 30. Default 10. */
24
+ maxDepth?: number;
25
+ /** Maximum output vertex count, including unused input vertices. Default 65536. */
26
+ maxVertices?: number;
27
+ /** Maximum output triangle count. Default 131072. */
28
+ maxTriangles?: number;
29
+ };
30
+
31
+ /** Select sampled transform error (default), or exclusively limit source-edge length. */
32
+ export type SubdivideTriangleMeshOptions = SubdivisionOptions &
33
+ (
34
+ | {
35
+ /** Sample target-space error, including triangle interiors. This is the default. */
36
+ refinement?: 'transform-error';
37
+ /** Positive, finite sampled error tolerance across target components, in target units. */
38
+ tolerance: number;
39
+ /** Positive maximum Euclidean source-edge length. Default Infinity. */
40
+ maxEdgeLength?: number;
41
+ }
42
+ | {
43
+ /** Split only long indexed edges, without evaluating transform-error probes. */
44
+ refinement: 'source-edge';
45
+ /** No target-space tolerance is evaluated in source-edge mode. */
46
+ tolerance?: never;
47
+ /** Positive, finite maximum Euclidean edge length across all source components. */
48
+ maxEdgeLength: number;
49
+ }
50
+ );
51
+
52
+ /** Refined geometry with provenance for interpolating UVs and other source vertex attributes. */
53
+ export type SubdividedTriangleMesh = {
54
+ /** Flat source coordinates, including inserted vertices. */
55
+ sourcePositions: Float64Array;
56
+ /** Flat transformed coordinates, suitable for rendering. */
57
+ positions: Float64Array;
58
+ /** Refined triangle indices; input winding is preserved in source space. */
59
+ indices: Uint32Array;
60
+ /** Three original input vertex indices per output vertex. Unused slots use index 0. */
61
+ sourceVertexIndices: Uint32Array;
62
+ /** Three corresponding weights per output vertex, summing to one. */
63
+ sourceVertexWeights: Float64Array;
64
+ /** Original input triangle index for each output triangle. */
65
+ sourceTriangleIndices: Uint32Array;
66
+ };
67
+
68
+ type Vertex = {source: number[]; target: number[]; weights: Map<number, number>};
69
+ type Face = {vertices: [number, number, number]; sourceTriangle: number};
70
+
71
+ const EDGE_FRACTIONS = [0.25, 0.5, 0.75];
72
+ const FACE_WEIGHTS = [
73
+ [1 / 3, 1 / 3, 1 / 3],
74
+ [0.5, 0.25, 0.25],
75
+ [0.25, 0.5, 0.25],
76
+ [0.25, 0.25, 0.5]
77
+ ];
78
+
79
+ /** Refines a conforming triangle mesh to approximate a nonlinear coordinate transform.
80
+ * Checks edge quarter/midpoint samples and four interior barycentric samples. Failing faces
81
+ * split all three edges; neighbors split matching edges so no new T-junctions are introduced.
82
+ * The tolerance is sampled, not a universal error bound. Source interpolation is linear.
83
+ * Clip invalid domains and split projection seams before calling. Attribute seams must use
84
+ * duplicated input vertices; equal coordinates are never welded.
85
+ * Opt-in source-edge refinement skips error probes and transforms each output vertex once.
86
+ * It provides no target-space error bound or interior-domain validation.
87
+ * @throws RangeError For invalid input/options, rejected transform samples, or exhausted limits.
88
+ */
89
+ export function subdivideTriangleMesh(
90
+ mesh: TriangleMesh,
91
+ options: SubdivideTriangleMeshOptions
92
+ ): SubdividedTriangleMesh {
93
+ const {
94
+ transform,
95
+ tolerance,
96
+ refinement = 'transform-error',
97
+ size = 2,
98
+ targetSize = size,
99
+ maxEdgeLength = Infinity,
100
+ maxDepth = 10,
101
+ maxVertices = 65536,
102
+ maxTriangles = 131072
103
+ } = options;
104
+ validateOptions();
105
+ const vertices: Vertex[] = [];
106
+ let faces: Face[] = [];
107
+ for (let i = 0; i < mesh.positions.length; i += size) {
108
+ const source = Array.from({length: size}, (_, j) => mesh.positions[i + j]);
109
+ if (!source.every(Number.isFinite)) throw new RangeError('Source positions must be finite');
110
+ vertices.push({source, target: project(source), weights: new Map([[i / size, 1]])});
111
+ }
112
+ for (let i = 0; i < mesh.indices.length; i += 3) {
113
+ const indices = Array.from({length: 3}, (_, j) => mesh.indices[i + j]);
114
+ if (!indices.every(index => Number.isInteger(index) && index >= 0 && index < vertices.length)) {
115
+ throw new RangeError('Triangle indices must reference input vertices');
116
+ }
117
+ faces.push({vertices: indices as [number, number, number], sourceTriangle: i / 3});
118
+ }
119
+
120
+ for (let depth = 0; ; depth++) {
121
+ const splitEdges = new Set<string>();
122
+ for (const face of faces) {
123
+ if (refinement === 'source-edge') {
124
+ for (let edge = 0; edge < 3; edge++) {
125
+ const a = face.vertices[edge];
126
+ const b = face.vertices[(edge + 1) % 3];
127
+ if (sourceEdgeLength(vertices[a], vertices[b]) > maxEdgeLength) {
128
+ splitEdges.add(edgeKey(a, b));
129
+ }
130
+ }
131
+ } else if (needsRefinement(face)) {
132
+ const [a, b, c] = face.vertices;
133
+ splitEdges.add(edgeKey(a, b));
134
+ splitEdges.add(edgeKey(b, c));
135
+ splitEdges.add(edgeKey(c, a));
136
+ }
137
+ }
138
+ if (!splitEdges.size) return buildResult();
139
+ if (depth >= maxDepth) throw new RangeError('Triangle mesh subdivision exceeded maxDepth');
140
+ const midpoints = new Map<string, number>();
141
+ const refined: Face[] = [];
142
+ for (const face of faces) {
143
+ splitFace(face, refined, splitEdges, midpoints);
144
+ }
145
+ faces = refined;
146
+ }
147
+
148
+ function validateOptions(): void {
149
+ if (
150
+ typeof transform !== 'function' ||
151
+ (refinement !== 'transform-error' && refinement !== 'source-edge') ||
152
+ (refinement === 'transform-error' &&
153
+ (tolerance === undefined || !Number.isFinite(tolerance) || tolerance <= 0)) ||
154
+ (refinement === 'source-edge' &&
155
+ (tolerance !== undefined || !Number.isFinite(maxEdgeLength))) ||
156
+ (size !== 2 && size !== 3) ||
157
+ (targetSize !== 2 && targetSize !== 3) ||
158
+ !(maxEdgeLength > 0) ||
159
+ (!Number.isFinite(maxEdgeLength) && maxEdgeLength !== Infinity) ||
160
+ !Number.isInteger(maxDepth) ||
161
+ maxDepth < 0 ||
162
+ maxDepth > 30 ||
163
+ !validLimit(maxVertices) ||
164
+ !validLimit(maxTriangles) ||
165
+ !Number.isSafeInteger(mesh.positions.length) ||
166
+ mesh.positions.length < 0 ||
167
+ mesh.positions.length % size !== 0 ||
168
+ !Number.isSafeInteger(mesh.indices.length) ||
169
+ mesh.indices.length < 0 ||
170
+ mesh.indices.length % 3 !== 0
171
+ )
172
+ throw new RangeError('Invalid triangle mesh subdivision options or input lengths');
173
+ if (mesh.positions.length / size > maxVertices || mesh.indices.length / 3 > maxTriangles) {
174
+ throw new RangeError('Input mesh exceeds subdivision limits');
175
+ }
176
+ }
177
+
178
+ function project(source: number[]): number[] {
179
+ const result = transform(source.slice());
180
+ if (!result || result.length !== targetSize) {
181
+ throw new RangeError('Transform must return targetSize components');
182
+ }
183
+ const target = Array.from(result);
184
+ if (!target.every(Number.isFinite))
185
+ throw new RangeError('Transform returned nonfinite coordinates');
186
+ return target;
187
+ }
188
+
189
+ function error(points: Vertex[], weights: number[]): number {
190
+ const source = blend(
191
+ points.map(p => p.source),
192
+ weights
193
+ );
194
+ const linearTarget = blend(
195
+ points.map(p => p.target),
196
+ weights
197
+ );
198
+ return Math.hypot(...project(source).map((value, i) => value - linearTarget[i]));
199
+ }
200
+
201
+ function needsRefinement(face: Face): boolean {
202
+ const points = face.vertices.map(index => vertices[index]);
203
+ let exceedsTolerance = false;
204
+ for (let i = 0; i < 3; i++) {
205
+ const a = points[i];
206
+ const b = points[(i + 1) % 3];
207
+ const length = sourceEdgeLength(a, b);
208
+ if (length > maxEdgeLength) exceedsTolerance = true;
209
+ for (const fraction of EDGE_FRACTIONS) {
210
+ if (error([a, b], [1 - fraction, fraction]) > (tolerance ?? Infinity))
211
+ exceedsTolerance = true;
212
+ }
213
+ }
214
+ for (const weights of FACE_WEIGHTS) {
215
+ if (error(points, weights) > (tolerance ?? Infinity)) exceedsTolerance = true;
216
+ }
217
+ return exceedsTolerance;
218
+ }
219
+
220
+ function midpoint(a: number, b: number, midpoints: Map<string, number>): number {
221
+ const key = edgeKey(a, b);
222
+ const existing = midpoints.get(key);
223
+ if (existing !== undefined) return existing;
224
+ if (vertices.length >= maxVertices)
225
+ throw new RangeError('Triangle mesh subdivision exceeded maxVertices');
226
+ const source = blend([vertices[a].source, vertices[b].source], [0.5, 0.5]);
227
+ const weights = new Map<number, number>();
228
+ for (const vertex of [vertices[a], vertices[b]]) {
229
+ for (const [index, weight] of vertex.weights) {
230
+ weights.set(index, (weights.get(index) || 0) + weight * 0.5);
231
+ }
232
+ }
233
+ // Every leaf lies inside one original face. Shared boundary vertices use only
234
+ // the original edge endpoints, so at most three source vertices contribute.
235
+ if (weights.size > 3) throw new Error('Inconsistent mesh provenance');
236
+ const index = vertices.length;
237
+ vertices.push({source, target: project(source), weights});
238
+ midpoints.set(key, index);
239
+ return index;
240
+ }
241
+
242
+ function splitFace(
243
+ face: Face,
244
+ output: Face[],
245
+ splitEdges: Set<string>,
246
+ midpoints: Map<string, number>
247
+ ): void {
248
+ const [a, b, c] = face.vertices;
249
+ const ab = splitEdges.has(edgeKey(a, b)) ? midpoint(a, b, midpoints) : -1;
250
+ const bc = splitEdges.has(edgeKey(b, c)) ? midpoint(b, c, midpoints) : -1;
251
+ const ca = splitEdges.has(edgeKey(c, a)) ? midpoint(c, a, midpoints) : -1;
252
+ const count = Number(ab >= 0) + Number(bc >= 0) + Number(ca >= 0);
253
+ if (count === 0) emit(a, b, c);
254
+ else if (count === 3) {
255
+ emit(a, ab, ca);
256
+ emit(ab, b, bc);
257
+ emit(ca, bc, c);
258
+ emit(ab, bc, ca);
259
+ } else {
260
+ // Rotate to a canonical one-edge or two-edge template, preserving winding.
261
+ const corners = [a, b, c];
262
+ const edges = [ab, bc, ca];
263
+ const start = count === 1 ? edges.findIndex(v => v >= 0) : edges.findIndex(v => v < 0);
264
+ const rotation = count === 1 ? start : (start + 1) % 3;
265
+ const x = corners[rotation];
266
+ const y = corners[(rotation + 1) % 3];
267
+ const z = corners[(rotation + 2) % 3];
268
+ const xy = edges[rotation];
269
+ if (count === 1) {
270
+ emit(x, xy, z);
271
+ emit(xy, y, z);
272
+ } else {
273
+ const yz = edges[(rotation + 1) % 3];
274
+ emit(y, yz, xy);
275
+ emit(x, xy, z);
276
+ emit(xy, yz, z);
277
+ }
278
+ }
279
+ function emit(x: number, y: number, z: number): void {
280
+ if (output.length >= maxTriangles)
281
+ throw new RangeError('Triangle mesh subdivision exceeded maxTriangles');
282
+ output.push({vertices: [x, y, z], sourceTriangle: face.sourceTriangle});
283
+ }
284
+ }
285
+
286
+ function buildResult(): SubdividedTriangleMesh {
287
+ const sourceVertexIndices = new Uint32Array(vertices.length * 3);
288
+ const sourceVertexWeights = new Float64Array(vertices.length * 3);
289
+ for (let i = 0; i < vertices.length; i++) {
290
+ let slot = 0;
291
+ for (const [index, weight] of vertices[i].weights) {
292
+ sourceVertexIndices[i * 3 + slot] = index;
293
+ sourceVertexWeights[i * 3 + slot++] = weight;
294
+ }
295
+ }
296
+ return {
297
+ sourcePositions: new Float64Array(vertices.flatMap(v => v.source)),
298
+ positions: new Float64Array(vertices.flatMap(v => v.target)),
299
+ indices: new Uint32Array(faces.flatMap(f => f.vertices)),
300
+ sourceVertexIndices,
301
+ sourceVertexWeights,
302
+ sourceTriangleIndices: new Uint32Array(faces.map(f => f.sourceTriangle))
303
+ };
304
+ }
305
+ }
306
+
307
+ /** Measures an indexed edge in source-coordinate units. */
308
+ function sourceEdgeLength(a: Vertex, b: Vertex): number {
309
+ return Math.hypot(...a.source.map((value, component) => value - b.source[component]));
310
+ }
311
+
312
+ function edgeKey(a: number, b: number): string {
313
+ return a <= b ? `${a}:${b}` : `${b}:${a}`;
314
+ }
315
+
316
+ function validLimit(value: number): boolean {
317
+ return Number.isSafeInteger(value) && value > 0 && value <= 0xffffffff;
318
+ }
319
+
320
+ function blend(positions: number[][], weights: number[]): number[] {
321
+ return positions[0].map((_, i) => positions.reduce((sum, p, j) => sum + p[i] * weights[j], 0));
322
+ }
@@ -0,0 +1,50 @@
1
+ // math.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // SPDX-FileCopyrightText: Copyright (c) vis.gl contributors
4
+
5
+ import type {NumericArray} from '@math.gl/core';
6
+
7
+ export function push(target: number[], source: number[]): boolean {
8
+ const size = source.length;
9
+ const startIndex = target.length;
10
+
11
+ // dedupe, if source is the same point as the last vertex
12
+ if (startIndex > 0) {
13
+ let isDuplicate = true;
14
+ for (let i = 0; i < size; i++) {
15
+ if (target[startIndex - size + i] !== source[i]) {
16
+ isDuplicate = false;
17
+ break;
18
+ }
19
+ }
20
+ if (isDuplicate) {
21
+ return false;
22
+ }
23
+ }
24
+
25
+ for (let i = 0; i < size; i++) {
26
+ target[startIndex + i] = source[i];
27
+ }
28
+ return true;
29
+ }
30
+
31
+ export function copy(target: number[], source: Readonly<NumericArray>): void {
32
+ const size = source.length;
33
+ for (let i = 0; i < size; i++) {
34
+ target[i] = source[i];
35
+ }
36
+ }
37
+
38
+ export function getPointAtIndex(
39
+ positions: Readonly<NumericArray>,
40
+ index: number,
41
+ size: number,
42
+ offset: number,
43
+ out: number[] = []
44
+ ): number[] {
45
+ const startI = offset + index * size;
46
+ for (let i = 0; i < size; i++) {
47
+ out[i] = positions[startI + i];
48
+ }
49
+ return out;
50
+ }