react-babylon-map 0.0.1

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 (211) hide show
  1. package/.claude/settings.local.json +78 -0
  2. package/demo.html +161 -0
  3. package/dist/cjs/main.js +520 -0
  4. package/dist/es/main.mjs +20 -0
  5. package/dist/es/main.mjs.map +1 -0
  6. package/dist/es/main10.mjs +33 -0
  7. package/dist/es/main10.mjs.map +1 -0
  8. package/dist/es/main11.mjs +12 -0
  9. package/dist/es/main11.mjs.map +1 -0
  10. package/dist/es/main12.mjs +14 -0
  11. package/dist/es/main12.mjs.map +1 -0
  12. package/dist/es/main13.mjs +12 -0
  13. package/dist/es/main13.mjs.map +1 -0
  14. package/dist/es/main14.mjs +5 -0
  15. package/dist/es/main14.mjs.map +1 -0
  16. package/dist/es/main15.mjs +12 -0
  17. package/dist/es/main15.mjs.map +1 -0
  18. package/dist/es/main16.mjs +25 -0
  19. package/dist/es/main16.mjs.map +1 -0
  20. package/dist/es/main17.mjs +54 -0
  21. package/dist/es/main17.mjs.map +1 -0
  22. package/dist/es/main18.mjs +88 -0
  23. package/dist/es/main18.mjs.map +1 -0
  24. package/dist/es/main19.mjs +18 -0
  25. package/dist/es/main19.mjs.map +1 -0
  26. package/dist/es/main2.mjs +9 -0
  27. package/dist/es/main2.mjs.map +1 -0
  28. package/dist/es/main20.mjs +21 -0
  29. package/dist/es/main20.mjs.map +1 -0
  30. package/dist/es/main21.mjs +61 -0
  31. package/dist/es/main21.mjs.map +1 -0
  32. package/dist/es/main3.mjs +46 -0
  33. package/dist/es/main3.mjs.map +1 -0
  34. package/dist/es/main4.mjs +23 -0
  35. package/dist/es/main4.mjs.map +1 -0
  36. package/dist/es/main5.mjs +69 -0
  37. package/dist/es/main5.mjs.map +1 -0
  38. package/dist/es/main6.mjs +35 -0
  39. package/dist/es/main6.mjs.map +1 -0
  40. package/dist/es/main7.mjs +65 -0
  41. package/dist/es/main7.mjs.map +1 -0
  42. package/dist/es/main8.mjs +14 -0
  43. package/dist/es/main8.mjs.map +1 -0
  44. package/dist/es/main9.mjs +26 -0
  45. package/dist/es/main9.mjs.map +1 -0
  46. package/dist/maplibre/cjs/main.js +520 -0
  47. package/dist/maplibre/es/main.mjs +20 -0
  48. package/dist/maplibre/es/main.mjs.map +1 -0
  49. package/dist/maplibre/es/main10.mjs +33 -0
  50. package/dist/maplibre/es/main10.mjs.map +1 -0
  51. package/dist/maplibre/es/main11.mjs +12 -0
  52. package/dist/maplibre/es/main11.mjs.map +1 -0
  53. package/dist/maplibre/es/main12.mjs +14 -0
  54. package/dist/maplibre/es/main12.mjs.map +1 -0
  55. package/dist/maplibre/es/main13.mjs +12 -0
  56. package/dist/maplibre/es/main13.mjs.map +1 -0
  57. package/dist/maplibre/es/main14.mjs +5 -0
  58. package/dist/maplibre/es/main14.mjs.map +1 -0
  59. package/dist/maplibre/es/main15.mjs +12 -0
  60. package/dist/maplibre/es/main15.mjs.map +1 -0
  61. package/dist/maplibre/es/main16.mjs +25 -0
  62. package/dist/maplibre/es/main16.mjs.map +1 -0
  63. package/dist/maplibre/es/main17.mjs +54 -0
  64. package/dist/maplibre/es/main17.mjs.map +1 -0
  65. package/dist/maplibre/es/main18.mjs +88 -0
  66. package/dist/maplibre/es/main18.mjs.map +1 -0
  67. package/dist/maplibre/es/main19.mjs +18 -0
  68. package/dist/maplibre/es/main19.mjs.map +1 -0
  69. package/dist/maplibre/es/main2.mjs +9 -0
  70. package/dist/maplibre/es/main2.mjs.map +1 -0
  71. package/dist/maplibre/es/main20.mjs +61 -0
  72. package/dist/maplibre/es/main20.mjs.map +1 -0
  73. package/dist/maplibre/es/main21.mjs +21 -0
  74. package/dist/maplibre/es/main21.mjs.map +1 -0
  75. package/dist/maplibre/es/main3.mjs +46 -0
  76. package/dist/maplibre/es/main3.mjs.map +1 -0
  77. package/dist/maplibre/es/main4.mjs +23 -0
  78. package/dist/maplibre/es/main4.mjs.map +1 -0
  79. package/dist/maplibre/es/main5.mjs +69 -0
  80. package/dist/maplibre/es/main5.mjs.map +1 -0
  81. package/dist/maplibre/es/main6.mjs +35 -0
  82. package/dist/maplibre/es/main6.mjs.map +1 -0
  83. package/dist/maplibre/es/main7.mjs +65 -0
  84. package/dist/maplibre/es/main7.mjs.map +1 -0
  85. package/dist/maplibre/es/main8.mjs +14 -0
  86. package/dist/maplibre/es/main8.mjs.map +1 -0
  87. package/dist/maplibre/es/main9.mjs +26 -0
  88. package/dist/maplibre/es/main9.mjs.map +1 -0
  89. package/dist/maplibre/types/api/canvas-props.d.ts +9 -0
  90. package/dist/maplibre/types/api/coordinates.d.ts +13 -0
  91. package/dist/maplibre/types/api/coords-to-vector-3.d.ts +3 -0
  92. package/dist/maplibre/types/api/coords.d.ts +5 -0
  93. package/dist/maplibre/types/api/index.d.ts +7 -0
  94. package/dist/maplibre/types/api/near-coordinates.d.ts +13 -0
  95. package/dist/maplibre/types/api/use-map.d.ts +3 -0
  96. package/dist/maplibre/types/api/vector-3-to-coords.d.ts +2 -0
  97. package/dist/maplibre/types/core/canvas-in-layer/use-canvas-in-layer.d.ts +15 -0
  98. package/dist/maplibre/types/core/canvas-in-layer/use-render.d.ts +15 -0
  99. package/dist/maplibre/types/core/canvas-in-layer/use-root.d.ts +11 -0
  100. package/dist/maplibre/types/core/canvas-overlay/canvas-portal.d.ts +10 -0
  101. package/dist/maplibre/types/core/canvas-overlay/init-canvas-fc.d.ts +11 -0
  102. package/dist/maplibre/types/core/canvas-overlay/render.d.ts +1 -0
  103. package/dist/maplibre/types/core/canvas-overlay/sync-camera-fc.d.ts +12 -0
  104. package/dist/maplibre/types/core/coords-to-matrix.d.ts +9 -0
  105. package/dist/maplibre/types/core/earth-radius.d.ts +1 -0
  106. package/dist/maplibre/types/core/generic-map.d.ts +49 -0
  107. package/dist/maplibre/types/core/matrix-utils.d.ts +7 -0
  108. package/dist/maplibre/types/core/sync-camera.d.ts +7 -0
  109. package/dist/maplibre/types/core/use-babylon-map.d.ts +32 -0
  110. package/dist/maplibre/types/core/use-coords-to-matrix.d.ts +6 -0
  111. package/dist/maplibre/types/core/use-coords.d.ts +5 -0
  112. package/dist/maplibre/types/core/use-function.d.ts +1 -0
  113. package/dist/maplibre/types/maplibre/canvas.d.ts +4 -0
  114. package/dist/maplibre/types/maplibre.index.d.ts +4 -0
  115. package/dist/types/api/canvas-props.d.ts +9 -0
  116. package/dist/types/api/coordinates.d.ts +13 -0
  117. package/dist/types/api/coords-to-vector-3.d.ts +3 -0
  118. package/dist/types/api/coords.d.ts +5 -0
  119. package/dist/types/api/index.d.ts +7 -0
  120. package/dist/types/api/near-coordinates.d.ts +13 -0
  121. package/dist/types/api/use-map.d.ts +3 -0
  122. package/dist/types/api/vector-3-to-coords.d.ts +2 -0
  123. package/dist/types/core/canvas-in-layer/use-canvas-in-layer.d.ts +15 -0
  124. package/dist/types/core/canvas-in-layer/use-render.d.ts +15 -0
  125. package/dist/types/core/canvas-in-layer/use-root.d.ts +11 -0
  126. package/dist/types/core/canvas-overlay/canvas-portal.d.ts +10 -0
  127. package/dist/types/core/canvas-overlay/init-canvas-fc.d.ts +11 -0
  128. package/dist/types/core/canvas-overlay/render.d.ts +1 -0
  129. package/dist/types/core/canvas-overlay/sync-camera-fc.d.ts +12 -0
  130. package/dist/types/core/coords-to-matrix.d.ts +9 -0
  131. package/dist/types/core/earth-radius.d.ts +1 -0
  132. package/dist/types/core/generic-map.d.ts +49 -0
  133. package/dist/types/core/matrix-utils.d.ts +7 -0
  134. package/dist/types/core/sync-camera.d.ts +7 -0
  135. package/dist/types/core/use-babylon-map.d.ts +32 -0
  136. package/dist/types/core/use-coords-to-matrix.d.ts +6 -0
  137. package/dist/types/core/use-coords.d.ts +5 -0
  138. package/dist/types/core/use-function.d.ts +1 -0
  139. package/dist/types/mapbox/canvas.d.ts +4 -0
  140. package/dist/types/mapbox.index.d.ts +4 -0
  141. package/package.json +58 -0
  142. package/plan.md +719 -0
  143. package/src/api/canvas-props.ts +10 -0
  144. package/src/api/coordinates.tsx +83 -0
  145. package/src/api/coords-to-vector-3.ts +39 -0
  146. package/src/api/coords.tsx +6 -0
  147. package/src/api/index.ts +7 -0
  148. package/src/api/near-coordinates.tsx +87 -0
  149. package/src/api/use-map.ts +8 -0
  150. package/src/api/vector-3-to-coords.ts +13 -0
  151. package/src/core/canvas-in-layer/use-canvas-in-layer.tsx +27 -0
  152. package/src/core/canvas-in-layer/use-render.ts +43 -0
  153. package/src/core/canvas-in-layer/use-root.tsx +82 -0
  154. package/src/core/canvas-overlay/canvas-portal.tsx +98 -0
  155. package/src/core/canvas-overlay/init-canvas-fc.tsx +45 -0
  156. package/src/core/canvas-overlay/render.tsx +1 -0
  157. package/src/core/canvas-overlay/sync-camera-fc.tsx +83 -0
  158. package/src/core/coords-to-matrix.ts +21 -0
  159. package/src/core/earth-radius.ts +1 -0
  160. package/src/core/events.ts +55 -0
  161. package/src/core/generic-map.ts +59 -0
  162. package/src/core/map-engine.tsx +70 -0
  163. package/src/core/matrix-utils.ts +22 -0
  164. package/src/core/sync-camera.ts +29 -0
  165. package/src/core/use-babylon-map.ts +46 -0
  166. package/src/core/use-coords-to-matrix.ts +13 -0
  167. package/src/core/use-coords.tsx +22 -0
  168. package/src/core/use-function.ts +10 -0
  169. package/src/mapbox/canvas.tsx +59 -0
  170. package/src/mapbox.index.ts +7 -0
  171. package/src/maplibre/canvas.tsx +59 -0
  172. package/src/maplibre.index.ts +7 -0
  173. package/src/vite-env.d.ts +1 -0
  174. package/stories/.ladle/components.tsx +50 -0
  175. package/stories/.ladle/style.css +63 -0
  176. package/stories/package.json +31 -0
  177. package/stories/pnpm-lock.yaml +5450 -0
  178. package/stories/sandbox.config.json +3 -0
  179. package/stories/src/adaptive-dpr.tsx +34 -0
  180. package/stories/src/billboard.stories.tsx +111 -0
  181. package/stories/src/buildings-3d.stories.tsx +280 -0
  182. package/stories/src/canvas/mapbox.stories.tsx +113 -0
  183. package/stories/src/canvas/maplibre.stories.tsx +93 -0
  184. package/stories/src/comparison.stories.tsx +161 -0
  185. package/stories/src/extrude/chaillot.ts +8 -0
  186. package/stories/src/exude-coordinates.stories.tsx +139 -0
  187. package/stories/src/free-3d-buildings/get-buildings-data.ts +49 -0
  188. package/stories/src/html-on-top.stories.tsx +156 -0
  189. package/stories/src/ifc/ifc-to-babylon.ts +97 -0
  190. package/stories/src/ifc/ifc.main.ts +904 -0
  191. package/stories/src/ifc/ifc2bb.ts +343 -0
  192. package/stories/src/ifc/model.ifc +14155 -0
  193. package/stories/src/ifc.stories.tsx +276 -0
  194. package/stories/src/mapbox/story-mapbox.tsx +97 -0
  195. package/stories/src/maplibre/story-maplibre.tsx +36 -0
  196. package/stories/src/multi-coordinates.stories.tsx +115 -0
  197. package/stories/src/pivot-controls.stories.tsx +148 -0
  198. package/stories/src/postprocessing.stories.tsx +125 -0
  199. package/stories/src/render-on-demand.stories.tsx +76 -0
  200. package/stories/src/story-map.tsx +44 -0
  201. package/stories/src/sunlight.stories.tsx +215 -0
  202. package/stories/src/vite-env.d.ts +1 -0
  203. package/stories/tsconfig.json +32 -0
  204. package/stories/tsconfig.node.json +10 -0
  205. package/stories/vite.config.ts +27 -0
  206. package/tsconfig.json +31 -0
  207. package/tsconfig.mapbox.json +7 -0
  208. package/tsconfig.maplibre.json +7 -0
  209. package/tsconfig.node.json +10 -0
  210. package/tsconfig.types.json +25 -0
  211. package/vite.config.ts +65 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main14.mjs","sources":["../../../src/core/earth-radius.ts"],"sourcesContent":["export const earthRadius = 6371008.8;\n"],"names":[],"mappings":"AAAO,MAAM,cAAc;"}
