@tangram.gl/tangram-renderer 0.0.0-stage → 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (321) hide show
  1. package/README.md +59 -2
  2. package/dist/core.js +36923 -0
  3. package/dist/core.js.map +6 -0
  4. package/dist/index.js +32 -0
  5. package/dist/loaders-gl-worker.js +82 -0
  6. package/dist/loaders-gl-worker.js.map +6 -0
  7. package/dist/map-logic.js +2 -0
  8. package/dist/map-logic.js.map +6 -0
  9. package/dist/projected-basemaps-worker.js +3 -0
  10. package/dist/projected-basemaps-worker.js.map +6 -0
  11. package/dist/shader-modules.js +141 -0
  12. package/dist/shader-modules.js.map +6 -0
  13. package/dist/style-schema.js +126 -0
  14. package/dist/style-schema.js.map +6 -0
  15. package/dist/tangram-style.schema.json +882 -0
  16. package/dist/tangram.debug.mjs +37139 -0
  17. package/dist/tangram.debug.mjs.map +6 -0
  18. package/dist/tangram.min.mjs +4950 -0
  19. package/dist/types/builders/earcut.d.ts +15 -0
  20. package/dist/types/core.d.ts +29 -0
  21. package/dist/types/gl/constants.d.ts +2 -0
  22. package/dist/types/gl/globe_mesh.d.ts +48 -0
  23. package/dist/types/gl/glsl.d.ts +17 -0
  24. package/dist/types/gl/vertex-constants.d.ts +4 -0
  25. package/dist/types/gl/vertex-types.d.ts +34 -0
  26. package/dist/types/gl/vertex_data.d.ts +32 -0
  27. package/dist/types/gl/vertex_elements.d.ts +8 -0
  28. package/dist/types/gl/vertex_layout.d.ts +32 -0
  29. package/dist/types/glsl.d.ts +14 -0
  30. package/dist/types/gpu/luma_device_renderer.d.ts +66 -0
  31. package/dist/types/gpu/resource_lifecycle.d.ts +4 -0
  32. package/dist/types/gpu/tangram_gpu_backend.d.ts +151 -0
  33. package/dist/types/index.d.ts +155 -0
  34. package/dist/types/lights/light-definitions.d.ts +121 -0
  35. package/dist/types/map-logic/draped-terrain-bounds.d.ts +41 -0
  36. package/dist/types/map-logic/globe-terrain-preparation.d.ts +85 -0
  37. package/dist/types/map-logic/globe-terrain.d.ts +54 -0
  38. package/dist/types/map-logic/index.d.ts +33 -0
  39. package/dist/types/map-logic/label-identity.d.ts +22 -0
  40. package/dist/types/map-logic/label-placement.d.ts +32 -0
  41. package/dist/types/map-logic/screen-bounds.d.ts +15 -0
  42. package/dist/types/map-logic/terrain-data.d.ts +55 -0
  43. package/dist/types/map-logic/terrain-error.d.ts +51 -0
  44. package/dist/types/map-logic/terrain-ground-topology.d.ts +26 -0
  45. package/dist/types/map-logic/terrain-height-field.d.ts +59 -0
  46. package/dist/types/map-logic/terrain-navigation.d.ts +27 -0
  47. package/dist/types/map-logic/terrain-neighborhood.d.ts +5 -0
  48. package/dist/types/map-logic/terrain-query.d.ts +33 -0
  49. package/dist/types/map-logic/terrain-resource-budget.d.ts +51 -0
  50. package/dist/types/map-logic/terrain-transition-topology.d.ts +23 -0
  51. package/dist/types/map-logic/tile-build-queue.d.ts +51 -0
  52. package/dist/types/map-logic/tile-cache-policy.d.ts +46 -0
  53. package/dist/types/map-logic/tile-residency.d.ts +17 -0
  54. package/dist/types/map-logic/triangle-query-index.d.ts +87 -0
  55. package/dist/types/procedures/js-yaml.d.ts +15 -0
  56. package/dist/types/procedures/mesh-projector.d.ts +107 -0
  57. package/dist/types/procedures/mvt-dependencies.d.ts +20 -0
  58. package/dist/types/procedures/projected-coordinate-transform.d.ts +27 -0
  59. package/dist/types/procedures/projection-batch-executor.d.ts +53 -0
  60. package/dist/types/procedures/scene-yaml-legacy.d.ts +6 -0
  61. package/dist/types/procedures/terrain-draping.d.ts +165 -0
  62. package/dist/types/procedures/terrain-globe.d.ts +6 -0
  63. package/dist/types/procedures/terrain-styled-topology.d.ts +34 -0
  64. package/dist/types/procedures/web-mercator-legacy.d.ts +4 -0
  65. package/dist/types/procedures/web-mercator-math.d.ts +4 -0
  66. package/dist/types/scene/globals.d.ts +11 -0
  67. package/dist/types/scene/ground_footprint.d.ts +16 -0
  68. package/dist/types/scene/host_frame.d.ts +54 -0
  69. package/dist/types/scene/projection_math.d.ts +52 -0
  70. package/dist/types/scene/scene-resource-types.d.ts +177 -0
  71. package/dist/types/scene/scene_bundle.d.ts +69 -0
  72. package/dist/types/scene/visibility_adapter.d.ts +106 -0
  73. package/dist/types/selection/draped-terrain-surface.d.ts +78 -0
  74. package/dist/types/selection/terrain_surface.d.ts +149 -0
  75. package/dist/types/shader-modules/globe-horizon.d.ts +15 -0
  76. package/dist/types/shader-modules/height-decode.d.ts +13 -0
  77. package/dist/types/shader-modules/hillshade.d.ts +13 -0
  78. package/dist/types/shader-modules/index.d.ts +6 -0
  79. package/dist/types/shader-modules/planar.d.ts +12 -0
  80. package/dist/types/shader-modules/sphere-map.d.ts +13 -0
  81. package/dist/types/shader-modules/triplanar.d.ts +15 -0
  82. package/dist/types/sources/decoded_tile_store.d.ts +95 -0
  83. package/dist/types/sources/tile_source_metadata.d.ts +32 -0
  84. package/dist/types/styles/text/fontfaceobserver.d.ts +10 -0
  85. package/dist/types/tile/tile_id.d.ts +37 -0
  86. package/dist/types/tile/tile_traversal_adapter.d.ts +63 -0
  87. package/dist/types/types.d.ts +293 -0
  88. package/dist/types/utils/geo.d.ts +57 -0
  89. package/dist/types/utils/hash.d.ts +1 -0
  90. package/dist/types/utils/log.d.ts +27 -0
  91. package/dist/types/utils/props.d.ts +6 -0
  92. package/dist/types/utils/subscribe.d.ts +10 -0
  93. package/dist/types/utils/thread.d.ts +6 -0
  94. package/dist/types/utils/urls.d.ts +26 -0
  95. package/dist/types/utils/utils.d.ts +26 -0
  96. package/dist/types/utils/version.d.ts +2 -0
  97. package/dist/types/utils/worker-types.d.ts +68 -0
  98. package/dist/types/utils/worker_broker.d.ts +3 -0
  99. package/package.json +103 -3
  100. package/src/builders/common.ts +41 -0
  101. package/src/builders/earcut.d.ts +15 -0
  102. package/src/builders/geometry-types.ts +60 -0
  103. package/src/builders/points.ts +115 -0
  104. package/src/builders/polygons.ts +225 -0
  105. package/src/builders/polylines.ts +682 -0
  106. package/src/builders/wireframe.ts +31 -0
  107. package/src/core.d.ts +29 -0
  108. package/src/core.ts +33 -0
  109. package/src/experimental/loaders-gl-worker.ts +19 -0
  110. package/src/experimental/projected-basemaps-worker.ts +13 -0
  111. package/src/experimental/projected-mesh-cache.ts +137 -0
  112. package/src/experimental/projected-mesh-domain.ts +110 -0
  113. package/src/experimental/projected-mesh-refinement.ts +193 -0
  114. package/src/experimental/projected-mesh.ts +399 -0
  115. package/src/experimental/projected-normal.ts +26 -0
  116. package/src/experimental/projected-symbol-mesh.ts +74 -0
  117. package/src/gl/constants.ts +18 -0
  118. package/src/gl/context.ts +103 -0
  119. package/src/gl/extensions.ts +30 -0
  120. package/src/gl/globe_mesh.ts +285 -0
  121. package/src/gl/glsl.ts +257 -0
  122. package/src/gl/mesh-types.ts +56 -0
  123. package/src/gl/render_state.ts +111 -0
  124. package/src/gl/shader_program.ts +1310 -0
  125. package/src/gl/texture.ts +814 -0
  126. package/src/gl/uniform_buffer.ts +340 -0
  127. package/src/gl/vao.ts +154 -0
  128. package/src/gl/vbo_mesh.ts +349 -0
  129. package/src/gl/vertex-constants.ts +19 -0
  130. package/src/gl/vertex-types.ts +35 -0
  131. package/src/gl/vertex_data.ts +126 -0
  132. package/src/gl/vertex_elements.ts +54 -0
  133. package/src/gl/vertex_layout.ts +241 -0
  134. package/src/glsl.d.ts +14 -0
  135. package/src/gpu/luma_device_renderer.ts +579 -0
  136. package/src/gpu/pixel_readback.ts +51 -0
  137. package/src/gpu/resource_lifecycle.ts +32 -0
  138. package/src/gpu/tangram_gpu_backend.ts +195 -0
  139. package/src/index.d.ts +155 -0
  140. package/src/index.ts +105 -0
  141. package/src/labels/collision-types.ts +94 -0
  142. package/src/labels/collision.ts +273 -0
  143. package/src/labels/collision_grid.ts +61 -0
  144. package/src/labels/intersect.ts +30 -0
  145. package/src/labels/label-types.ts +91 -0
  146. package/src/labels/label.ts +207 -0
  147. package/src/labels/label_line.ts +801 -0
  148. package/src/labels/label_point.ts +131 -0
  149. package/src/labels/main-pass-types.ts +73 -0
  150. package/src/labels/main_pass.ts +221 -0
  151. package/src/labels/point_anchor.ts +100 -0
  152. package/src/labels/point_placement.ts +150 -0
  153. package/src/labels/projected-pass.ts +259 -0
  154. package/src/labels/repeat_group.ts +72 -0
  155. package/src/lights/ambient_light.glsl +18 -0
  156. package/src/lights/directional_light.glsl +39 -0
  157. package/src/lights/geographic-lights.ts +21 -0
  158. package/src/lights/light-definitions.ts +285 -0
  159. package/src/lights/light.ts +590 -0
  160. package/src/lights/lighting-uniforms.ts +80 -0
  161. package/src/lights/lighting-wgsl.ts +116 -0
  162. package/src/lights/material.glsl +237 -0
  163. package/src/lights/material.ts +145 -0
  164. package/src/lights/native-falloff.ts +37 -0
  165. package/src/lights/point_light.glsl +96 -0
  166. package/src/lights/spot_light.glsl +111 -0
  167. package/src/map-logic/draped-terrain-bounds.ts +71 -0
  168. package/src/map-logic/globe-terrain-preparation.ts +217 -0
  169. package/src/map-logic/globe-terrain.ts +296 -0
  170. package/src/map-logic/index.ts +37 -0
  171. package/src/map-logic/label-identity.ts +36 -0
  172. package/src/map-logic/label-placement.ts +117 -0
  173. package/src/map-logic/screen-bounds.ts +34 -0
  174. package/src/map-logic/terrain-data.ts +107 -0
  175. package/src/map-logic/terrain-error.ts +134 -0
  176. package/src/map-logic/terrain-ground-topology.ts +164 -0
  177. package/src/map-logic/terrain-height-field.ts +254 -0
  178. package/src/map-logic/terrain-navigation.ts +50 -0
  179. package/src/map-logic/terrain-neighborhood.ts +43 -0
  180. package/src/map-logic/terrain-query.ts +51 -0
  181. package/src/map-logic/terrain-resource-budget.ts +124 -0
  182. package/src/map-logic/terrain-transition-topology.ts +164 -0
  183. package/src/map-logic/tile-build-queue.ts +110 -0
  184. package/src/map-logic/tile-cache-policy.ts +89 -0
  185. package/src/map-logic/tile-residency.ts +50 -0
  186. package/src/map-logic/triangle-query-index.ts +265 -0
  187. package/src/procedures/js-yaml.d.ts +15 -0
  188. package/src/procedures/mesh-projector.ts +191 -0
  189. package/src/procedures/mlt-loaders.ts +55 -0
  190. package/src/procedures/mvt-dependencies.d.ts +20 -0
  191. package/src/procedures/mvt-legacy.ts +150 -0
  192. package/src/procedures/mvt-loaders.ts +53 -0
  193. package/src/procedures/mvt-parser.ts +48 -0
  194. package/src/procedures/mvt-properties.ts +36 -0
  195. package/src/procedures/mvt-tile-provider.ts +72 -0
  196. package/src/procedures/pmtiles-loader.ts +75 -0
  197. package/src/procedures/projected-coordinate-transform.ts +79 -0
  198. package/src/procedures/projection-batch-executor.ts +140 -0
  199. package/src/procedures/scene-yaml-legacy.ts +16 -0
  200. package/src/procedures/scene-yaml-loaders.ts +10 -0
  201. package/src/procedures/terrain-draping.ts +713 -0
  202. package/src/procedures/terrain-globe.ts +32 -0
  203. package/src/procedures/terrain-styled-topology.ts +184 -0
  204. package/src/procedures/web-mercator-legacy.ts +24 -0
  205. package/src/procedures/web-mercator-math.ts +50 -0
  206. package/src/scene/camera.ts +298 -0
  207. package/src/scene/camera_base.ts +116 -0
  208. package/src/scene/classic_scene.ts +20 -0
  209. package/src/scene/external_camera.ts +101 -0
  210. package/src/scene/globals.ts +120 -0
  211. package/src/scene/ground_footprint.ts +139 -0
  212. package/src/scene/host_frame.ts +326 -0
  213. package/src/scene/projected_tile_lod.ts +125 -0
  214. package/src/scene/projection_math.ts +142 -0
  215. package/src/scene/projection_shaders.ts +183 -0
  216. package/src/scene/renderer.ts +516 -0
  217. package/src/scene/scene-resource-types.ts +174 -0
  218. package/src/scene/scene.ts +2378 -0
  219. package/src/scene/scene_bundle.ts +304 -0
  220. package/src/scene/scene_debug.ts +129 -0
  221. package/src/scene/scene_loader.ts +402 -0
  222. package/src/scene/scene_worker.ts +528 -0
  223. package/src/scene/view.ts +683 -0
  224. package/src/scene/visibility_adapter.ts +319 -0
  225. package/src/scene/worker_url.ts +15 -0
  226. package/src/selection/draped-terrain-surface.ts +377 -0
  227. package/src/selection/selection-types.ts +79 -0
  228. package/src/selection/selection.ts +542 -0
  229. package/src/selection/selection_fragment.glsl +18 -0
  230. package/src/selection/selection_globals.glsl +9 -0
  231. package/src/selection/selection_pixels.ts +59 -0
  232. package/src/selection/selection_vertex.glsl +15 -0
  233. package/src/selection/terrain_surface.ts +298 -0
  234. package/src/shader-modules/globe-horizon.ts +52 -0
  235. package/src/shader-modules/height-decode.ts +41 -0
  236. package/src/shader-modules/hillshade.ts +70 -0
  237. package/src/shader-modules/index.ts +10 -0
  238. package/src/shader-modules/planar.ts +24 -0
  239. package/src/shader-modules/sphere-map.ts +38 -0
  240. package/src/shader-modules/triplanar.ts +45 -0
  241. package/src/sources/aligned_tile_source.ts +122 -0
  242. package/src/sources/data_source.ts +655 -0
  243. package/src/sources/decoded_tile_store.ts +245 -0
  244. package/src/sources/geojson.ts +300 -0
  245. package/src/sources/mvt.ts +247 -0
  246. package/src/sources/raster.ts +341 -0
  247. package/src/sources/shared_tile_source_adapter.ts +117 -0
  248. package/src/sources/sources.ts +10 -0
  249. package/src/sources/tile_source_adapter.ts +84 -0
  250. package/src/sources/tile_source_metadata.ts +65 -0
  251. package/src/sources/tile_source_state.ts +112 -0
  252. package/src/sources/topojson.ts +90 -0
  253. package/src/styles/feature_annotations.ts +16 -0
  254. package/src/styles/filter.ts +190 -0
  255. package/src/styles/geometry-style-types.ts +209 -0
  256. package/src/styles/globe_visibility_wgsl.ts +22 -0
  257. package/src/styles/layer-types.ts +45 -0
  258. package/src/styles/layer.ts +586 -0
  259. package/src/styles/lines/dasharray.ts +49 -0
  260. package/src/styles/lines/lines.ts +707 -0
  261. package/src/styles/lines/lines_wgsl.ts +224 -0
  262. package/src/styles/points/point-runtime-types.ts +125 -0
  263. package/src/styles/points/points.ts +1079 -0
  264. package/src/styles/points/points_fragment.glsl +126 -0
  265. package/src/styles/points/points_vertex.glsl +230 -0
  266. package/src/styles/points/points_wgsl.ts +189 -0
  267. package/src/styles/polygons/polygons.ts +268 -0
  268. package/src/styles/polygons/polygons_fragment.glsl +173 -0
  269. package/src/styles/polygons/polygons_vertex.glsl +213 -0
  270. package/src/styles/polygons/polygons_wgsl.ts +127 -0
  271. package/src/styles/property-types.ts +125 -0
  272. package/src/styles/raster/raster.ts +33 -0
  273. package/src/styles/raster/raster_globals.glsl +46 -0
  274. package/src/styles/style-mixing-types.ts +101 -0
  275. package/src/styles/style-runtime-types.ts +220 -0
  276. package/src/styles/style-schema.ts +133 -0
  277. package/src/styles/style.ts +1033 -0
  278. package/src/styles/style_globals.glsl +69 -0
  279. package/src/styles/style_manager.ts +464 -0
  280. package/src/styles/style_parser.ts +620 -0
  281. package/src/styles/text/font_manager.ts +180 -0
  282. package/src/styles/text/fontfaceobserver.d.ts +10 -0
  283. package/src/styles/text/text-types.ts +220 -0
  284. package/src/styles/text/text.ts +378 -0
  285. package/src/styles/text/text_canvas.ts +773 -0
  286. package/src/styles/text/text_labels.ts +436 -0
  287. package/src/styles/text/text_segments.ts +142 -0
  288. package/src/styles/text/text_settings.ts +228 -0
  289. package/src/styles/text/text_wgsl.ts +159 -0
  290. package/src/styles/text/text_wrap.ts +194 -0
  291. package/src/tile/globe_tile_preload.ts +40 -0
  292. package/src/tile/tangram_tileset_2d.ts +108 -0
  293. package/src/tile/tile-build-types.ts +155 -0
  294. package/src/tile/tile.ts +807 -0
  295. package/src/tile/tile_id.ts +172 -0
  296. package/src/tile/tile_manager.ts +889 -0
  297. package/src/tile/tile_pyramid.ts +119 -0
  298. package/src/tile/tile_resource_cache.ts +91 -0
  299. package/src/tile/tile_traversal_adapter.ts +132 -0
  300. package/src/types.ts +332 -0
  301. package/src/utils/debounce.ts +17 -0
  302. package/src/utils/debug_settings.ts +43 -0
  303. package/src/utils/errors.ts +12 -0
  304. package/src/utils/functions.ts +95 -0
  305. package/src/utils/geo.ts +364 -0
  306. package/src/utils/hash.ts +14 -0
  307. package/src/utils/log.ts +108 -0
  308. package/src/utils/media_capture.ts +193 -0
  309. package/src/utils/merge.ts +44 -0
  310. package/src/utils/obb.ts +134 -0
  311. package/src/utils/props.ts +43 -0
  312. package/src/utils/slice.ts +14 -0
  313. package/src/utils/subscribe.ts +58 -0
  314. package/src/utils/task.ts +154 -0
  315. package/src/utils/thread.ts +26 -0
  316. package/src/utils/urls.ts +223 -0
  317. package/src/utils/utils.ts +310 -0
  318. package/src/utils/vector.ts +197 -0
  319. package/src/utils/version.ts +8 -0
  320. package/src/utils/worker-types.ts +79 -0
  321. package/src/utils/worker_broker.ts +523 -0
@@ -0,0 +1,285 @@
1
+ // tangram-layers
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import type {
6
+ AmbientLight, DirectionalLight, PointLight, SpotLight
7
+ } from '@luma.gl/shadertools';
8
+
9
+ /** An RGB contribution or position, copied at the adapter boundary. */
10
+ type Triple = readonly [number, number, number];
11
+
12
+ /** Tangram's normalized RGB/RGBA, CSS color, or scalar lighting contribution. */
13
+ export type TangramLightColor = number | string | Triple | readonly [number, number, number, number];
14
+
15
+ /** Optional Tangram shading controls layered on native luma.gl light definitions. */
16
+ export interface TangramLightExtensions {
17
+ /** Independent normalized ambient contribution; defaults to the native light contribution. */
18
+ ambient?: TangramLightColor;
19
+ /** Independent normalized diffuse contribution; defaults to the native light contribution. */
20
+ diffuse?: TangramLightColor;
21
+ /** Independent normalized specular contribution; defaults to the native light contribution. */
22
+ specular?: TangramLightColor;
23
+ /** Suppress this light without removing its authored definition. */
24
+ visible?: boolean;
25
+ }
26
+
27
+ /** Optional positional falloff and coordinate controls; native coefficients remain `attenuation`. */
28
+ export interface TangramPositionalLightExtensions extends TangramLightExtensions {
29
+ /** Legacy exponent falloff, multiplied by the native polynomial attenuation. */
30
+ attenuationExponent?: number;
31
+ /** Legacy outer radius, or [inner, outer] radii, accepting Tangram meter/pixel units. */
32
+ radius?: number | string | readonly [number | string | null, number | string];
33
+ /** Optional legacy position interpretation; omitted means projected common-space coordinates. */
34
+ origin?: 'world' | 'ground' | 'camera';
35
+ /** Interpret native position as longitude/latitude/altitude rather than projected common coordinates. */
36
+ positionSpace?: 'common' | 'geographic';
37
+ /** Geographic spotlight orientation; defaults to ENU when positionSpace is geographic. */
38
+ directionSpace?: 'common' | 'enu';
39
+ }
40
+
41
+ /** Native ambient light with optional independent Tangram color contributions. */
42
+ export type TangramAmbientLight = AmbientLight & TangramLightExtensions;
43
+ /** Native directional light with optional independent Tangram color contributions. */
44
+ export type TangramDirectionalLight = DirectionalLight & TangramLightExtensions;
45
+ /** Native point light with optional Tangram color, falloff, and coordinate controls. */
46
+ export type TangramPointLight = PointLight & TangramPositionalLightExtensions;
47
+ /** Native spotlight with optional Tangram falloff inside its native radian cone. */
48
+ export type TangramSpotLight = SpotLight & TangramPositionalLightExtensions & {
49
+ /** Legacy cosine falloff exponent, multiplied by the native cone transition; defaults to zero. */
50
+ spotExponent?: number;
51
+ };
52
+ /** Every native luma.gl Light is assignable; all Tangram additions are optional. */
53
+ export type TangramLight = TangramAmbientLight | TangramDirectionalLight | TangramPointLight | TangramSpotLight;
54
+
55
+ /** Native descriptors after defaults, vectors, attenuation and spot cones have been validated. */
56
+ export type NormalizedTangramLight = (
57
+ Omit<TangramAmbientLight, 'color' | 'intensity'> | Omit<TangramDirectionalLight, 'color' | 'intensity'> |
58
+ (Omit<TangramPointLight, 'color' | 'intensity' | 'attenuation'> & {attenuation: Triple}) |
59
+ (Omit<TangramSpotLight, 'color' | 'intensity' | 'attenuation' | 'innerConeAngle' | 'outerConeAngle'> & {
60
+ attenuation: Triple; innerConeAngle: number; outerConeAngle: number
61
+ })
62
+ ) & {color: Triple; intensity: number};
63
+
64
+ /** Resolved Tangram light values, after color, unit and camera conversion. */
65
+ export interface ResolvedTangramLight {
66
+ /** Tangram's spotlight discriminator differs from luma.gl's `spot`. */
67
+ type: 'ambient' | 'directional' | 'point' | 'spotlight';
68
+ /** Linear RGB ambient contribution. */
69
+ ambient: Triple;
70
+ /** Linear RGB diffuse contribution. */
71
+ diffuse: Triple;
72
+ /** Linear RGB specular contribution. */
73
+ specular: Triple;
74
+ /** Position in the same eye-relative lighting space as the rendered surface. */
75
+ position?: Triple;
76
+ /** Incoming direction in the surface normal's lighting space. */
77
+ direction?: Triple;
78
+ /** Tangram's distance exponent, not luma.gl's polynomial coefficients. */
79
+ attenuation?: number;
80
+ /** Tangram's resolved inner/outer radii, in lighting-space units. */
81
+ radius?: readonly [number | null, number];
82
+ /** Tangram spotlight cutoff in degrees. */
83
+ angle?: number;
84
+ /** Tangram spotlight falloff exponent. */
85
+ exponent?: number;
86
+ }
87
+
88
+ /** A luma.gl light plus the Tangram-only data required for lossless shading. */
89
+ export interface TangramLightMapping {
90
+ /** Luma.gl-compatible byte RGB and resolved coordinates, with optional Tangram controls. */
91
+ light: TangramLight;
92
+ /** Positions are resolved lighting coordinates, not geographic longitude/latitude. */
93
+ coordinateSpace: 'tangram-lighting';
94
+ /** Exact legacy contributions and falloff; consumers must not silently discard them. */
95
+ tangram: ResolvedTangramLight;
96
+ }
97
+
98
+ /** Configuration produced for Tangram's existing shader composer from a native luma.gl light. */
99
+ export interface LumaLightConfig {
100
+ /** Tangram shader discriminator. */
101
+ type: ResolvedTangramLight['type'];
102
+ /** Linear ambient RGB. */
103
+ ambient: TangramLightColor;
104
+ /** Linear diffuse RGB. */
105
+ diffuse: TangramLightColor;
106
+ /** Linear specular RGB. */
107
+ specular: TangramLightColor;
108
+ /** Independent copy of the native light, used for native falloff and coordinates. */
109
+ lumaLight: NormalizedTangramLight;
110
+ /** Native common space by default, or an explicitly selected legacy position interpretation. */
111
+ origin: 'luma' | 'world' | 'ground' | 'camera';
112
+ /** Native projected position. */
113
+ position?: Triple;
114
+ /** Native incoming direction. */
115
+ direction?: Triple;
116
+ /** Tangram exponent, kept separate from the native polynomial coefficient vector. */
117
+ attenuation?: number;
118
+ /** Copied legacy radius configuration for the existing unit resolver. */
119
+ radius?: TangramPositionalLightExtensions['radius'];
120
+ /** Tangram spotlight exponent. */
121
+ exponent?: number;
122
+ }
123
+
124
+ /** Convert resolved Tangram data without pretending legacy falloff or separate colors are equivalent. */
125
+ export function mapTangramLight(resolved: Omit<ResolvedTangramLight, 'ambient' | 'diffuse' | 'specular'> & {
126
+ ambient: readonly number[];
127
+ diffuse: readonly number[];
128
+ specular: readonly number[];
129
+ }): TangramLightMapping {
130
+ const tangram: ResolvedTangramLight = {
131
+ ...resolved,
132
+ ambient: copyTriple(resolved.ambient),
133
+ diffuse: copyTriple(resolved.diffuse),
134
+ specular: copyTriple(resolved.specular),
135
+ ...(resolved.position ? {position: copyTriple(resolved.position)} : {}),
136
+ ...(resolved.direction ? {direction: copyTriple(resolved.direction)} : {}),
137
+ ...(resolved.radius ? {radius: [resolved.radius[0], resolved.radius[1]]} : {})
138
+ };
139
+ const color = (resolved.type === 'ambient' ? resolved.ambient : resolved.diffuse)
140
+ .map(component => component * 255);
141
+ const common = {color: copyTriple(color), intensity: 1,
142
+ ambient: copyTriple(resolved.ambient), diffuse: copyTriple(resolved.diffuse),
143
+ specular: copyTriple(resolved.specular)};
144
+ const positional = {
145
+ ...(resolved.attenuation != null ? {attenuationExponent: resolved.attenuation} : {}),
146
+ ...(resolved.radius ? {radius: [resolved.radius[0], resolved.radius[1]] as const} : {})
147
+ };
148
+ let light: TangramLight;
149
+ switch (resolved.type) {
150
+ case 'ambient':
151
+ light = {type: 'ambient', ...common};
152
+ break;
153
+ case 'directional':
154
+ light = {type: 'directional', ...common, direction: copyTriple(requireVector(resolved.direction, 'direction'))};
155
+ break;
156
+ case 'point':
157
+ light = {type: 'point', ...common, ...positional, position: copyTriple(requireVector(resolved.position, 'position'))};
158
+ break;
159
+ case 'spotlight': {
160
+ const angle = (resolved.angle ?? 20) * Math.PI / 180;
161
+ light = {type: 'spot', ...common, ...positional, position: copyTriple(requireVector(resolved.position, 'position')),
162
+ direction: copyTriple(requireVector(resolved.direction, 'direction')),
163
+ innerConeAngle: angle, outerConeAngle: angle,
164
+ ...(resolved.exponent != null ? {spotExponent: resolved.exponent} : {})};
165
+ break;
166
+ }
167
+ default:
168
+ throw new Error(`Unsupported Tangram light type: ${resolved.type}`);
169
+ }
170
+ return {light, coordinateSpace: 'tangram-lighting', tangram};
171
+ }
172
+
173
+ /** Translate a native luma.gl light while retaining its polynomial attenuation and radian cones. */
174
+ export function convertLumaLight(input: TangramLight): LumaLightConfig {
175
+ if (!input || !['ambient', 'directional', 'point', 'spot'].includes(input.type)) {
176
+ throw new Error('Expected a luma.gl ambient, directional, point or spot light');
177
+ }
178
+ const color = copyTriple(input.color ?? [0, 0, 0]);
179
+ const intensity = input.intensity ?? 1;
180
+ if (!Number.isFinite(intensity) || intensity < 0 || color.some(component => component < 0)) {
181
+ throw new Error('Luma light color and intensity must be finite and non-negative');
182
+ }
183
+ const contribution = copyTriple(color.map(component => component / 255 * intensity));
184
+ const lumaLight: TangramLight = {...input, color, intensity};
185
+ for (const property of ['ambient', 'diffuse', 'specular'] as const) {
186
+ if (input[property] != null) lumaLight[property] = copyContribution(input[property]);
187
+ }
188
+ if (input.visible != null && typeof input.visible !== 'boolean') {
189
+ throw new Error('Tangram light visibility must be a boolean');
190
+ }
191
+ if (lumaLight.type === 'directional' || lumaLight.type === 'spot') {
192
+ lumaLight.direction = copyTriple(requireVector(lumaLight.direction, 'direction'));
193
+ if (Math.hypot(...lumaLight.direction) === 0) {
194
+ throw new Error('Luma light direction must be non-zero');
195
+ }
196
+ }
197
+ if (lumaLight.type === 'point' || lumaLight.type === 'spot') {
198
+ lumaLight.position = copyTriple(requireVector(lumaLight.position, 'position'));
199
+ lumaLight.attenuation = copyTriple(lumaLight.attenuation ?? [1, 0, 0]);
200
+ if (lumaLight.attenuation.some(component => component < 0) || Math.max(...lumaLight.attenuation) === 0) {
201
+ throw new Error('Luma light attenuation must be non-negative and not all zero');
202
+ }
203
+ if (lumaLight.origin != null && !['world', 'ground', 'camera'].includes(lumaLight.origin)) {
204
+ throw new Error('Tangram light origin must be world, ground or camera');
205
+ }
206
+ if (lumaLight.positionSpace != null && !['common', 'geographic'].includes(lumaLight.positionSpace)) throw new Error('Light positionSpace must be common or geographic');
207
+ if (lumaLight.directionSpace != null && !['common', 'enu'].includes(lumaLight.directionSpace)) throw new Error('Light directionSpace must be common or enu');
208
+ if (lumaLight.positionSpace === 'geographic') {
209
+ if (lumaLight.origin != null) throw new Error('Geographic light positions cannot also specify a legacy origin');
210
+ if (Math.abs(lumaLight.position[1]) > 90) throw new Error('Geographic light latitude must be within +/-90 degrees');
211
+ } else if (lumaLight.directionSpace === 'enu') throw new Error('ENU light directions require geographic positions');
212
+ if (lumaLight.attenuationExponent != null) validateExponent(lumaLight.attenuationExponent);
213
+ if (lumaLight.radius != null) lumaLight.radius = copyRadius(lumaLight.radius);
214
+ }
215
+ if (lumaLight.type === 'spot') {
216
+ lumaLight.innerConeAngle = lumaLight.innerConeAngle ?? 0;
217
+ lumaLight.outerConeAngle = lumaLight.outerConeAngle ?? Math.PI / 4;
218
+ if (!Number.isFinite(lumaLight.innerConeAngle) || !Number.isFinite(lumaLight.outerConeAngle) ||
219
+ lumaLight.innerConeAngle < 0 || lumaLight.innerConeAngle > lumaLight.outerConeAngle ||
220
+ lumaLight.outerConeAngle > Math.PI / 2) {
221
+ throw new Error('Luma spot cones require 0 <= inner <= outer <= PI/2 radians');
222
+ }
223
+ if (lumaLight.spotExponent != null) validateExponent(lumaLight.spotExponent);
224
+ }
225
+ return {
226
+ type: lumaLight.type === 'spot' ? 'spotlight' : lumaLight.type,
227
+ ambient: lumaLight.ambient ?? (lumaLight.type === 'ambient' ? contribution : [0, 0, 0]),
228
+ diffuse: lumaLight.diffuse ?? (lumaLight.type === 'ambient' ? [0, 0, 0] : contribution),
229
+ specular: lumaLight.specular ?? (lumaLight.type === 'ambient' ? [0, 0, 0] : contribution),
230
+ // All required defaults and vector validation above have completed for this discriminator.
231
+ origin: 'origin' in lumaLight ? lumaLight.origin ?? 'luma' : 'luma', lumaLight: lumaLight as NormalizedTangramLight,
232
+ ...('position' in lumaLight ? {position: copyTriple(lumaLight.position)} : {}),
233
+ ...('direction' in lumaLight ? {direction: copyTriple(lumaLight.direction)} : {}),
234
+ ...('attenuationExponent' in lumaLight ? {attenuation: lumaLight.attenuationExponent} : {}),
235
+ ...('radius' in lumaLight ? {radius: lumaLight.radius} : {}),
236
+ ...(lumaLight.type === 'spot' ? {exponent: lumaLight.spotExponent ?? 0} : {})
237
+ };
238
+ }
239
+
240
+ /** Wrap native arrays without validation so scene globals resolve before Light.create converts them. */
241
+ export function normalizeSceneLights(lights: unknown): unknown {
242
+ if (!Array.isArray(lights)) return lights;
243
+ return Object.fromEntries(lights.map((light, index) => [`luma_light_${index}`, {luma: light}]));
244
+ }
245
+
246
+ /** Keep legacy color syntax independent of luma.gl's byte RGB field. */
247
+ function copyContribution(color: TangramLightColor): TangramLightColor {
248
+ if (typeof color === 'string') return color;
249
+ if (typeof color === 'number' && Number.isFinite(color)) return color;
250
+ if (Array.isArray(color) && (color.length === 3 || color.length === 4) && color.every(Number.isFinite)) {
251
+ return color.length === 3 ? [color[0], color[1], color[2]] : [color[0], color[1], color[2], color[3]];
252
+ }
253
+ throw new Error('Tangram light contributions require a finite scalar, RGB/RGBA tuple or CSS color');
254
+ }
255
+
256
+ /** Copy radii without sharing caller arrays; the legacy resolver handles unit strings. */
257
+ function copyRadius(radius: NonNullable<TangramPositionalLightExtensions['radius']>): NonNullable<TangramPositionalLightExtensions['radius']> {
258
+ const validate = (value: unknown) => typeof value === 'number' ? Number.isFinite(value) && value >= 0 :
259
+ typeof value === 'string' && /^\d+(?:\.\d+)?(?:px|m)?$/.test(value);
260
+ if (typeof radius === 'number' || typeof radius === 'string') {
261
+ if (validate(radius)) return radius;
262
+ } else if (radius.length === 2 && (radius[0] == null || validate(radius[0])) && validate(radius[1])) {
263
+ return [radius[0], radius[1]];
264
+ }
265
+ throw new Error('Tangram light radii require non-negative meter/pixel distances');
266
+ }
267
+
268
+ /** Falloff exponents must not introduce non-finite shader operations. */
269
+ function validateExponent(exponent: number): void {
270
+ if (!Number.isFinite(exponent) || exponent < 0) throw new Error('Tangram light exponents must be finite and non-negative');
271
+ }
272
+
273
+ /** Copy and validate vectors without sharing caller-owned arrays. */
274
+ function copyTriple(vector: ArrayLike<number>): [number, number, number] {
275
+ if (vector.length !== 3 || !Array.from(vector).every(Number.isFinite)) {
276
+ throw new Error('Light vectors must contain three finite numbers');
277
+ }
278
+ return [vector[0], vector[1], vector[2]];
279
+ }
280
+
281
+ /** Report missing required vectors instead of supplying an arbitrary position/direction. */
282
+ function requireVector(vector: ArrayLike<number> | undefined, name: string): ArrayLike<number> {
283
+ if (!vector) throw new Error(`Light requires a ${name}`);
284
+ return vector;
285
+ }