@@ -0,0 +1,12 @@
1
+ import { useContext } from "react";
2
+ import { BabylonMapContext } from "./main4.mjs";
3
+ function useCoords() {
4
+ const ctx = useContext(BabylonMapContext);
5
+ if (!ctx)
6
+ throw new Error("useCoords must be used inside a <Canvas>");
7
+ return ctx.coords;
8
+ }
9
+ export {
10
+ useCoords
11
+ };
12
+ //# sourceMappingURL=main15.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main15.mjs","sources":["../../../src/core/use-coords.tsx"],"sourcesContent":["import { useContext, useMemo } from 'react';\nimport { Coords } from '../api/coords';\nimport { BabylonMapContext, BabylonMap } from './use-babylon-map';\n\n/** Read the current coordinates from context. */\nexport function useCoords(): Coords {\n const ctx = useContext(BabylonMapContext);\n if (!ctx) throw new Error('useCoords must be used inside a <Canvas>');\n return (ctx as any).coords as Coords; // eslint-disable-line @typescript-eslint/no-explicit-any\n}\n\n/** Update the coordinates stored on the context. */\nexport function useSetCoords({ longitude, latitude, altitude }: Coords) {\n // Coordinates are now stored directly on the BabylonMap context object\n // so downstream hooks can read them.\n useMemo(() => {\n const ctx = (BabylonMapContext as any)._currentValue as BabylonMap | null; // eslint-disable-line @typescript-eslint/no-explicit-any\n if (ctx) {\n (ctx as any).coords = { longitude, latitude, altitude }; // eslint-disable-line @typescript-eslint/no-explicit-any\n }\n }, [longitude, latitude, altitude]);\n}\n"],"names":[],"mappings":";;AAKO,SAAS,YAAoB;AAC5B,QAAA,MAAM,WAAW,iBAAiB;AACxC,MAAI,CAAC;AAAW,UAAA,IAAI,MAAM,0CAA0C;AACpE,SAAQ,IAAY;AACtB;"}
@@ -0,0 +1,25 @@
1
+ import { syncCamera } from "./main12.mjs";
2
+ import { useFunction } from "./main11.mjs";
3
+ function useRender({
4
+ map,
5
+ origin,
6
+ scene,
7
+ camera,
8
+ frameloop,
9
+ babylonMap
10
+ }) {
11
+ const render = useFunction((_gl, projViewMx) => {
12
+ const pVMx = "defaultProjectionData" in projViewMx ? Object.values(projViewMx.defaultProjectionData.mainMatrix) : projViewMx;
13
+ babylonMap.viewProjMx = pVMx;
14
+ syncCamera(camera, origin, pVMx);
15
+ scene.getEngine().wipeCaches(true);
16
+ scene.render(false);
17
+ if (!frameloop || frameloop === "always")
18
+ map.triggerRepaint();
19
+ });
20
+ return render;
21
+ }
22
+ export {
23
+ useRender
24
+ };
25
+ //# sourceMappingURL=main16.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main16.mjs","sources":["../../../src/core/canvas-in-layer/use-render.ts"],"sourcesContent":["import { FreeCamera, Matrix, Scene } from '@babylonjs/core';\nimport { MapInstance } from '../generic-map';\nimport { syncCamera } from '../sync-camera';\nimport { useFunction } from '../use-function';\nimport { BabylonMap } from '../use-babylon-map';\n\nexport function useRender({\n map, origin, scene, camera, frameloop, babylonMap,\n}: {\n map: MapInstance;\n origin: Matrix;\n scene: Scene;\n camera: FreeCamera;\n frameloop?: 'always' | 'demand';\n babylonMap: BabylonMap;\n}) {\n const render = useFunction((\n _gl: WebGL2RenderingContext,\n projViewMx: number[] | { defaultProjectionData: { mainMatrix: Record<string, number> } },\n ) => {\n const pVMx = 'defaultProjectionData' in projViewMx\n ? Object.values(projViewMx.defaultProjectionData.mainMatrix)\n : projViewMx;\n\n // Update shared context\n babylonMap.viewProjMx = pVMx as number[];\n\n // Sync camera\n syncCamera(camera, origin, pVMx as number[]);\n\n // Wipe Babylon's internal GL state caches so the next render\n // re-applies everything from scratch. This is critical when\n // sharing a GL context with MapLibre.\n scene.getEngine().wipeCaches(true);\n\n // Render the Babylon scene into the shared GL context.\n scene.render(false);\n\n if (!frameloop || frameloop === 'always') map.triggerRepaint();\n });\n\n return render;\n}\n"],"names":[],"mappings":";;AAMO,SAAS,UAAU;AAAA,EACxB;AAAA,EAAK;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAW;AACzC,GAOG;AACD,QAAM,SAAS,YAAY,CACzB,KACA,eACG;AACG,UAAA,OAAO,2BAA2B,aACpC,OAAO,OAAO,WAAW,sBAAsB,UAAU,IACzD;AAGJ,eAAW,aAAa;AAGb,eAAA,QAAQ,QAAQ,IAAgB;AAKrC,UAAA,UAAA,EAAY,WAAW,IAAI;AAGjC,UAAM,OAAO,KAAK;AAEd,QAAA,CAAC,aAAa,cAAc;AAAU,UAAI,eAAe;AAAA,EAAA,CAC9D;AAEM,SAAA;AACT;"}
@@ -0,0 +1,54 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Engine, Scene, Color4, FreeCamera, Vector3 } from "@babylonjs/core";
3
+ import { createRoot } from "./main21.mjs";
4
+ import { useState, useEffect } from "react";
5
+ import { createBabylonMap, BabylonMapContext } from "./main4.mjs";
6
+ import { useFunction } from "./main11.mjs";
7
+ function useRoot(fromLngLat, map, { longitude, latitude, altitude, frameloop, ...props }) {
8
+ const [{ engine, scene, camera, reactRoot, babylonMap }] = useState(() => {
9
+ const canvas = map.getCanvas();
10
+ const gl = canvas.getContext("webgl2") || canvas.getContext("webgl");
11
+ const engine2 = new Engine(
12
+ gl,
13
+ true,
14
+ { useHighPrecisionMatrix: true },
15
+ true
16
+ );
17
+ const scene2 = new Scene(engine2);
18
+ scene2.autoClear = false;
19
+ scene2.clearColor = new Color4(0, 0, 0, 0);
20
+ scene2.detachControl();
21
+ const camera2 = new FreeCamera("cam", Vector3.Zero(), scene2);
22
+ camera2.inputs.clear();
23
+ camera2.minZ = 0;
24
+ const babylonMap2 = createBabylonMap({ map, fromLngLat, engine: engine2, scene: scene2 });
25
+ const container = document.createElement("div");
26
+ const reactRoot2 = createRoot(container);
27
+ return { engine: engine2, scene: scene2, camera: camera2, reactRoot: reactRoot2, container, babylonMap: babylonMap2 };
28
+ });
29
+ const onResize = useFunction(() => {
30
+ engine.resize();
31
+ });
32
+ const onRemove = useFunction(() => {
33
+ reactRoot.unmount();
34
+ scene.dispose();
35
+ engine.dispose();
36
+ });
37
+ babylonMap.coords = { longitude, latitude, altitude };
38
+ useEffect(() => {
39
+ map.on("resize", onResize);
40
+ return () => {
41
+ map.off("resize", onResize);
42
+ };
43
+ }, []);
44
+ useEffect(() => {
45
+ reactRoot.render(
46
+ /* @__PURE__ */ jsx(BabylonMapContext.Provider, { value: babylonMap, children: props.children })
47
+ );
48
+ }, [props.children]);
49
+ return { onRemove, engine, scene, camera, babylonMap };
50
+ }
51
+ export {
52
+ useRoot
53
+ };
54
+ //# sourceMappingURL=main17.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main17.mjs","sources":["../../../src/core/canvas-in-layer/use-root.tsx"],"sourcesContent":["import { Color4, Engine, FreeCamera, Scene, Vector3 } from '@babylonjs/core';\nimport { createRoot, Root } from 'react-dom/client';\nimport { useEffect, useState } from 'react';\nimport { CanvasProps } from '../../api/canvas-props';\nimport { BabylonMap, BabylonMapContext, createBabylonMap } from '../use-babylon-map';\nimport { FromLngLat, MapInstance } from '../generic-map';\nimport { useFunction } from '../use-function';\n\ninterface RootState {\n engine: Engine;\n scene: Scene;\n camera: FreeCamera;\n reactRoot: Root;\n container: HTMLDivElement;\n babylonMap: BabylonMap;\n}\n\nexport function useRoot(\n fromLngLat: FromLngLat,\n map: MapInstance,\n { longitude, latitude, altitude, frameloop, ...props }: CanvasProps,\n) {\n const [{ engine, scene, camera, reactRoot, babylonMap }] = useState<RootState>(() => {\n const canvas = map.getCanvas();\n const gl = (canvas.getContext('webgl2') || canvas.getContext('webgl')) as WebGLRenderingContext;\n\n // Create Babylon Engine from MapLibre's GL context (same pattern as demo.html)\n const engine = new Engine(\n gl as WebGL2RenderingContext,\n true,\n { useHighPrecisionMatrix: true },\n true,\n );\n\n const scene = new Scene(engine);\n scene.autoClear = false;\n scene.clearColor = new Color4(0, 0, 0, 0);\n scene.detachControl(); // let MapLibre handle pointer events\n\n const camera = new FreeCamera('cam', Vector3.Zero(), scene);\n camera.inputs.clear();\n camera.minZ = 0;\n\n const babylonMap = createBabylonMap({ map, fromLngLat, engine, scene });\n\n // Separate React root for children\n const container = document.createElement('div');\n const reactRoot = createRoot(container);\n\n return { engine, scene, camera, reactRoot, container, babylonMap };\n });\n\n const onResize = useFunction(() => {\n engine.resize();\n });\n\n const onRemove = useFunction(() => {\n reactRoot.unmount();\n scene.dispose();\n engine.dispose();\n });\n\n // Update coords on babylonMap\n babylonMap.coords = { longitude, latitude, altitude };\n\n // Resize listener\n useEffect(() => {\n map.on('resize', onResize);\n return () => { map.off('resize', onResize); };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Render children into the separate React root\n useEffect(() => {\n reactRoot.render(\n <BabylonMapContext.Provider value={babylonMap}>\n {props.children}\n </BabylonMapContext.Provider>,\n );\n }, [props.children]); // eslint-disable-line react-hooks/exhaustive-deps\n\n return { onRemove, engine, scene, camera, babylonMap };\n}\n"],"names":["engine","scene","camera","babylonMap","reactRoot"],"mappings":";;;;;;AAiBgB,SAAA,QACd,YACA,KACA,EAAE,WAAW,UAAU,UAAU,WAAW,GAAG,SAC/C;AACM,QAAA,CAAC,EAAE,QAAQ,OAAO,QAAQ,WAAW,WAAW,CAAC,IAAI,SAAoB,MAAM;AAC7E,UAAA,SAAS,IAAI;AACnB,UAAM,KAAM,OAAO,WAAW,QAAQ,KAAK,OAAO,WAAW,OAAO;AAGpE,UAAMA,UAAS,IAAI;AAAA,MACjB;AAAA,MACA;AAAA,MACA,EAAE,wBAAwB,KAAK;AAAA,MAC/B;AAAA,IAAA;AAGIC,UAAAA,SAAQ,IAAI,MAAMD,OAAM;AAC9BC,WAAM,YAAY;AAClBA,WAAM,aAAa,IAAI,OAAO,GAAG,GAAG,GAAG,CAAC;AACxCA,WAAM,cAAc;AAEpB,UAAMC,UAAS,IAAI,WAAW,OAAO,QAAQ,KAAA,GAAQD,MAAK;AAC1DC,YAAO,OAAO;AACdA,YAAO,OAAO;AAERC,UAAAA,cAAa,iBAAiB,EAAE,KAAK,YAAY,QAAAH,SAAQ,OAAAC,OAAAA,CAAO;AAGhE,UAAA,YAAY,SAAS,cAAc,KAAK;AACxCG,UAAAA,aAAY,WAAW,SAAS;AAE/B,WAAA,EAAE,QAAAJ,SAAQ,OAAAC,QAAO,QAAAC,SAAQ,WAAAE,YAAW,WAAW,YAAAD,YAAW;AAAA,EAAA,CAClE;AAEK,QAAA,WAAW,YAAY,MAAM;AACjC,WAAO,OAAO;AAAA,EAAA,CACf;AAEK,QAAA,WAAW,YAAY,MAAM;AACjC,cAAU,QAAQ;AAClB,UAAM,QAAQ;AACd,WAAO,QAAQ;AAAA,EAAA,CAChB;AAGD,aAAW,SAAS,EAAE,WAAW,UAAU,SAAS;AAGpD,YAAU,MAAM;AACV,QAAA,GAAG,UAAU,QAAQ;AACzB,WAAO,MAAM;AAAM,UAAA,IAAI,UAAU,QAAQ;AAAA,IAAA;AAAA,EAC3C,GAAG,CAAE,CAAA;AAGL,YAAU,MAAM;AACJ,cAAA;AAAA,0BACP,kBAAkB,UAAlB,EAA2B,OAAO,YAChC,gBAAM,UACT;AAAA,IAAA;AAAA,EACF,GACC,CAAC,MAAM,QAAQ,CAAC;AAEnB,SAAO,EAAE,UAAU,QAAQ,OAAO,QAAQ,WAAW;AACvD;"}
@@ -0,0 +1,88 @@
1
+ import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
+ import { Engine, Scene, Color4, FreeCamera, Vector3 } from "@babylonjs/core";
3
+ import { memo, useRef, useState, useEffect } from "react";
4
+ import { createBabylonMap, BabylonMapContext } from "./main4.mjs";
5
+ import { useFunction } from "./main11.mjs";
6
+ import { SyncCameraFC } from "./main20.mjs";
7
+ const canvasStyle = {
8
+ position: "absolute",
9
+ top: 0,
10
+ left: 0,
11
+ width: "100%",
12
+ height: "100%",
13
+ pointerEvents: "none"
14
+ };
15
+ const CanvasPortal = memo(({
16
+ children,
17
+ latitude,
18
+ longitude,
19
+ altitude,
20
+ setOnRender,
21
+ map,
22
+ fromLngLat
23
+ }) => {
24
+ const canvasRef = useRef(null);
25
+ const mapCanvas = map.getCanvas();
26
+ const [babylonMap, setBabylonMap] = useState(null);
27
+ const [ready, setReady] = useState(false);
28
+ useEffect(() => {
29
+ const canvas = canvasRef.current;
30
+ const engine = new Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true, useHighPrecisionMatrix: true });
31
+ const scene = new Scene(engine);
32
+ scene.clearColor = new Color4(0, 0, 0, 0);
33
+ const camera = new FreeCamera("cam", Vector3.Zero(), scene);
34
+ camera.inputs.clear();
35
+ camera.minZ = 0;
36
+ setBabylonMap(createBabylonMap({ map, fromLngLat, engine, scene }));
37
+ return () => {
38
+ scene.dispose();
39
+ engine.dispose();
40
+ };
41
+ }, []);
42
+ useEffect(() => {
43
+ if (!(babylonMap == null ? void 0 : babylonMap.engine))
44
+ return;
45
+ const engine = babylonMap.engine;
46
+ const onResize = () => {
47
+ const c = canvasRef.current;
48
+ if (!c)
49
+ return;
50
+ c.width = mapCanvas.clientWidth * window.devicePixelRatio;
51
+ c.height = mapCanvas.clientHeight * window.devicePixelRatio;
52
+ c.style.width = `${mapCanvas.clientWidth}px`;
53
+ c.style.height = `${mapCanvas.clientHeight}px`;
54
+ engine.resize();
55
+ };
56
+ onResize();
57
+ map.on("resize", onResize);
58
+ return () => {
59
+ map.off("resize", onResize);
60
+ };
61
+ }, [babylonMap, map, mapCanvas]);
62
+ const onReady = useFunction(() => {
63
+ setReady(true);
64
+ });
65
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
66
+ /* @__PURE__ */ jsx("canvas", { ref: canvasRef, style: canvasStyle }),
67
+ babylonMap && /* @__PURE__ */ jsxs(BabylonMapContext.Provider, { value: babylonMap, children: [
68
+ /* @__PURE__ */ jsx(
69
+ SyncCameraFC,
70
+ {
71
+ latitude,
72
+ longitude,
73
+ altitude,
74
+ setOnRender,
75
+ onReady,
76
+ map,
77
+ canvasRef
78
+ }
79
+ ),
80
+ ready && children
81
+ ] })
82
+ ] });
83
+ });
84
+ CanvasPortal.displayName = "CanvasPortal";
85
+ export {
86
+ CanvasPortal
87
+ };
88
+ //# sourceMappingURL=main18.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main18.mjs","sources":["../../../src/core/canvas-overlay/canvas-portal.tsx"],"sourcesContent":["import { Color4, Engine, FreeCamera, Scene, Vector3 } from '@babylonjs/core';\nimport { memo, useEffect, useRef, useState } from 'react';\nimport { CanvasProps } from '../../api/canvas-props';\nimport { BabylonMap, BabylonMapContext, createBabylonMap } from '../use-babylon-map';\nimport { FromLngLat, MapInstance } from '../generic-map';\nimport { useFunction } from '../use-function';\nimport { SyncCameraFC } from './sync-camera-fc';\n\ninterface CanvasPortalProps extends CanvasProps {\n setOnRender: (callback: () => (mx: number[]) => void) => void;\n map: MapInstance;\n fromLngLat: FromLngLat;\n}\n\nconst canvasStyle: React.CSSProperties = {\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n pointerEvents: 'none',\n};\n\nexport const CanvasPortal = memo<CanvasPortalProps>(({\n children, latitude, longitude, altitude,\n setOnRender, map, fromLngLat,\n}) => {\n\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const mapCanvas = map.getCanvas();\n\n const [babylonMap, setBabylonMap] = useState<BabylonMap | null>(null);\n const [ready, setReady] = useState(false);\n\n // Create Engine + Scene on mount\n useEffect(() => {\n const canvas = canvasRef.current!;\n const engine = new Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true, useHighPrecisionMatrix: true });\n const scene = new Scene(engine);\n scene.clearColor = new Color4(0, 0, 0, 0);\n\n const camera = new FreeCamera('cam', Vector3.Zero(), scene);\n camera.inputs.clear();\n camera.minZ = 0;\n\n setBabylonMap(createBabylonMap({ map, fromLngLat, engine, scene }));\n\n return () => {\n scene.dispose();\n engine.dispose();\n };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Resize handling\n useEffect(() => {\n if (!babylonMap?.engine) return;\n const engine = babylonMap.engine;\n\n const onResize = () => {\n const c = canvasRef.current;\n if (!c) return;\n c.width = mapCanvas.clientWidth * window.devicePixelRatio;\n c.height = mapCanvas.clientHeight * window.devicePixelRatio;\n c.style.width = `${mapCanvas.clientWidth}px`;\n c.style.height = `${mapCanvas.clientHeight}px`;\n engine.resize();\n };\n\n onResize();\n map.on('resize', onResize);\n return () => { map.off('resize', onResize); };\n }, [babylonMap, map, mapCanvas]);\n\n const onReady = useFunction(() => {\n setReady(true);\n });\n\n return (\n <>\n <canvas ref={canvasRef} style={canvasStyle} />\n {babylonMap && (\n <BabylonMapContext.Provider value={babylonMap}>\n <SyncCameraFC\n latitude={latitude}\n longitude={longitude}\n altitude={altitude}\n setOnRender={setOnRender}\n onReady={onReady}\n map={map}\n canvasRef={canvasRef}\n />\n {ready && children}\n </BabylonMapContext.Provider>\n )}\n </>\n );\n});\nCanvasPortal.displayName = 'CanvasPortal';\n"],"names":[],"mappings":";;;;;;AAcA,MAAM,cAAmC;AAAA,EACvC,UAAU;AAAA,EACV,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,eAAe;AACjB;AAEa,MAAA,eAAe,KAAwB,CAAC;AAAA,EACnD;AAAA,EAAU;AAAA,EAAU;AAAA,EAAW;AAAA,EAC/B;AAAA,EAAa;AAAA,EAAK;AACpB,MAAM;AAEE,QAAA,YAAY,OAA0B,IAAI;AAC1C,QAAA,YAAY,IAAI;AAEtB,QAAM,CAAC,YAAY,aAAa,IAAI,SAA4B,IAAI;AACpE,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,KAAK;AAGxC,YAAU,MAAM;AACd,UAAM,SAAS,UAAU;AACzB,UAAM,SAAS,IAAI,OAAO,QAAQ,MAAM,EAAE,uBAAuB,MAAM,SAAS,MAAM,wBAAwB,KAAM,CAAA;AAC9G,UAAA,QAAQ,IAAI,MAAM,MAAM;AAC9B,UAAM,aAAa,IAAI,OAAO,GAAG,GAAG,GAAG,CAAC;AAExC,UAAM,SAAS,IAAI,WAAW,OAAO,QAAQ,KAAA,GAAQ,KAAK;AAC1D,WAAO,OAAO;AACd,WAAO,OAAO;AAEd,kBAAc,iBAAiB,EAAE,KAAK,YAAY,QAAQ,MAAO,CAAA,CAAC;AAElE,WAAO,MAAM;AACX,YAAM,QAAQ;AACd,aAAO,QAAQ;AAAA,IAAA;AAAA,EAEnB,GAAG,CAAE,CAAA;AAGL,YAAU,MAAM;AACd,QAAI,EAAC,yCAAY;AAAQ;AACzB,UAAM,SAAS,WAAW;AAE1B,UAAM,WAAW,MAAM;AACrB,YAAM,IAAI,UAAU;AACpB,UAAI,CAAC;AAAG;AACN,QAAA,QAAQ,UAAU,cAAc,OAAO;AACvC,QAAA,SAAS,UAAU,eAAe,OAAO;AAC3C,QAAE,MAAM,QAAQ,GAAG,UAAU,WAAW;AACxC,QAAE,MAAM,SAAS,GAAG,UAAU,YAAY;AAC1C,aAAO,OAAO;AAAA,IAAA;AAGP;AACL,QAAA,GAAG,UAAU,QAAQ;AACzB,WAAO,MAAM;AAAM,UAAA,IAAI,UAAU,QAAQ;AAAA,IAAA;AAAA,EACxC,GAAA,CAAC,YAAY,KAAK,SAAS,CAAC;AAEzB,QAAA,UAAU,YAAY,MAAM;AAChC,aAAS,IAAI;AAAA,EAAA,CACd;AAED,SAEI,qBAAA,UAAA,EAAA,UAAA;AAAA,IAAA,oBAAC,UAAO,EAAA,KAAK,WAAW,OAAO,aAAa;AAAA,IAC3C,cACE,qBAAA,kBAAkB,UAAlB,EAA2B,OAAO,YACjC,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MACF;AAAA,MACC,SAAS;AAAA,IAAA,GACZ;AAAA,EAEJ,EAAA,CAAA;AAEJ,CAAC;AACD,aAAa,cAAc;"}
@@ -0,0 +1,18 @@
1
+ import { Vector3, Quaternion, Matrix } from "@babylonjs/core";
2
+ function coordsToMatrix({
3
+ longitude,
4
+ latitude,
5
+ altitude,
6
+ fromLngLat
7
+ }) {
8
+ const center = fromLngLat([longitude, latitude], altitude);
9
+ const scaleUnit = center.meterInMercatorCoordinateUnits();
10
+ const position = new Vector3(center.x, center.y, center.z || 0);
11
+ const scaling = new Vector3(scaleUnit, scaleUnit, scaleUnit);
12
+ const rotation = Quaternion.FromEulerAngles(Math.PI / 2, 0, 0);
13
+ return Matrix.Compose(scaling, rotation, position);
14
+ }
15
+ export {
16
+ coordsToMatrix
17
+ };
18
+ //# sourceMappingURL=main19.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main19.mjs","sources":["../../../src/core/coords-to-matrix.ts"],"sourcesContent":["import { Matrix, Quaternion, Vector3 } from '@babylonjs/core';\nimport { FromLngLat } from './generic-map';\nimport { Coords } from '../api/coords';\n\n/** Calculate Babylon.js Matrix from coordinates.\n * Returns a Babylon Matrix (world transform at the given geo coord).\n * Matches the pattern from MapLibre + Babylon.js integration demo. */\nexport function coordsToMatrix({\n longitude, latitude, altitude, fromLngLat\n}: Coords & { fromLngLat: FromLngLat }): Matrix {\n const center = fromLngLat([longitude, latitude], altitude);\n const scaleUnit = center.meterInMercatorCoordinateUnits();\n\n const position = new Vector3(center.x, center.y, center.z || 0);\n const scaling = new Vector3(scaleUnit, scaleUnit, scaleUnit);\n // Babylon default: +x east, +y up, +z north\n // MapLibre default: +x east, -y north, +z up\n const rotation = Quaternion.FromEulerAngles(Math.PI / 2, 0, 0);\n\n return Matrix.Compose(scaling, rotation, position);\n}\n"],"names":[],"mappings":";AAOO,SAAS,eAAe;AAAA,EAC7B;AAAA,EAAW;AAAA,EAAU;AAAA,EAAU;AACjC,GAAgD;AAC9C,QAAM,SAAS,WAAW,CAAC,WAAW,QAAQ,GAAG,QAAQ;AACnD,QAAA,YAAY,OAAO;AAEnB,QAAA,WAAW,IAAI,QAAQ,OAAO,GAAG,OAAO,GAAG,OAAO,KAAK,CAAC;AAC9D,QAAM,UAAU,IAAI,QAAQ,WAAW,WAAW,SAAS;AAG3D,QAAM,WAAW,WAAW,gBAAgB,KAAK,KAAK,GAAG,GAAG,CAAC;AAE7D,SAAO,OAAO,QAAQ,SAAS,UAAU,QAAQ;AACnD;"}
@@ -0,0 +1,9 @@
1
+ import { useBabylonMap } from "./main4.mjs";
2
+ const useMap = () => {
3
+ const ctx = useBabylonMap();
4
+ return ctx.map;
5
+ };
6
+ export {
7
+ useMap
8
+ };
9
+ //# sourceMappingURL=main2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main2.mjs","sources":["../../../src/api/use-map.ts"],"sourcesContent":["import { MapInstance } from '../core/generic-map';\nimport { useBabylonMap } from '../core/use-babylon-map';\n\n/** Access the underlying map instance from inside a `<Canvas>`. */\nexport const useMap = <T extends MapInstance = MapInstance>(): T => {\n const ctx = useBabylonMap();\n return ctx.map as T;\n};\n"],"names":[],"mappings":";AAIO,MAAM,SAAS,MAA8C;AAClE,QAAM,MAAM;AACZ,SAAO,IAAI;AACb;"}
@@ -0,0 +1,61 @@
1
+ import { memo, useRef, useMemo, useEffect } from "react";
2
+ import { syncCamera } from "./main12.mjs";
3
+ import { useCoordsToMatrix } from "./main13.mjs";
4
+ import { useFunction } from "./main11.mjs";
5
+ import { useBabylonMap } from "./main4.mjs";
6
+ const SyncCameraFC = memo(({
7
+ latitude,
8
+ longitude,
9
+ altitude = 0,
10
+ setOnRender,
11
+ onReady,
12
+ map,
13
+ canvasRef
14
+ }) => {
15
+ const mapCanvas = map.getCanvas();
16
+ const babylonMap = useBabylonMap();
17
+ const scene = babylonMap.scene;
18
+ const engine = babylonMap.engine;
19
+ const origin = useCoordsToMatrix({ latitude, longitude, altitude, fromLngLat: babylonMap.fromLngLat });
20
+ const ready = useRef(false);
21
+ const triggerRepaint = useMemo(() => map.triggerRepaint, [map]);
22
+ const mapPaintRequests = useRef(0);
23
+ const triggerRepaintOff = useFunction(() => {
24
+ mapPaintRequests.current++;
25
+ });
26
+ const onRender = useFunction((viewProjMx) => {
27
+ map.triggerRepaint = triggerRepaintOff;
28
+ if (canvasRef.current && engine) {
29
+ if (canvasRef.current.width !== mapCanvas.width || canvasRef.current.height !== mapCanvas.height) {
30
+ canvasRef.current.width = mapCanvas.clientWidth * window.devicePixelRatio;
31
+ canvasRef.current.height = mapCanvas.clientHeight * window.devicePixelRatio;
32
+ canvasRef.current.style.width = `${mapCanvas.clientWidth}px`;
33
+ canvasRef.current.style.height = `${mapCanvas.clientHeight}px`;
34
+ engine.resize();
35
+ }
36
+ }
37
+ const pVMx = "defaultProjectionData" in viewProjMx ? Object.values(viewProjMx.defaultProjectionData.mainMatrix) : viewProjMx;
38
+ babylonMap.viewProjMx = pVMx;
39
+ syncCamera(scene.activeCamera, origin, babylonMap.viewProjMx);
40
+ engine.wipeCaches(true);
41
+ scene.render(false);
42
+ if (!ready.current && onReady) {
43
+ ready.current = true;
44
+ onReady();
45
+ }
46
+ map.triggerRepaint = triggerRepaint;
47
+ if (mapPaintRequests.current > 0) {
48
+ mapPaintRequests.current = 0;
49
+ map.triggerRepaint();
50
+ }
51
+ });
52
+ useEffect(() => {
53
+ setOnRender && setOnRender(() => onRender);
54
+ }, [setOnRender, onRender]);
55
+ return null;
56
+ });
57
+ SyncCameraFC.displayName = "SyncCameraFC";
58
+ export {
59
+ SyncCameraFC
60
+ };
61
+ //# sourceMappingURL=main20.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main20.mjs","sources":["../../../src/core/canvas-overlay/sync-camera-fc.tsx"],"sourcesContent":["import { FreeCamera } from '@babylonjs/core';\nimport { memo, RefObject, useEffect, useRef, useMemo } from 'react';\nimport { Coords } from '../../api/coords';\nimport { MapInstance } from '../generic-map';\nimport { syncCamera } from '../sync-camera';\nimport { useCoordsToMatrix } from '../use-coords-to-matrix';\nimport { useFunction } from '../use-function';\nimport { useBabylonMap } from '../use-babylon-map';\n\ninterface SyncCameraFCProps extends Coords {\n setOnRender?: (callback: () => (mx: number[]) => void) => void;\n onReady?: () => void;\n map: MapInstance;\n canvasRef: RefObject<HTMLCanvasElement | null>;\n}\n\n/** React component to sync the Babylon camera with the map provider on each render. */\nexport const SyncCameraFC = memo<SyncCameraFCProps>(({\n latitude, longitude, altitude = 0, setOnRender, onReady, map, canvasRef,\n}) => {\n\n const mapCanvas = map.getCanvas();\n const babylonMap = useBabylonMap();\n const scene = babylonMap.scene!;\n const engine = babylonMap.engine!;\n\n const origin = useCoordsToMatrix({ latitude, longitude, altitude, fromLngLat: babylonMap.fromLngLat });\n\n const ready = useRef(false);\n\n const triggerRepaint = useMemo(() => map.triggerRepaint, [map]);\n const mapPaintRequests = useRef(0);\n const triggerRepaintOff = useFunction(() => {\n mapPaintRequests.current++;\n });\n\n // Render callback — called by MapLibre on each paint frame\n const onRender = useFunction((viewProjMx: number[] | { defaultProjectionData: { mainMatrix: Record<string, number> } }) => {\n map.triggerRepaint = triggerRepaintOff;\n\n // Resize if needed\n if (canvasRef.current && engine) {\n if (canvasRef.current.width !== mapCanvas.width || canvasRef.current.height !== mapCanvas.height) {\n canvasRef.current.width = mapCanvas.clientWidth * window.devicePixelRatio;\n canvasRef.current.height = mapCanvas.clientHeight * window.devicePixelRatio;\n canvasRef.current.style.width = `${mapCanvas.clientWidth}px`;\n canvasRef.current.style.height = `${mapCanvas.clientHeight}px`;\n engine.resize();\n }\n }\n\n const pVMx = 'defaultProjectionData' in viewProjMx\n ? Object.values(viewProjMx.defaultProjectionData.mainMatrix)\n : viewProjMx;\n babylonMap.viewProjMx = pVMx as number[];\n\n // Sync camera\n syncCamera(scene.activeCamera as FreeCamera, origin, babylonMap.viewProjMx);\n\n // Wipe caches and render one frame\n engine.wipeCaches(true);\n scene.render(false);\n\n if (!ready.current && onReady) {\n ready.current = true;\n onReady();\n }\n\n // Restore triggerRepaint for demand-based rendering\n map.triggerRepaint = triggerRepaint;\n if (mapPaintRequests.current > 0) {\n mapPaintRequests.current = 0;\n map.triggerRepaint();\n }\n });\n\n useEffect(() => {\n setOnRender && setOnRender(() => onRender);\n }, [setOnRender, onRender]);\n\n return null;\n});\nSyncCameraFC.displayName = 'SyncCameraFC';\n"],"names":[],"mappings":";;;;;AAiBa,MAAA,eAAe,KAAwB,CAAC;AAAA,EACnD;AAAA,EAAU;AAAA,EAAW,WAAW;AAAA,EAAG;AAAA,EAAa;AAAA,EAAS;AAAA,EAAK;AAChE,MAAM;AAEE,QAAA,YAAY,IAAI;AACtB,QAAM,aAAa;AACnB,QAAM,QAAQ,WAAW;AACzB,QAAM,SAAS,WAAW;AAEpB,QAAA,SAAS,kBAAkB,EAAE,UAAU,WAAW,UAAU,YAAY,WAAW,WAAA,CAAY;AAE/F,QAAA,QAAQ,OAAO,KAAK;AAE1B,QAAM,iBAAiB,QAAQ,MAAM,IAAI,gBAAgB,CAAC,GAAG,CAAC;AACxD,QAAA,mBAAmB,OAAO,CAAC;AAC3B,QAAA,oBAAoB,YAAY,MAAM;AACzB,qBAAA;AAAA,EAAA,CAClB;AAGK,QAAA,WAAW,YAAY,CAAC,eAA6F;AACzH,QAAI,iBAAiB;AAGjB,QAAA,UAAU,WAAW,QAAQ;AAC3B,UAAA,UAAU,QAAQ,UAAU,UAAU,SAAS,UAAU,QAAQ,WAAW,UAAU,QAAQ;AAChG,kBAAU,QAAQ,QAAQ,UAAU,cAAc,OAAO;AACzD,kBAAU,QAAQ,SAAS,UAAU,eAAe,OAAO;AAC3D,kBAAU,QAAQ,MAAM,QAAQ,GAAG,UAAU,WAAW;AACxD,kBAAU,QAAQ,MAAM,SAAS,GAAG,UAAU,YAAY;AAC1D,eAAO,OAAO;AAAA,MAChB;AAAA,IACF;AAEM,UAAA,OAAO,2BAA2B,aACpC,OAAO,OAAO,WAAW,sBAAsB,UAAU,IACzD;AACJ,eAAW,aAAa;AAGxB,eAAW,MAAM,cAA4B,QAAQ,WAAW,UAAU;AAG1E,WAAO,WAAW,IAAI;AACtB,UAAM,OAAO,KAAK;AAEd,QAAA,CAAC,MAAM,WAAW,SAAS;AAC7B,YAAM,UAAU;AACR;IACV;AAGA,QAAI,iBAAiB;AACjB,QAAA,iBAAiB,UAAU,GAAG;AAChC,uBAAiB,UAAU;AAC3B,UAAI,eAAe;AAAA,IACrB;AAAA,EAAA,CACD;AAED,YAAU,MAAM;AACC,mBAAA,YAAY,MAAM,QAAQ;AAAA,EAAA,GACxC,CAAC,aAAa,QAAQ,CAAC;AAEnB,SAAA;AACT,CAAC;AACD,aAAa,cAAc;"}
@@ -0,0 +1,21 @@
1
+ import require$$0 from "react-dom";
2
+ var createRoot;
3
+ var m = require$$0;
4
+ if (process.env.NODE_ENV === "production") {
5
+ createRoot = m.createRoot;
6
+ m.hydrateRoot;
7
+ } else {
8
+ var i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
9
+ createRoot = function(c, o) {
10
+ i.usingClientEntryPoint = true;
11
+ try {
12
+ return m.createRoot(c, o);
13
+ } finally {
14
+ i.usingClientEntryPoint = false;
15
+ }
16
+ };
17
+ }
18
+ export {
19
+ createRoot
20
+ };
21
+ //# sourceMappingURL=main21.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main21.mjs","sources":["../../../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/client.js"],"sourcesContent":["'use strict';\n\nvar m = require('react-dom');\nif (process.env.NODE_ENV === 'production') {\n exports.createRoot = m.createRoot;\n exports.hydrateRoot = m.hydrateRoot;\n} else {\n var i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;\n exports.createRoot = function(c, o) {\n i.usingClientEntryPoint = true;\n try {\n return m.createRoot(c, o);\n } finally {\n i.usingClientEntryPoint = false;\n }\n };\n exports.hydrateRoot = function(c, h, o) {\n i.usingClientEntryPoint = true;\n try {\n return m.hydrateRoot(c, h, o);\n } finally {\n i.usingClientEntryPoint = false;\n }\n };\n}\n"],"names":[],"mappings":";;AAEA,IAAI,IAAI;AACR,IAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,eAAqB,EAAE;AACD,IAAE;AAC1B,OAAO;AACL,MAAI,IAAI,EAAE;AACV,eAAqB,SAAS,GAAG,GAAG;AAClC,MAAE,wBAAwB;AAC1B,QAAI;AACF,aAAO,EAAE,WAAW,GAAG,CAAC;AAAA,IAC9B,UAAc;AACR,QAAE,wBAAwB;AAAA,IAC3B;AAAA,EACL;AASA;","x_google_ignoreList":[0]}
@@ -0,0 +1,46 @@
1
+ import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
+ import { MercatorCoordinate } from "maplibre-gl";
3
+ import { memo, useState } from "react";
4
+ import { useMap, Layer } from "react-map-gl/maplibre";
5
+ import { useCanvasInLayer } from "./main9.mjs";
6
+ import { InitCanvasFC } from "./main10.mjs";
7
+ import { useFunction } from "./main11.mjs";
8
+ const fromLngLat = MercatorCoordinate.fromLngLat;
9
+ const Canvas = memo(({ overlay, ...props }) => {
10
+ const map = useMap().current.getMap();
11
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
12
+ overlay && /* @__PURE__ */ jsx(CanvasOverlay, { map, ...props }),
13
+ !overlay && /* @__PURE__ */ jsx(CanvasInLayer, { map, ...props })
14
+ ] });
15
+ });
16
+ Canvas.displayName = "Canvas";
17
+ const CanvasInLayer = memo(({ map, ...props }) => {
18
+ const layerProps = useCanvasInLayer(props, fromLngLat, map);
19
+ return /* @__PURE__ */ jsx(Layer, { ...layerProps });
20
+ });
21
+ CanvasInLayer.displayName = "CanvasInLayer";
22
+ const CanvasOverlay = memo(({ map, id, beforeId, ...props }) => {
23
+ const [onRender, setOnRender] = useState();
24
+ const render = useFunction((_gl, mx) => {
25
+ if (!onRender)
26
+ return;
27
+ onRender(mx);
28
+ });
29
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
30
+ /* @__PURE__ */ jsx(Layer, { id, beforeId, type: "custom", render }),
31
+ /* @__PURE__ */ jsx(
32
+ InitCanvasFC,
33
+ {
34
+ ...props,
35
+ setOnRender,
36
+ map,
37
+ fromLngLat
38
+ }
39
+ )
40
+ ] });
41
+ });
42
+ CanvasOverlay.displayName = "CanvasOverlay";
43
+ export {
44
+ Canvas
45
+ };
46
+ //# sourceMappingURL=main3.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main3.mjs","sources":["../../../src/maplibre/canvas.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-ts-comment */\nimport { MercatorCoordinate } from 'maplibre-gl';\nimport { memo, useState } from 'react';\nimport { Layer, useMap } from 'react-map-gl/maplibre';\nimport { CanvasProps } from '../api/canvas-props';\nimport { useCanvasInLayer } from '../core/canvas-in-layer/use-canvas-in-layer';\nimport { InitCanvasFC } from '../core/canvas-overlay/init-canvas-fc';\nimport { Render } from '../core/canvas-overlay/render';\nimport { MapInstance } from '../core/generic-map';\nimport { useFunction } from '../core/use-function';\n\nconst fromLngLat = MercatorCoordinate.fromLngLat;\n\n/** `react-babylon-map` canvas inside `MapLibre` */\nexport const Canvas = memo<CanvasProps>(({ overlay, ...props }) => {\n const map = useMap().current!.getMap(); // eslint-disable-line @typescript-eslint/no-non-null-assertion\n\n return (\n <>\n {overlay && <CanvasOverlay map={map} {...props} />}\n {!overlay && <CanvasInLayer map={map} {...props} />}\n </>\n );\n});\nCanvas.displayName = 'Canvas';\n\ninterface CanvasPropsAndMap extends CanvasProps {\n map: MapInstance;\n}\n\nconst CanvasInLayer = memo<CanvasPropsAndMap>(({ map, ...props }) => {\n const layerProps = useCanvasInLayer(props, fromLngLat, map);\n /* @ts-ignore */\n return <Layer {...layerProps} />;\n});\nCanvasInLayer.displayName = 'CanvasInLayer';\n\nconst CanvasOverlay = memo<CanvasPropsAndMap>(({ map, id, beforeId, ...props }) => {\n const [onRender, setOnRender] = useState<(mx: number[]) => void>();\n\n const render = useFunction<Render>((_gl, mx) => {\n if (!onRender) return;\n onRender(mx as number[]);\n });\n\n return (\n <>\n {/* @ts-ignore */}\n <Layer id={id} beforeId={beforeId} type=\"custom\" render={render} />\n <InitCanvasFC\n {...props}\n setOnRender={setOnRender}\n map={map}\n fromLngLat={fromLngLat}\n />\n </>\n );\n});\nCanvasOverlay.displayName = 'CanvasOverlay';\n"],"names":[],"mappings":";;;;;;;AAWA,MAAM,aAAa,mBAAmB;AAG/B,MAAM,SAAS,KAAkB,CAAC,EAAE,SAAS,GAAG,YAAY;AACjE,QAAM,MAAM,OAAA,EAAS,QAAS,OAAO;AAErC,SAEK,qBAAA,UAAA,EAAA,UAAA;AAAA,IAAA,WAAY,oBAAA,eAAA,EAAc,KAAW,GAAG,MAAO,CAAA;AAAA,IAC/C,CAAC,WAAW,oBAAC,eAAc,EAAA,KAAW,GAAG,OAAO;AAAA,EACnD,EAAA,CAAA;AAEJ,CAAC;AACD,OAAO,cAAc;AAMrB,MAAM,gBAAgB,KAAwB,CAAC,EAAE,KAAK,GAAG,YAAY;AACnE,QAAM,aAAa,iBAAiB,OAAO,YAAY,GAAG;AAEnD,SAAA,oBAAC,OAAO,EAAA,GAAG,WAAY,CAAA;AAChC,CAAC;AACD,cAAc,cAAc;AAE5B,MAAM,gBAAgB,KAAwB,CAAC,EAAE,KAAK,IAAI,UAAU,GAAG,YAAY;AACjF,QAAM,CAAC,UAAU,WAAW,IAAI,SAAiC;AAEjE,QAAM,SAAS,YAAoB,CAAC,KAAK,OAAO;AAC9C,QAAI,CAAC;AAAU;AACf,aAAS,EAAc;AAAA,EAAA,CACxB;AAED,SAGI,qBAAA,UAAA,EAAA,UAAA;AAAA,IAAA,oBAAC,OAAM,EAAA,IAAQ,UAAoB,MAAK,UAAS,QAAgB;AAAA,IACjE;AAAA,MAAC;AAAA,MAAA;AAAA,QACE,GAAG;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IACF;AAAA,EACF,EAAA,CAAA;AAEJ,CAAC;AACD,cAAc,cAAc;"}
@@ -0,0 +1,23 @@
1
+ import { createContext, useContext } from "react";
2
+ const BabylonMapContext = createContext(null);
3
+ function useBabylonMap() {
4
+ const ctx = useContext(BabylonMapContext);
5
+ if (!ctx)
6
+ throw new Error("useBabylonMap must be used inside a <Canvas>");
7
+ return ctx;
8
+ }
9
+ function createBabylonMap(opts) {
10
+ return {
11
+ map: opts.map,
12
+ viewProjMx: new Array(16).fill(0),
13
+ fromLngLat: opts.fromLngLat,
14
+ engine: opts.engine,
15
+ scene: opts.scene
16
+ };
17
+ }
18
+ export {
19
+ BabylonMapContext,
20
+ createBabylonMap,
21
+ useBabylonMap
22
+ };
23
+ //# sourceMappingURL=main4.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main4.mjs","sources":["../../../src/core/use-babylon-map.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\nimport { Engine, Scene } from '@babylonjs/core';\nimport { FromLngLat, MapInstance } from './generic-map';\n\n/** Context object shared between both rendering modes. */\nexport interface BabylonMap<T extends MapInstance = MapInstance> {\n /** Map provider instance */\n map: T;\n /** Column-major view-projection matrix from the map provider */\n viewProjMx: number[];\n /** Mercator coordinate factory */\n fromLngLat: FromLngLat;\n /** Babylon Engine (may be null during init) */\n engine?: Engine;\n /** Babylon Scene (may be null during init) */\n scene?: Scene;\n /** Current origin coordinates (set by Canvas) */\n coords?: { longitude: number; latitude: number; altitude?: number };\n}\n\n// ── React context ──────────────────────────────────────────────────────\n\nexport const BabylonMapContext = createContext<BabylonMap | null>(null);\n\n/** Access the current BabylonMap context (map, scene, engine, viewProjMx). */\nexport function useBabylonMap<T extends MapInstance = MapInstance>(): BabylonMap<T> {\n const ctx = useContext(BabylonMapContext);\n if (!ctx) throw new Error('useBabylonMap must be used inside a <Canvas>');\n return ctx as BabylonMap<T>;\n}\n\n/** Initialise / update the BabylonMap context value. */\nexport function createBabylonMap<T extends MapInstance>(opts: {\n map: T;\n fromLngLat: FromLngLat;\n engine?: Engine;\n scene?: Scene;\n}): BabylonMap<T> {\n return {\n map: opts.map,\n viewProjMx: new Array(16).fill(0) as number[],\n fromLngLat: opts.fromLngLat,\n engine: opts.engine,\n scene: opts.scene,\n };\n}\n"],"names":[],"mappings":";AAsBa,MAAA,oBAAoB,cAAiC,IAAI;AAG/D,SAAS,gBAAoE;AAC5E,QAAA,MAAM,WAAW,iBAAiB;AACxC,MAAI,CAAC;AAAW,UAAA,IAAI,MAAM,8CAA8C;AACjE,SAAA;AACT;AAGO,SAAS,iBAAwC,MAKtC;AACT,SAAA;AAAA,IACL,KAAK,KAAK;AAAA,IACV,YAAY,IAAI,MAAM,EAAE,EAAE,KAAK,CAAC;AAAA,IAChC,YAAY,KAAK;AAAA,IACjB,QAAQ,KAAK;AAAA,IACb,OAAO,KAAK;AAAA,EAAA;AAEhB;"}
@@ -0,0 +1,69 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Scene, Color4, FreeCamera, Vector3, HemisphericLight } from "@babylonjs/core";
3
+ import { memo, useState, useRef, useEffect } from "react";
4
+ import { syncCamera } from "./main12.mjs";
5
+ import { useCoordsToMatrix } from "./main13.mjs";
6
+ import { useBabylonMap, BabylonMapContext } from "./main4.mjs";
7
+ const Coordinates = memo(({
8
+ latitude,
9
+ longitude,
10
+ altitude = 0,
11
+ children
12
+ }) => {
13
+ const babylonMap = useBabylonMap();
14
+ const origin = useCoordsToMatrix({
15
+ latitude,
16
+ longitude,
17
+ altitude,
18
+ fromLngLat: babylonMap.fromLngLat
19
+ });
20
+ const [subScene] = useState(() => {
21
+ if (!babylonMap.engine)
22
+ return null;
23
+ const sub = new Scene(babylonMap.engine);
24
+ sub.autoClear = false;
25
+ sub.clearColor = new Color4(0, 0, 0, 0);
26
+ return sub;
27
+ });
28
+ const cameraRef = useRef(null);
29
+ useEffect(() => {
30
+ if (!subScene)
31
+ return;
32
+ const cam = new FreeCamera("coordsCam", Vector3.Zero(), subScene);
33
+ cam.inputs.clear();
34
+ cam.minZ = 0;
35
+ cameraRef.current = cam;
36
+ const light = new HemisphericLight("coordsLight", new Vector3(0, 1, 0), subScene);
37
+ light.intensity = 1;
38
+ return () => {
39
+ cam.dispose();
40
+ light.dispose();
41
+ };
42
+ }, [subScene]);
43
+ useEffect(() => {
44
+ if (!subScene || !babylonMap.scene)
45
+ return;
46
+ const mainScene = babylonMap.scene;
47
+ const observer = mainScene.onBeforeRenderObservable.add(() => {
48
+ var _a;
49
+ if (!cameraRef.current)
50
+ return;
51
+ syncCamera(cameraRef.current, origin, babylonMap.viewProjMx);
52
+ (_a = babylonMap.engine) == null ? void 0 : _a.wipeCaches(true);
53
+ subScene.render(false);
54
+ });
55
+ return () => {
56
+ mainScene.onBeforeRenderObservable.remove(observer);
57
+ };
58
+ }, [subScene, babylonMap.scene, origin, babylonMap]);
59
+ const childMap = {
60
+ ...babylonMap,
61
+ scene: subScene || void 0
62
+ };
63
+ return /* @__PURE__ */ jsx(BabylonMapContext.Provider, { value: childMap, children });
64
+ });
65
+ Coordinates.displayName = "Coordinates";
66
+ export {
67
+ Coordinates
68
+ };
69
+ //# sourceMappingURL=main5.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main5.mjs","sources":["../../../src/api/coordinates.tsx"],"sourcesContent":["import { Color4, FreeCamera, HemisphericLight, Scene, Vector3 } from '@babylonjs/core';\nimport { memo, useEffect, useRef, useState } from 'react';\nimport { syncCamera } from '../core/sync-camera';\nimport { useCoordsToMatrix } from '../core/use-coords-to-matrix';\nimport { useBabylonMap, BabylonMapContext } from '../core/use-babylon-map';\nimport type { BabylonMap } from '../core/use-babylon-map';\n\nexport interface CoordinatesProps {\n longitude: number;\n latitude: number;\n altitude?: number;\n children?: React.ReactNode;\n}\n\n/**\n * Place 3D content at specific geographic coordinates inside a `<Canvas>`.\n * Creates a sub-scene with its own camera synced to the given geo position,\n * mirroring react-three-map's createPortal approach.\n */\nexport const Coordinates = memo<CoordinatesProps>(({\n latitude, longitude, altitude = 0, children,\n}) => {\n const babylonMap = useBabylonMap();\n const origin = useCoordsToMatrix({\n latitude, longitude, altitude, fromLngLat: babylonMap.fromLngLat,\n });\n\n // Create a sub-scene for this coordinate portal\n const [subScene] = useState(() => {\n if (!babylonMap.engine) return null;\n const sub = new Scene(babylonMap.engine);\n sub.autoClear = false;\n sub.clearColor = new Color4(0, 0, 0, 0);\n return sub;\n });\n\n const cameraRef = useRef<FreeCamera | null>(null);\n\n // Create camera + default light in sub-scene\n useEffect(() => {\n if (!subScene) return;\n const cam = new FreeCamera('coordsCam', Vector3.Zero(), subScene);\n cam.inputs.clear();\n cam.minZ = 0;\n cameraRef.current = cam;\n\n // Add a default light so StandardMaterial isn't black\n const light = new HemisphericLight('coordsLight', new Vector3(0, 1, 0), subScene);\n light.intensity = 1;\n\n return () => { cam.dispose(); light.dispose(); };\n }, [subScene]);\n\n // Render the sub-scene each frame, synced to its geographic position\n useEffect(() => {\n if (!subScene || !babylonMap.scene) return;\n const mainScene = babylonMap.scene;\n\n const observer = mainScene.onBeforeRenderObservable.add(() => {\n if (!cameraRef.current) return;\n syncCamera(cameraRef.current, origin, babylonMap.viewProjMx);\n babylonMap.engine?.wipeCaches(true);\n subScene.render(false);\n });\n\n return () => {\n mainScene.onBeforeRenderObservable.remove(observer);\n };\n }, [subScene, babylonMap.scene, origin, babylonMap]);\n\n // Provide child context pointing at the sub-scene\n const childMap: BabylonMap = {\n ...babylonMap,\n scene: subScene || undefined,\n };\n\n return (\n <BabylonMapContext.Provider value={childMap}>\n {children}\n </BabylonMapContext.Provider>\n );\n});\nCoordinates.displayName = 'Coordinates';\n"],"names":[],"mappings":";;;;;;AAmBa,MAAA,cAAc,KAAuB,CAAC;AAAA,EACjD;AAAA,EAAU;AAAA,EAAW,WAAW;AAAA,EAAG;AACrC,MAAM;AACJ,QAAM,aAAa;AACnB,QAAM,SAAS,kBAAkB;AAAA,IAC/B;AAAA,IAAU;AAAA,IAAW;AAAA,IAAU,YAAY,WAAW;AAAA,EAAA,CACvD;AAGD,QAAM,CAAC,QAAQ,IAAI,SAAS,MAAM;AAChC,QAAI,CAAC,WAAW;AAAe,aAAA;AAC/B,UAAM,MAAM,IAAI,MAAM,WAAW,MAAM;AACvC,QAAI,YAAY;AAChB,QAAI,aAAa,IAAI,OAAO,GAAG,GAAG,GAAG,CAAC;AAC/B,WAAA;AAAA,EAAA,CACR;AAEK,QAAA,YAAY,OAA0B,IAAI;AAGhD,YAAU,MAAM;AACd,QAAI,CAAC;AAAU;AACf,UAAM,MAAM,IAAI,WAAW,aAAa,QAAQ,KAAA,GAAQ,QAAQ;AAChE,QAAI,OAAO;AACX,QAAI,OAAO;AACX,cAAU,UAAU;AAGd,UAAA,QAAQ,IAAI,iBAAiB,eAAe,IAAI,QAAQ,GAAG,GAAG,CAAC,GAAG,QAAQ;AAChF,UAAM,YAAY;AAElB,WAAO,MAAM;AAAE,UAAI,QAAQ;AAAG,YAAM,QAAQ;AAAA,IAAA;AAAA,EAAG,GAC9C,CAAC,QAAQ,CAAC;AAGb,YAAU,MAAM;AACV,QAAA,CAAC,YAAY,CAAC,WAAW;AAAO;AACpC,UAAM,YAAY,WAAW;AAE7B,UAAM,WAAW,UAAU,yBAAyB,IAAI,MAAM;;AAC5D,UAAI,CAAC,UAAU;AAAS;AACxB,iBAAW,UAAU,SAAS,QAAQ,WAAW,UAAU;AAChD,uBAAA,WAAA,mBAAQ,WAAW;AAC9B,eAAS,OAAO,KAAK;AAAA,IAAA,CACtB;AAED,WAAO,MAAM;AACD,gBAAA,yBAAyB,OAAO,QAAQ;AAAA,IAAA;AAAA,EACpD,GACC,CAAC,UAAU,WAAW,OAAO,QAAQ,UAAU,CAAC;AAGnD,QAAM,WAAuB;AAAA,IAC3B,GAAG;AAAA,IACH,OAAO,YAAY;AAAA,EAAA;AAGrB,6BACG,kBAAkB,UAAlB,EAA2B,OAAO,UAChC,SACH,CAAA;AAEJ,CAAC;AACD,YAAY,cAAc;"}
@@ -0,0 +1,35 @@
1
+ import { earthRadius } from "./main14.mjs";
2
+ const DEG2RAD = Math.PI / 180;
3
+ const mercatorScaleLookup = {};
4
+ function getMercatorScale(lat) {
5
+ const index = Math.round(lat * 1e3);
6
+ if (mercatorScaleLookup[index] === void 0) {
7
+ mercatorScaleLookup[index] = 1 / Math.cos(lat * DEG2RAD);
8
+ }
9
+ return mercatorScaleLookup[index];
10
+ }
11
+ function averageMercatorScale(originLat, pointLat, steps = 10) {
12
+ let totalScale = 0;
13
+ const latStep = (pointLat - originLat) / steps;
14
+ for (let i = 0; i <= steps; i++) {
15
+ const lat = originLat + latStep * i;
16
+ totalScale += getMercatorScale(lat);
17
+ }
18
+ return totalScale / (steps + 1);
19
+ }
20
+ function coordsToVector3(point, origin) {
21
+ const latitudeDiff = (point.latitude - origin.latitude) * DEG2RAD;
22
+ const longitudeDiff = (point.longitude - origin.longitude) * DEG2RAD;
23
+ const altitudeDiff = (point.altitude || 0) - (origin.altitude || 0);
24
+ const x = longitudeDiff * earthRadius * Math.cos(origin.latitude * DEG2RAD);
25
+ const y = altitudeDiff;
26
+ const steps = Math.ceil(Math.abs(point.latitude - origin.latitude)) * 100 + 1;
27
+ const avgScale = averageMercatorScale(origin.latitude, point.latitude, steps);
28
+ const z = -latitudeDiff * earthRadius / getMercatorScale(origin.latitude) * avgScale;
29
+ return [x, y, z];
30
+ }
31
+ export {
32
+ averageMercatorScale,
33
+ coordsToVector3
34
+ };
35
+ //# sourceMappingURL=main6.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main6.mjs","sources":["../../../src/api/coords-to-vector-3.ts"],"sourcesContent":["import { earthRadius } from '../core/earth-radius';\nimport { Coords } from './coords';\n\nconst DEG2RAD = Math.PI / 180;\n\nconst mercatorScaleLookup: { [key: number]: number } = {};\n\nfunction getMercatorScale(lat: number): number {\n const index = Math.round(lat * 1000);\n if (mercatorScaleLookup[index] === undefined) {\n mercatorScaleLookup[index] = 1 / Math.cos(lat * DEG2RAD);\n }\n return mercatorScaleLookup[index];\n}\n\nexport function averageMercatorScale(originLat: number, pointLat: number, steps = 10): number {\n let totalScale = 0;\n const latStep = (pointLat - originLat) / steps;\n for (let i = 0; i <= steps; i++) {\n const lat = originLat + latStep * i;\n totalScale += getMercatorScale(lat);\n }\n return totalScale / (steps + 1);\n}\n\nexport function coordsToVector3(point: Coords, origin: Coords): [number, number, number] {\n const latitudeDiff = (point.latitude - origin.latitude) * DEG2RAD;\n const longitudeDiff = (point.longitude - origin.longitude) * DEG2RAD;\n const altitudeDiff = (point.altitude || 0) - (origin.altitude || 0);\n\n const x = longitudeDiff * earthRadius * Math.cos(origin.latitude * DEG2RAD);\n const y = altitudeDiff;\n\n const steps = Math.ceil(Math.abs(point.latitude - origin.latitude)) * 100 + 1;\n const avgScale = averageMercatorScale(origin.latitude, point.latitude, steps);\n\n const z = ((-latitudeDiff * earthRadius) / getMercatorScale(origin.latitude)) * avgScale;\n return [x, y, z];\n}\n"],"names":[],"mappings":";AAGA,MAAM,UAAU,KAAK,KAAK;AAE1B,MAAM,sBAAiD,CAAA;AAEvD,SAAS,iBAAiB,KAAqB;AAC7C,QAAM,QAAQ,KAAK,MAAM,MAAM,GAAI;AAC/B,MAAA,oBAAoB,KAAK,MAAM,QAAW;AAC5C,wBAAoB,KAAK,IAAI,IAAI,KAAK,IAAI,MAAM,OAAO;AAAA,EACzD;AACA,SAAO,oBAAoB,KAAK;AAClC;AAEO,SAAS,qBAAqB,WAAmB,UAAkB,QAAQ,IAAY;AAC5F,MAAI,aAAa;AACX,QAAA,WAAW,WAAW,aAAa;AACzC,WAAS,IAAI,GAAG,KAAK,OAAO,KAAK;AACzB,UAAA,MAAM,YAAY,UAAU;AAClC,kBAAc,iBAAiB,GAAG;AAAA,EACpC;AACA,SAAO,cAAc,QAAQ;AAC/B;AAEgB,SAAA,gBAAgB,OAAe,QAA0C;AACvF,QAAM,gBAAgB,MAAM,WAAW,OAAO,YAAY;AAC1D,QAAM,iBAAiB,MAAM,YAAY,OAAO,aAAa;AAC7D,QAAM,gBAAgB,MAAM,YAAY,MAAM,OAAO,YAAY;AAEjE,QAAM,IAAI,gBAAgB,cAAc,KAAK,IAAI,OAAO,WAAW,OAAO;AAC1E,QAAM,IAAI;AAEJ,QAAA,QAAQ,KAAK,KAAK,KAAK,IAAI,MAAM,WAAW,OAAO,QAAQ,CAAC,IAAI,MAAM;AAC5E,QAAM,WAAW,qBAAqB,OAAO,UAAU,MAAM,UAAU,KAAK;AAE5E,QAAM,IAAM,CAAC,eAAe,cAAe,iBAAiB,OAAO,QAAQ,IAAK;AACzE,SAAA,CAAC,GAAG,GAAG,CAAC;AACjB;"}
@@ -0,0 +1,65 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Scene, Color4, FreeCamera, Vector3, HemisphericLight } from "@babylonjs/core";
3
+ import { memo, useState, useRef, useEffect } from "react";
4
+ import { useBabylonMap, BabylonMapContext } from "./main4.mjs";
5
+ import { useCoords } from "./main15.mjs";
6
+ import { coordsToVector3 } from "./main6.mjs";
7
+ const NearCoordinates = memo(({ children, ...coords }) => {
8
+ const { latitude, longitude, altitude } = useCoords();
9
+ const babylonMap = useBabylonMap();
10
+ const pos = coordsToVector3(coords, { latitude, longitude, altitude });
11
+ const [subScene] = useState(() => {
12
+ if (!babylonMap.engine)
13
+ return null;
14
+ const sub = new Scene(babylonMap.engine);
15
+ sub.autoClear = false;
16
+ sub.clearColor = new Color4(0, 0, 0, 0);
17
+ return sub;
18
+ });
19
+ const cameraRef = useRef(null);
20
+ useEffect(() => {
21
+ if (!subScene)
22
+ return;
23
+ const cam = new FreeCamera("nearCoordsCam", new Vector3(pos[0], pos[1], pos[2]), subScene);
24
+ cam.inputs.clear();
25
+ cam.minZ = 0;
26
+ cameraRef.current = cam;
27
+ const light = new HemisphericLight("nearCoordsLight", new Vector3(0, 1, 0), subScene);
28
+ light.intensity = 1;
29
+ return () => {
30
+ cam.dispose();
31
+ light.dispose();
32
+ };
33
+ }, [subScene]);
34
+ useEffect(() => {
35
+ if (!cameraRef.current)
36
+ return;
37
+ cameraRef.current.position.set(pos[0], pos[1], pos[2]);
38
+ }, [pos]);
39
+ useEffect(() => {
40
+ if (!subScene || !babylonMap.scene)
41
+ return;
42
+ const mainScene = babylonMap.scene;
43
+ const observer = mainScene.onBeforeRenderObservable.add(() => {
44
+ var _a;
45
+ if (!cameraRef.current)
46
+ return;
47
+ cameraRef.current.freezeProjectionMatrix(babylonMap.scene.activeCamera.getProjectionMatrix());
48
+ (_a = babylonMap.engine) == null ? void 0 : _a.wipeCaches(true);
49
+ subScene.render(false);
50
+ });
51
+ return () => {
52
+ mainScene.onBeforeRenderObservable.remove(observer);
53
+ };
54
+ }, [subScene, babylonMap.scene, babylonMap]);
55
+ const childMap = {
56
+ ...babylonMap,
57
+ scene: subScene || void 0
58
+ };
59
+ return /* @__PURE__ */ jsx(BabylonMapContext.Provider, { value: childMap, children });
60
+ });
61
+ NearCoordinates.displayName = "NearCoordinates";
62
+ export {
63
+ NearCoordinates
64
+ };
65
+ //# sourceMappingURL=main7.mjs.map