@ifc-lite/viewer 1.17.2 → 1.17.4

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 (520) hide show
  1. package/.turbo/turbo-build.log +34 -24
  2. package/.turbo/turbo-typecheck.log +1 -42
  3. package/CHANGELOG.md +24 -0
  4. package/DESKTOP_CONTRACT_VERSION +1 -0
  5. package/dist/assets/arrow-CZ5kQ26f.js +20 -0
  6. package/dist/assets/basketViewActivator-BmnNtVfZ.js +1 -0
  7. package/dist/assets/bcf-DOG9_WPX.js +281 -0
  8. package/dist/assets/{browser-BDShTXzi.js → browser-C5TFR7sH.js} +1 -1
  9. package/dist/assets/cesium-ADbP7waU.css +1 -0
  10. package/dist/assets/cesium-DUOzBlqv.js +17817 -0
  11. package/dist/assets/drawing-2d-gWfpdfYe.js +257 -0
  12. package/dist/assets/epsg-index.generated-BjJrt_0S.js +1 -0
  13. package/dist/assets/exporters-ChAtBmlj.js +80367 -0
  14. package/dist/assets/geometry.worker-BQ0rzNo-.js +1 -0
  15. package/dist/assets/ids-B4jTqB1O.js +1 -0
  16. package/dist/assets/ifc-lite_bg-BX4E7TX8.wasm +0 -0
  17. package/dist/assets/index-Co8E2-FE.js +106013 -0
  18. package/dist/assets/index-DckuDqlv.css +1 -0
  19. package/dist/assets/lens-CSASnhAL.js +1 -0
  20. package/dist/assets/maplibre-gl-CGLcoNXc.js +811 -0
  21. package/dist/assets/native-bridge-BRvbckFQ.js +429 -0
  22. package/dist/assets/{arrow2-bb-jcVEo.js → parquet-CEXmQNRO.js} +2 -2
  23. package/dist/assets/sandbox-DZiNLNMk.js +5933 -0
  24. package/dist/assets/server-client-BV8zHZ7Y.js +626 -0
  25. package/dist/assets/tauri-core-stub-D8Fa-u43.js +1 -0
  26. package/dist/assets/tauri-dialog-stub-r7Wksg7o.js +1 -0
  27. package/dist/assets/tauri-fs-stub-BdeRC7aK.js +1 -0
  28. package/dist/assets/wasm-bridge-g01g7T9b.js +1 -0
  29. package/dist/assets/zip-DBEtpeu6.js +12 -0
  30. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_0.json +1 -0
  31. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_1.json +1 -0
  32. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_10.json +1 -0
  33. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_11.json +1 -0
  34. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_12.json +1 -0
  35. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_13.json +1 -0
  36. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_14.json +1 -0
  37. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_15.json +1 -0
  38. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_16.json +1 -0
  39. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_17.json +1 -0
  40. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_18.json +1 -0
  41. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_19.json +1 -0
  42. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_2.json +1 -0
  43. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_20.json +1 -0
  44. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_21.json +1 -0
  45. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_22.json +1 -0
  46. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_23.json +1 -0
  47. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_24.json +1 -0
  48. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_25.json +1 -0
  49. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_26.json +1 -0
  50. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_27.json +1 -0
  51. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_3.json +1 -0
  52. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_4.json +1 -0
  53. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_5.json +1 -0
  54. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_6.json +1 -0
  55. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_7.json +1 -0
  56. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_8.json +1 -0
  57. package/dist/cesium/Assets/IAU2006_XYS/IAU2006_XYS_9.json +1 -0
  58. package/dist/cesium/Assets/Images/bing_maps_credit.png +0 -0
  59. package/dist/cesium/Assets/Images/cesium_credit.png +0 -0
  60. package/dist/cesium/Assets/Images/google_earth_credit.png +0 -0
  61. package/dist/cesium/Assets/Images/ion-credit.png +0 -0
  62. package/dist/cesium/Assets/Textures/LensFlare/DirtMask.jpg +0 -0
  63. package/dist/cesium/Assets/Textures/LensFlare/StarBurst.jpg +0 -0
  64. package/dist/cesium/Assets/Textures/NaturalEarthII/0/0/0.jpg +0 -0
  65. package/dist/cesium/Assets/Textures/NaturalEarthII/0/1/0.jpg +0 -0
  66. package/dist/cesium/Assets/Textures/NaturalEarthII/1/0/0.jpg +0 -0
  67. package/dist/cesium/Assets/Textures/NaturalEarthII/1/0/1.jpg +0 -0
  68. package/dist/cesium/Assets/Textures/NaturalEarthII/1/1/0.jpg +0 -0
  69. package/dist/cesium/Assets/Textures/NaturalEarthII/1/1/1.jpg +0 -0
  70. package/dist/cesium/Assets/Textures/NaturalEarthII/1/2/0.jpg +0 -0
  71. package/dist/cesium/Assets/Textures/NaturalEarthII/1/2/1.jpg +0 -0
  72. package/dist/cesium/Assets/Textures/NaturalEarthII/1/3/0.jpg +0 -0
  73. package/dist/cesium/Assets/Textures/NaturalEarthII/1/3/1.jpg +0 -0
  74. package/dist/cesium/Assets/Textures/NaturalEarthII/2/0/0.jpg +0 -0
  75. package/dist/cesium/Assets/Textures/NaturalEarthII/2/0/1.jpg +0 -0
  76. package/dist/cesium/Assets/Textures/NaturalEarthII/2/0/2.jpg +0 -0
  77. package/dist/cesium/Assets/Textures/NaturalEarthII/2/0/3.jpg +0 -0
  78. package/dist/cesium/Assets/Textures/NaturalEarthII/2/1/0.jpg +0 -0
  79. package/dist/cesium/Assets/Textures/NaturalEarthII/2/1/1.jpg +0 -0
  80. package/dist/cesium/Assets/Textures/NaturalEarthII/2/1/2.jpg +0 -0
  81. package/dist/cesium/Assets/Textures/NaturalEarthII/2/1/3.jpg +0 -0
  82. package/dist/cesium/Assets/Textures/NaturalEarthII/2/2/0.jpg +0 -0
  83. package/dist/cesium/Assets/Textures/NaturalEarthII/2/2/1.jpg +0 -0
  84. package/dist/cesium/Assets/Textures/NaturalEarthII/2/2/2.jpg +0 -0
  85. package/dist/cesium/Assets/Textures/NaturalEarthII/2/2/3.jpg +0 -0
  86. package/dist/cesium/Assets/Textures/NaturalEarthII/2/3/0.jpg +0 -0
  87. package/dist/cesium/Assets/Textures/NaturalEarthII/2/3/1.jpg +0 -0
  88. package/dist/cesium/Assets/Textures/NaturalEarthII/2/3/2.jpg +0 -0
  89. package/dist/cesium/Assets/Textures/NaturalEarthII/2/3/3.jpg +0 -0
  90. package/dist/cesium/Assets/Textures/NaturalEarthII/2/4/0.jpg +0 -0
  91. package/dist/cesium/Assets/Textures/NaturalEarthII/2/4/1.jpg +0 -0
  92. package/dist/cesium/Assets/Textures/NaturalEarthII/2/4/2.jpg +0 -0
  93. package/dist/cesium/Assets/Textures/NaturalEarthII/2/4/3.jpg +0 -0
  94. package/dist/cesium/Assets/Textures/NaturalEarthII/2/5/0.jpg +0 -0
  95. package/dist/cesium/Assets/Textures/NaturalEarthII/2/5/1.jpg +0 -0
  96. package/dist/cesium/Assets/Textures/NaturalEarthII/2/5/2.jpg +0 -0
  97. package/dist/cesium/Assets/Textures/NaturalEarthII/2/5/3.jpg +0 -0
  98. package/dist/cesium/Assets/Textures/NaturalEarthII/2/6/0.jpg +0 -0
  99. package/dist/cesium/Assets/Textures/NaturalEarthII/2/6/1.jpg +0 -0
  100. package/dist/cesium/Assets/Textures/NaturalEarthII/2/6/2.jpg +0 -0
  101. package/dist/cesium/Assets/Textures/NaturalEarthII/2/6/3.jpg +0 -0
  102. package/dist/cesium/Assets/Textures/NaturalEarthII/2/7/0.jpg +0 -0
  103. package/dist/cesium/Assets/Textures/NaturalEarthII/2/7/1.jpg +0 -0
  104. package/dist/cesium/Assets/Textures/NaturalEarthII/2/7/2.jpg +0 -0
  105. package/dist/cesium/Assets/Textures/NaturalEarthII/2/7/3.jpg +0 -0
  106. package/dist/cesium/Assets/Textures/NaturalEarthII/tilemapresource.xml +14 -0
  107. package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_mx.jpg +0 -0
  108. package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_my.jpg +0 -0
  109. package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_mz.jpg +0 -0
  110. package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_px.jpg +0 -0
  111. package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_py.jpg +0 -0
  112. package/dist/cesium/Assets/Textures/SkyBox/tycho2t3_80_pz.jpg +0 -0
  113. package/dist/cesium/Assets/Textures/maki/airfield.png +0 -0
  114. package/dist/cesium/Assets/Textures/maki/airport.png +0 -0
  115. package/dist/cesium/Assets/Textures/maki/alcohol-shop.png +0 -0
  116. package/dist/cesium/Assets/Textures/maki/america-football.png +0 -0
  117. package/dist/cesium/Assets/Textures/maki/art-gallery.png +0 -0
  118. package/dist/cesium/Assets/Textures/maki/bakery.png +0 -0
  119. package/dist/cesium/Assets/Textures/maki/bank.png +0 -0
  120. package/dist/cesium/Assets/Textures/maki/bar.png +0 -0
  121. package/dist/cesium/Assets/Textures/maki/baseball.png +0 -0
  122. package/dist/cesium/Assets/Textures/maki/basketball.png +0 -0
  123. package/dist/cesium/Assets/Textures/maki/beer.png +0 -0
  124. package/dist/cesium/Assets/Textures/maki/bicycle.png +0 -0
  125. package/dist/cesium/Assets/Textures/maki/building.png +0 -0
  126. package/dist/cesium/Assets/Textures/maki/bus.png +0 -0
  127. package/dist/cesium/Assets/Textures/maki/cafe.png +0 -0
  128. package/dist/cesium/Assets/Textures/maki/camera.png +0 -0
  129. package/dist/cesium/Assets/Textures/maki/campsite.png +0 -0
  130. package/dist/cesium/Assets/Textures/maki/car.png +0 -0
  131. package/dist/cesium/Assets/Textures/maki/cemetery.png +0 -0
  132. package/dist/cesium/Assets/Textures/maki/cesium.png +0 -0
  133. package/dist/cesium/Assets/Textures/maki/chemist.png +0 -0
  134. package/dist/cesium/Assets/Textures/maki/cinema.png +0 -0
  135. package/dist/cesium/Assets/Textures/maki/circle-stroked.png +0 -0
  136. package/dist/cesium/Assets/Textures/maki/circle.png +0 -0
  137. package/dist/cesium/Assets/Textures/maki/city.png +0 -0
  138. package/dist/cesium/Assets/Textures/maki/clothing-store.png +0 -0
  139. package/dist/cesium/Assets/Textures/maki/college.png +0 -0
  140. package/dist/cesium/Assets/Textures/maki/commercial.png +0 -0
  141. package/dist/cesium/Assets/Textures/maki/cricket.png +0 -0
  142. package/dist/cesium/Assets/Textures/maki/cross.png +0 -0
  143. package/dist/cesium/Assets/Textures/maki/dam.png +0 -0
  144. package/dist/cesium/Assets/Textures/maki/danger.png +0 -0
  145. package/dist/cesium/Assets/Textures/maki/disability.png +0 -0
  146. package/dist/cesium/Assets/Textures/maki/dog-park.png +0 -0
  147. package/dist/cesium/Assets/Textures/maki/embassy.png +0 -0
  148. package/dist/cesium/Assets/Textures/maki/emergency-telephone.png +0 -0
  149. package/dist/cesium/Assets/Textures/maki/entrance.png +0 -0
  150. package/dist/cesium/Assets/Textures/maki/farm.png +0 -0
  151. package/dist/cesium/Assets/Textures/maki/fast-food.png +0 -0
  152. package/dist/cesium/Assets/Textures/maki/ferry.png +0 -0
  153. package/dist/cesium/Assets/Textures/maki/fire-station.png +0 -0
  154. package/dist/cesium/Assets/Textures/maki/fuel.png +0 -0
  155. package/dist/cesium/Assets/Textures/maki/garden.png +0 -0
  156. package/dist/cesium/Assets/Textures/maki/gift.png +0 -0
  157. package/dist/cesium/Assets/Textures/maki/golf.png +0 -0
  158. package/dist/cesium/Assets/Textures/maki/grocery.png +0 -0
  159. package/dist/cesium/Assets/Textures/maki/hairdresser.png +0 -0
  160. package/dist/cesium/Assets/Textures/maki/harbor.png +0 -0
  161. package/dist/cesium/Assets/Textures/maki/heart.png +0 -0
  162. package/dist/cesium/Assets/Textures/maki/heliport.png +0 -0
  163. package/dist/cesium/Assets/Textures/maki/hospital.png +0 -0
  164. package/dist/cesium/Assets/Textures/maki/ice-cream.png +0 -0
  165. package/dist/cesium/Assets/Textures/maki/industrial.png +0 -0
  166. package/dist/cesium/Assets/Textures/maki/land-use.png +0 -0
  167. package/dist/cesium/Assets/Textures/maki/laundry.png +0 -0
  168. package/dist/cesium/Assets/Textures/maki/library.png +0 -0
  169. package/dist/cesium/Assets/Textures/maki/lighthouse.png +0 -0
  170. package/dist/cesium/Assets/Textures/maki/lodging.png +0 -0
  171. package/dist/cesium/Assets/Textures/maki/logging.png +0 -0
  172. package/dist/cesium/Assets/Textures/maki/london-underground.png +0 -0
  173. package/dist/cesium/Assets/Textures/maki/marker-stroked.png +0 -0
  174. package/dist/cesium/Assets/Textures/maki/marker.png +0 -0
  175. package/dist/cesium/Assets/Textures/maki/minefield.png +0 -0
  176. package/dist/cesium/Assets/Textures/maki/mobilephone.png +0 -0
  177. package/dist/cesium/Assets/Textures/maki/monument.png +0 -0
  178. package/dist/cesium/Assets/Textures/maki/museum.png +0 -0
  179. package/dist/cesium/Assets/Textures/maki/music.png +0 -0
  180. package/dist/cesium/Assets/Textures/maki/oil-well.png +0 -0
  181. package/dist/cesium/Assets/Textures/maki/park.png +0 -0
  182. package/dist/cesium/Assets/Textures/maki/park2.png +0 -0
  183. package/dist/cesium/Assets/Textures/maki/parking-garage.png +0 -0
  184. package/dist/cesium/Assets/Textures/maki/parking.png +0 -0
  185. package/dist/cesium/Assets/Textures/maki/pharmacy.png +0 -0
  186. package/dist/cesium/Assets/Textures/maki/pitch.png +0 -0
  187. package/dist/cesium/Assets/Textures/maki/place-of-worship.png +0 -0
  188. package/dist/cesium/Assets/Textures/maki/playground.png +0 -0
  189. package/dist/cesium/Assets/Textures/maki/police.png +0 -0
  190. package/dist/cesium/Assets/Textures/maki/polling-place.png +0 -0
  191. package/dist/cesium/Assets/Textures/maki/post.png +0 -0
  192. package/dist/cesium/Assets/Textures/maki/prison.png +0 -0
  193. package/dist/cesium/Assets/Textures/maki/rail-above.png +0 -0
  194. package/dist/cesium/Assets/Textures/maki/rail-light.png +0 -0
  195. package/dist/cesium/Assets/Textures/maki/rail-metro.png +0 -0
  196. package/dist/cesium/Assets/Textures/maki/rail-underground.png +0 -0
  197. package/dist/cesium/Assets/Textures/maki/rail.png +0 -0
  198. package/dist/cesium/Assets/Textures/maki/religious-christian.png +0 -0
  199. package/dist/cesium/Assets/Textures/maki/religious-jewish.png +0 -0
  200. package/dist/cesium/Assets/Textures/maki/religious-muslim.png +0 -0
  201. package/dist/cesium/Assets/Textures/maki/restaurant.png +0 -0
  202. package/dist/cesium/Assets/Textures/maki/roadblock.png +0 -0
  203. package/dist/cesium/Assets/Textures/maki/rocket.png +0 -0
  204. package/dist/cesium/Assets/Textures/maki/school.png +0 -0
  205. package/dist/cesium/Assets/Textures/maki/scooter.png +0 -0
  206. package/dist/cesium/Assets/Textures/maki/shop.png +0 -0
  207. package/dist/cesium/Assets/Textures/maki/skiing.png +0 -0
  208. package/dist/cesium/Assets/Textures/maki/slaughterhouse.png +0 -0
  209. package/dist/cesium/Assets/Textures/maki/soccer.png +0 -0
  210. package/dist/cesium/Assets/Textures/maki/square-stroked.png +0 -0
  211. package/dist/cesium/Assets/Textures/maki/square.png +0 -0
  212. package/dist/cesium/Assets/Textures/maki/star-stroked.png +0 -0
  213. package/dist/cesium/Assets/Textures/maki/star.png +0 -0
  214. package/dist/cesium/Assets/Textures/maki/suitcase.png +0 -0
  215. package/dist/cesium/Assets/Textures/maki/swimming.png +0 -0
  216. package/dist/cesium/Assets/Textures/maki/telephone.png +0 -0
  217. package/dist/cesium/Assets/Textures/maki/tennis.png +0 -0
  218. package/dist/cesium/Assets/Textures/maki/theatre.png +0 -0
  219. package/dist/cesium/Assets/Textures/maki/toilets.png +0 -0
  220. package/dist/cesium/Assets/Textures/maki/town-hall.png +0 -0
  221. package/dist/cesium/Assets/Textures/maki/town.png +0 -0
  222. package/dist/cesium/Assets/Textures/maki/triangle-stroked.png +0 -0
  223. package/dist/cesium/Assets/Textures/maki/triangle.png +0 -0
  224. package/dist/cesium/Assets/Textures/maki/village.png +0 -0
  225. package/dist/cesium/Assets/Textures/maki/warehouse.png +0 -0
  226. package/dist/cesium/Assets/Textures/maki/waste-basket.png +0 -0
  227. package/dist/cesium/Assets/Textures/maki/water.png +0 -0
  228. package/dist/cesium/Assets/Textures/maki/wetland.png +0 -0
  229. package/dist/cesium/Assets/Textures/maki/zoo.png +0 -0
  230. package/dist/cesium/Assets/Textures/moonSmall.jpg +0 -0
  231. package/dist/cesium/Assets/Textures/pin.svg +1 -0
  232. package/dist/cesium/Assets/Textures/waterNormals.jpg +0 -0
  233. package/dist/cesium/Assets/Textures/waterNormalsSmall.jpg +0 -0
  234. package/dist/cesium/Assets/approximateTerrainHeights.json +1 -0
  235. package/dist/cesium/ThirdParty/Workers/package.json +1 -0
  236. package/dist/cesium/ThirdParty/Workers/zip-web-worker.js +1 -0
  237. package/dist/cesium/ThirdParty/basis_transcoder.wasm +0 -0
  238. package/dist/cesium/ThirdParty/draco_decoder.wasm +0 -0
  239. package/dist/cesium/ThirdParty/google-earth-dbroot-parser.js +1 -0
  240. package/dist/cesium/ThirdParty/wasm_splats_bg.wasm +0 -0
  241. package/dist/cesium/ThirdParty/zip-module.wasm +0 -0
  242. package/dist/cesium/Widgets/Animation/Animation.css +127 -0
  243. package/dist/cesium/Widgets/Animation/lighter.css +70 -0
  244. package/dist/cesium/Widgets/BaseLayerPicker/BaseLayerPicker.css +108 -0
  245. package/dist/cesium/Widgets/BaseLayerPicker/lighter.css +22 -0
  246. package/dist/cesium/Widgets/Cesium3DTilesInspector/Cesium3DTilesInspector.css +102 -0
  247. package/dist/cesium/Widgets/CesiumInspector/CesiumInspector.css +113 -0
  248. package/dist/cesium/Widgets/CesiumWidget/CesiumWidget.css +119 -0
  249. package/dist/cesium/Widgets/CesiumWidget/lighter.css +14 -0
  250. package/dist/cesium/Widgets/FullscreenButton/FullscreenButton.css +8 -0
  251. package/dist/cesium/Widgets/Geocoder/Geocoder.css +70 -0
  252. package/dist/cesium/Widgets/Geocoder/lighter.css +17 -0
  253. package/dist/cesium/Widgets/I3SBuildingSceneLayerExplorer/I3SBuildingSceneLayerExplorer.css +27 -0
  254. package/dist/cesium/Widgets/Images/ImageryProviders/ArcGisMapServiceWorldHillshade.png +0 -0
  255. package/dist/cesium/Widgets/Images/ImageryProviders/ArcGisMapServiceWorldImagery.png +0 -0
  256. package/dist/cesium/Widgets/Images/ImageryProviders/ArcGisMapServiceWorldOcean.png +0 -0
  257. package/dist/cesium/Widgets/Images/ImageryProviders/azureAerial.png +0 -0
  258. package/dist/cesium/Widgets/Images/ImageryProviders/azureRoads.png +0 -0
  259. package/dist/cesium/Widgets/Images/ImageryProviders/bingAerial.png +0 -0
  260. package/dist/cesium/Widgets/Images/ImageryProviders/bingAerialLabels.png +0 -0
  261. package/dist/cesium/Widgets/Images/ImageryProviders/bingRoads.png +0 -0
  262. package/dist/cesium/Widgets/Images/ImageryProviders/blueMarble.png +0 -0
  263. package/dist/cesium/Widgets/Images/ImageryProviders/earthAtNight.png +0 -0
  264. package/dist/cesium/Widgets/Images/ImageryProviders/googleContour.png +0 -0
  265. package/dist/cesium/Widgets/Images/ImageryProviders/googleRoadmap.png +0 -0
  266. package/dist/cesium/Widgets/Images/ImageryProviders/googleSatellite.png +0 -0
  267. package/dist/cesium/Widgets/Images/ImageryProviders/googleSatelliteLabels.png +0 -0
  268. package/dist/cesium/Widgets/Images/ImageryProviders/mapQuestOpenStreetMap.png +0 -0
  269. package/dist/cesium/Widgets/Images/ImageryProviders/mapboxSatellite.png +0 -0
  270. package/dist/cesium/Widgets/Images/ImageryProviders/mapboxStreets.png +0 -0
  271. package/dist/cesium/Widgets/Images/ImageryProviders/mapboxTerrain.png +0 -0
  272. package/dist/cesium/Widgets/Images/ImageryProviders/naturalEarthII.png +0 -0
  273. package/dist/cesium/Widgets/Images/ImageryProviders/openStreetMap.png +0 -0
  274. package/dist/cesium/Widgets/Images/ImageryProviders/sentinel-2.png +0 -0
  275. package/dist/cesium/Widgets/Images/ImageryProviders/stadiaAlidadeSmooth.png +0 -0
  276. package/dist/cesium/Widgets/Images/ImageryProviders/stadiaAlidadeSmoothDark.png +0 -0
  277. package/dist/cesium/Widgets/Images/ImageryProviders/stamenToner.png +0 -0
  278. package/dist/cesium/Widgets/Images/ImageryProviders/stamenWatercolor.png +0 -0
  279. package/dist/cesium/Widgets/Images/NavigationHelp/Mouse.svg +84 -0
  280. package/dist/cesium/Widgets/Images/NavigationHelp/MouseLeft.svg +76 -0
  281. package/dist/cesium/Widgets/Images/NavigationHelp/MouseMiddle.svg +76 -0
  282. package/dist/cesium/Widgets/Images/NavigationHelp/MouseRight.svg +76 -0
  283. package/dist/cesium/Widgets/Images/NavigationHelp/Touch.svg +120 -0
  284. package/dist/cesium/Widgets/Images/NavigationHelp/TouchDrag.svg +129 -0
  285. package/dist/cesium/Widgets/Images/NavigationHelp/TouchRotate.svg +76 -0
  286. package/dist/cesium/Widgets/Images/NavigationHelp/TouchTilt.svg +135 -0
  287. package/dist/cesium/Widgets/Images/NavigationHelp/TouchZoom.svg +74 -0
  288. package/dist/cesium/Widgets/Images/TerrainProviders/CesiumWorldTerrain.png +0 -0
  289. package/dist/cesium/Widgets/Images/TerrainProviders/Ellipsoid.png +0 -0
  290. package/dist/cesium/Widgets/Images/TimelineIcons.png +0 -0
  291. package/dist/cesium/Widgets/Images/info-loading.gif +0 -0
  292. package/dist/cesium/Widgets/InfoBox/InfoBox.css +92 -0
  293. package/dist/cesium/Widgets/InfoBox/InfoBoxDescription.css +178 -0
  294. package/dist/cesium/Widgets/NavigationHelpButton/NavigationHelpButton.css +93 -0
  295. package/dist/cesium/Widgets/NavigationHelpButton/lighter.css +38 -0
  296. package/dist/cesium/Widgets/PerformanceWatchdog/PerformanceWatchdog.css +15 -0
  297. package/dist/cesium/Widgets/ProjectionPicker/ProjectionPicker.css +38 -0
  298. package/dist/cesium/Widgets/SceneModePicker/SceneModePicker.css +56 -0
  299. package/dist/cesium/Widgets/SelectionIndicator/SelectionIndicator.css +20 -0
  300. package/dist/cesium/Widgets/Timeline/Timeline.css +103 -0
  301. package/dist/cesium/Widgets/Timeline/lighter.css +23 -0
  302. package/dist/cesium/Widgets/VRButton/VRButton.css +8 -0
  303. package/dist/cesium/Widgets/Viewer/Viewer.css +107 -0
  304. package/dist/cesium/Widgets/VoxelInspector/VoxelInspector.css +16 -0
  305. package/dist/cesium/Widgets/lighter.css +237 -0
  306. package/dist/cesium/Widgets/lighterShared.css +46 -0
  307. package/dist/cesium/Widgets/shared.css +103 -0
  308. package/dist/cesium/Widgets/widgets.css +1342 -0
  309. package/dist/cesium/Workers/chunk-23ZQ2IVV.js +29 -0
  310. package/dist/cesium/Workers/chunk-2EQO3Q56.js +26 -0
  311. package/dist/cesium/Workers/chunk-2MJIIVP4.js +26 -0
  312. package/dist/cesium/Workers/chunk-2TE5NTVD.js +26 -0
  313. package/dist/cesium/Workers/chunk-2ZBHLJST.js +26 -0
  314. package/dist/cesium/Workers/chunk-5TJMAQVL.js +26 -0
  315. package/dist/cesium/Workers/chunk-6BD4U3VO.js +26 -0
  316. package/dist/cesium/Workers/chunk-7TVGLKQF.js +26 -0
  317. package/dist/cesium/Workers/chunk-BTSYJ5XU.js +26 -0
  318. package/dist/cesium/Workers/chunk-BXMEEOCS.js +63 -0
  319. package/dist/cesium/Workers/chunk-BYLCY7GP.js +29 -0
  320. package/dist/cesium/Workers/chunk-CTHM3W6I.js +26 -0
  321. package/dist/cesium/Workers/chunk-CUUSNIVQ.js +26 -0
  322. package/dist/cesium/Workers/chunk-E3JOOS3S.js +26 -0
  323. package/dist/cesium/Workers/chunk-E7KYDCM5.js +26 -0
  324. package/dist/cesium/Workers/chunk-EDVBB7SS.js +27 -0
  325. package/dist/cesium/Workers/chunk-EFBN7QNX.js +26 -0
  326. package/dist/cesium/Workers/chunk-EQ4YRVWL.js +26 -0
  327. package/dist/cesium/Workers/chunk-F6PRE7D6.js +26 -0
  328. package/dist/cesium/Workers/chunk-FC4ZZ65J.js +26 -0
  329. package/dist/cesium/Workers/chunk-FFBVWF2L.js +26 -0
  330. package/dist/cesium/Workers/chunk-GBAA6GVX.js +26 -0
  331. package/dist/cesium/Workers/chunk-ICALLYLG.js +26 -0
  332. package/dist/cesium/Workers/chunk-ILRYTWTP.js +26 -0
  333. package/dist/cesium/Workers/chunk-IRNLBSEJ.js +26 -0
  334. package/dist/cesium/Workers/chunk-IX4VMHEV.js +26 -0
  335. package/dist/cesium/Workers/chunk-L6QHHACZ.js +26 -0
  336. package/dist/cesium/Workers/chunk-LI2ZSORM.js +26 -0
  337. package/dist/cesium/Workers/chunk-LSLE2RL4.js +26 -0
  338. package/dist/cesium/Workers/chunk-M4HLDBCG.js +26 -0
  339. package/dist/cesium/Workers/chunk-MJHHSGEH.js +26 -0
  340. package/dist/cesium/Workers/chunk-NMVKML6W.js +26 -0
  341. package/dist/cesium/Workers/chunk-OCWJRAXS.js +26 -0
  342. package/dist/cesium/Workers/chunk-OIRKANTH.js +26 -0
  343. package/dist/cesium/Workers/chunk-OIT7J4IC.js +26 -0
  344. package/dist/cesium/Workers/chunk-OLZ3FYUM.js +26 -0
  345. package/dist/cesium/Workers/chunk-Q5BPHJQF.js +26 -0
  346. package/dist/cesium/Workers/chunk-QFM5DCMQ.js +26 -0
  347. package/dist/cesium/Workers/chunk-QKUIYMGC.js +28 -0
  348. package/dist/cesium/Workers/chunk-S44JILQT.js +26 -0
  349. package/dist/cesium/Workers/chunk-SLT4J352.js +26 -0
  350. package/dist/cesium/Workers/chunk-SQMIIXB7.js +26 -0
  351. package/dist/cesium/Workers/chunk-TJ4XLGBQ.js +26 -0
  352. package/dist/cesium/Workers/chunk-TNSUQXWK.js +27 -0
  353. package/dist/cesium/Workers/chunk-UBOGZS7F.js +26 -0
  354. package/dist/cesium/Workers/chunk-V3OSTMM6.js +26 -0
  355. package/dist/cesium/Workers/chunk-V7QEYVP3.js +26 -0
  356. package/dist/cesium/Workers/chunk-VUKYSU4H.js +26 -0
  357. package/dist/cesium/Workers/chunk-W37FE5GR.js +26 -0
  358. package/dist/cesium/Workers/chunk-WBOV35NL.js +26 -0
  359. package/dist/cesium/Workers/chunk-WPMZLB3Y.js +26 -0
  360. package/dist/cesium/Workers/chunk-WWWZVEEH.js +26 -0
  361. package/dist/cesium/Workers/chunk-XFIQ5DEQ.js +28 -0
  362. package/dist/cesium/Workers/chunk-XQHLGIO7.js +26 -0
  363. package/dist/cesium/Workers/chunk-XUSCFAVF.js +26 -0
  364. package/dist/cesium/Workers/chunk-YP7I5QBZ.js +26 -0
  365. package/dist/cesium/Workers/chunk-Z3QF2EHT.js +26 -0
  366. package/dist/cesium/Workers/combineGeometry.js +26 -0
  367. package/dist/cesium/Workers/createBoxGeometry.js +26 -0
  368. package/dist/cesium/Workers/createBoxOutlineGeometry.js +26 -0
  369. package/dist/cesium/Workers/createCircleGeometry.js +26 -0
  370. package/dist/cesium/Workers/createCircleOutlineGeometry.js +26 -0
  371. package/dist/cesium/Workers/createCoplanarPolygonGeometry.js +26 -0
  372. package/dist/cesium/Workers/createCoplanarPolygonOutlineGeometry.js +26 -0
  373. package/dist/cesium/Workers/createCorridorGeometry.js +26 -0
  374. package/dist/cesium/Workers/createCorridorOutlineGeometry.js +26 -0
  375. package/dist/cesium/Workers/createCylinderGeometry.js +26 -0
  376. package/dist/cesium/Workers/createCylinderOutlineGeometry.js +26 -0
  377. package/dist/cesium/Workers/createEllipseGeometry.js +26 -0
  378. package/dist/cesium/Workers/createEllipseOutlineGeometry.js +26 -0
  379. package/dist/cesium/Workers/createEllipsoidGeometry.js +26 -0
  380. package/dist/cesium/Workers/createEllipsoidOutlineGeometry.js +26 -0
  381. package/dist/cesium/Workers/createFrustumGeometry.js +26 -0
  382. package/dist/cesium/Workers/createFrustumOutlineGeometry.js +26 -0
  383. package/dist/cesium/Workers/createGeometry.js +26 -0
  384. package/dist/cesium/Workers/createGroundPolylineGeometry.js +26 -0
  385. package/dist/cesium/Workers/createPlaneGeometry.js +26 -0
  386. package/dist/cesium/Workers/createPlaneOutlineGeometry.js +26 -0
  387. package/dist/cesium/Workers/createPolygonGeometry.js +26 -0
  388. package/dist/cesium/Workers/createPolygonOutlineGeometry.js +26 -0
  389. package/dist/cesium/Workers/createPolylineGeometry.js +26 -0
  390. package/dist/cesium/Workers/createPolylineVolumeGeometry.js +26 -0
  391. package/dist/cesium/Workers/createPolylineVolumeOutlineGeometry.js +26 -0
  392. package/dist/cesium/Workers/createRectangleGeometry.js +26 -0
  393. package/dist/cesium/Workers/createRectangleOutlineGeometry.js +26 -0
  394. package/dist/cesium/Workers/createSimplePolylineGeometry.js +26 -0
  395. package/dist/cesium/Workers/createSphereGeometry.js +26 -0
  396. package/dist/cesium/Workers/createSphereOutlineGeometry.js +26 -0
  397. package/dist/cesium/Workers/createTaskProcessorWorker.js +26 -0
  398. package/dist/cesium/Workers/createVectorTileClampedPolylines.js +26 -0
  399. package/dist/cesium/Workers/createVectorTileGeometries.js +26 -0
  400. package/dist/cesium/Workers/createVectorTilePoints.js +26 -0
  401. package/dist/cesium/Workers/createVectorTilePolygons.js +26 -0
  402. package/dist/cesium/Workers/createVectorTilePolylines.js +26 -0
  403. package/dist/cesium/Workers/createVerticesFromCesium3DTilesTerrain.js +26 -0
  404. package/dist/cesium/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +26 -0
  405. package/dist/cesium/Workers/createVerticesFromHeightmap.js +26 -0
  406. package/dist/cesium/Workers/createVerticesFromQuantizedTerrainMesh.js +26 -0
  407. package/dist/cesium/Workers/createWallGeometry.js +26 -0
  408. package/dist/cesium/Workers/createWallOutlineGeometry.js +26 -0
  409. package/dist/cesium/Workers/decodeDraco.js +26 -0
  410. package/dist/cesium/Workers/decodeGoogleEarthEnterprisePacket.js +26 -0
  411. package/dist/cesium/Workers/decodeI3S.js +26 -0
  412. package/dist/cesium/Workers/gaussianSplatSorter.js +26 -0
  413. package/dist/cesium/Workers/gaussianSplatTextureGenerator.js +26 -0
  414. package/dist/cesium/Workers/incrementallyBuildTerrainPicker.js +26 -0
  415. package/dist/cesium/Workers/transcodeKTX2.js +56 -0
  416. package/dist/cesium/Workers/transferTypedArrayTest.js +26 -0
  417. package/dist/cesium/Workers/upsampleQuantizedTerrainMesh.js +26 -0
  418. package/dist/cesium/Workers/upsampleVerticesFromCesium3DTilesTerrain.js +26 -0
  419. package/dist/index.html +13 -2
  420. package/package.json +27 -19
  421. package/src/App.tsx +1 -17
  422. package/src/components/viewer/BCFPanel.tsx +46 -4
  423. package/src/components/viewer/CesiumOverlay.tsx +672 -0
  424. package/src/components/viewer/CesiumSettingsDialog.tsx +100 -0
  425. package/src/components/viewer/ChatPanel.tsx +54 -16
  426. package/src/components/viewer/CommandPalette.tsx +6 -1
  427. package/src/components/viewer/DesktopEntitlementBanner.tsx +74 -0
  428. package/src/components/viewer/ExportChangesButton.tsx +24 -4
  429. package/src/components/viewer/ExportDialog.tsx +38 -9
  430. package/src/components/viewer/HierarchyPanel.tsx +202 -6
  431. package/src/components/viewer/IDSPanel.tsx +52 -3
  432. package/src/components/viewer/KeyboardShortcutsDialog.tsx +1 -1
  433. package/src/components/viewer/MainToolbar.tsx +353 -27
  434. package/src/components/viewer/PropertiesPanel.tsx +306 -131
  435. package/src/components/viewer/ScriptPanel.tsx +34 -8
  436. package/src/components/viewer/Section2DPanel.tsx +3 -2
  437. package/src/components/viewer/SettingsPage.tsx +430 -0
  438. package/src/components/viewer/StatusBar.tsx +17 -1
  439. package/src/components/viewer/UpgradePage.tsx +6 -4
  440. package/src/components/viewer/ViewerLayout.tsx +47 -6
  441. package/src/components/viewer/Viewport.tsx +49 -8
  442. package/src/components/viewer/ViewportContainer.tsx +285 -32
  443. package/src/components/viewer/ViewportOverlays.tsx +129 -27
  444. package/src/components/viewer/hierarchy/treeDataBuilder.ts +2 -1
  445. package/src/components/viewer/properties/EpsgLookupDialog.tsx +418 -0
  446. package/src/components/viewer/properties/GeoreferencingPanel.tsx +703 -0
  447. package/src/components/viewer/properties/LocationMap.tsx +730 -0
  448. package/src/components/viewer/properties/ModelMetadataPanel.tsx +3 -70
  449. package/src/components/viewer/selectionHandlers.ts +4 -3
  450. package/src/components/viewer/useAnimationLoop.ts +4 -0
  451. package/src/components/viewer/useGeometryStreaming.ts +127 -40
  452. package/src/components/viewer/useMouseControls.ts +4 -1
  453. package/src/hooks/bcfIdLookup.ts +13 -11
  454. package/src/hooks/ids/idsColorSystem.ts +3 -8
  455. package/src/hooks/ingest/viewerModelIngest.ts +275 -0
  456. package/src/hooks/useIDS.ts +32 -17
  457. package/src/hooks/useIfc.ts +7 -1
  458. package/src/hooks/useIfcCache.ts +28 -15
  459. package/src/hooks/useIfcFederation.ts +59 -227
  460. package/src/hooks/useIfcLoader.ts +1656 -130
  461. package/src/hooks/useIfcServer.ts +0 -69
  462. package/src/lib/desktop/ClerkDesktopEntitlementSync.tsx +175 -0
  463. package/src/lib/desktop/desktopEntitlementEvents.ts +39 -0
  464. package/src/lib/desktop-entitlement.ts +45 -0
  465. package/src/lib/desktop-product.ts +124 -0
  466. package/src/lib/geo/cesium-bridge.ts +310 -0
  467. package/src/lib/geo/kmz-exporter.ts +112 -0
  468. package/src/lib/geo/reproject.ts +370 -0
  469. package/src/lib/lens/adapter.ts +3 -1
  470. package/src/lib/recent-files.ts +2 -1
  471. package/src/main.tsx +1 -0
  472. package/src/sdk/adapters/export-adapter.ts +14 -1
  473. package/src/sdk/adapters/viewer-adapter.ts +5 -9
  474. package/src/sdk/adapters/visibility-adapter.ts +6 -9
  475. package/src/services/analysis-extensions.ts +125 -0
  476. package/src/services/app-navigation.ts +13 -0
  477. package/src/services/bsdd.ts +53 -4
  478. package/src/services/cacheService.ts +1 -1
  479. package/src/services/desktop-cache.ts +43 -0
  480. package/src/services/desktop-export.ts +77 -0
  481. package/src/services/desktop-harness.ts +196 -0
  482. package/src/services/desktop-logger.ts +20 -0
  483. package/src/services/desktop-native-metadata.ts +207 -0
  484. package/src/services/desktop-panel-actions.ts +43 -0
  485. package/src/services/desktop-preferences.ts +44 -0
  486. package/src/services/file-dialog.ts +147 -0
  487. package/src/services/tauri-core-stub.ts +7 -0
  488. package/src/services/tauri-dialog-stub.ts +7 -0
  489. package/src/services/tauri-fs-stub.ts +7 -0
  490. package/src/store/basketVisibleSet.ts +3 -4
  491. package/src/store/globalId.ts +79 -0
  492. package/src/store/index.ts +41 -2
  493. package/src/store/slices/cesiumSlice.ts +122 -0
  494. package/src/store/slices/chatSlice.ts +5 -1
  495. package/src/store/slices/dataSlice.ts +139 -28
  496. package/src/store/slices/desktopEntitlementSlice.ts +86 -0
  497. package/src/store/slices/loadingSlice.ts +14 -2
  498. package/src/store/slices/modelSlice.ts +58 -3
  499. package/src/store/slices/mutationSlice.ts +178 -0
  500. package/src/store/slices/pinboardSlice.ts +4 -8
  501. package/src/store/types.ts +96 -2
  502. package/src/store.ts +1 -1
  503. package/src/utils/desktopModelSnapshot.ts +358 -0
  504. package/src/utils/ifcConfig.ts +6 -1
  505. package/src/utils/nativeSpatialDataStore.ts +250 -0
  506. package/src/utils/serverDataModel.ts +4 -0
  507. package/src/utils/spatialHierarchy.ts +10 -11
  508. package/vite.config.ts +41 -0
  509. package/dist/assets/Arrow.dom-BhOg9lpn.js +0 -20
  510. package/dist/assets/arrow2_bg-BlXl-cSQ.js +0 -1
  511. package/dist/assets/basketViewActivator-BRG5DBmM.js +0 -1
  512. package/dist/assets/desktop-cache-oPzaWXYE.js +0 -1
  513. package/dist/assets/geometry.worker-kgiT_Qhh.js +0 -1
  514. package/dist/assets/ifc-lite_bg-FNRmpSvM.wasm +0 -0
  515. package/dist/assets/index-B1Ecw4AU.js +0 -189756
  516. package/dist/assets/index-Ba4eoTe7.css +0 -1
  517. package/dist/assets/index-CrgYBjTn.js +0 -229
  518. package/dist/assets/module-6F3E5H7Y-tx0BadV3.js +0 -6
  519. package/dist/assets/native-bridge-Crsb7TKz.js +0 -111
  520. package/dist/assets/wasm-bridge-mJUhb7uk.js +0 -1
@@ -0,0 +1,310 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+
5
+ /**
6
+ * Cesium coordinate bridge — lookAtTransform approach.
7
+ *
8
+ * KEY INSIGHT (from Cesium GitHub #6032): Camera.setView() with direction/up
9
+ * vectors causes drift because it doesn't properly orthonormalize. The fix:
10
+ * use lookAtTransform() which sets a reference frame and keeps the camera
11
+ * matrix clean.
12
+ *
13
+ * APPROACH: Build a single 4x4 matrix that transforms from IFC viewer space
14
+ * to ECEF, pass it to Cesium via lookAtTransform(). Then set camera position,
15
+ * direction, and up in IFC viewer coordinates — Cesium applies the transform
16
+ * internally with full precision.
17
+ *
18
+ * The viewer→ECEF transform is composed of:
19
+ * 1. Translate by (-modelCenter) to center on model origin
20
+ * 2. Rotate via viewerYup→ifcZup axis swap
21
+ * 3. Rotate via Helmert (IFC→projected CRS alignment)
22
+ * 4. Transform ENU→ECEF via Cesium.Transforms.eastNorthUpToFixedFrame()
23
+ *
24
+ * Since this is a SINGLE matrix, it's applied atomically by Cesium — no
25
+ * intermediate rounding or re-orthonormalization. The model stays pinned.
26
+ */
27
+
28
+ import proj4 from 'proj4';
29
+ import type { MapConversion, ProjectedCRS } from '@ifc-lite/parser';
30
+ import type { CoordinateInfo } from '@ifc-lite/geometry';
31
+ import { resolveProjection } from './reproject';
32
+
33
+ export interface GeodesicPosition {
34
+ longitude: number;
35
+ latitude: number;
36
+ height: number;
37
+ }
38
+
39
+ export interface CesiumBridge {
40
+ modelOrigin: GeodesicPosition;
41
+ rotationAngle: number;
42
+
43
+ /**
44
+ * Sync the Cesium camera using lookAtTransform with a viewer→ECEF matrix.
45
+ * The IFC camera position/direction/up are passed in viewer coordinates —
46
+ * Cesium transforms them to ECEF internally using one consistent matrix.
47
+ */
48
+ syncCamera(
49
+ Cesium: typeof import('cesium'),
50
+ viewer: InstanceType<typeof import('cesium').Viewer>,
51
+ camPos: { x: number; y: number; z: number },
52
+ camTarget: { x: number; y: number; z: number },
53
+ camUp: { x: number; y: number; z: number },
54
+ fov: number,
55
+ terrainClampOffset?: number,
56
+ ): void;
57
+
58
+ /** Query terrain height at model origin. */
59
+ queryTerrainHeight(
60
+ Cesium: typeof import('cesium'),
61
+ viewer: InstanceType<typeof import('cesium').Viewer>,
62
+ ): Promise<number | null>;
63
+
64
+ viewerToGeodetic(vx: number, vy: number, vz: number): GeodesicPosition | null;
65
+ }
66
+
67
+ const TERRAIN_QUERY_RETRY_DELAY_MS = 3000;
68
+
69
+ export async function createCesiumBridge(
70
+ mapConversion: MapConversion,
71
+ projectedCRS: ProjectedCRS,
72
+ coordinateInfo?: CoordinateInfo,
73
+ ): Promise<CesiumBridge | null> {
74
+ const projDef = await resolveProjection(projectedCRS);
75
+ if (!projDef) return null;
76
+
77
+ const hScale = mapConversion.scale ?? 1.0;
78
+ const absc = mapConversion.xAxisAbscissa ?? 1.0;
79
+ const ordi = mapConversion.xAxisOrdinate ?? 0.0;
80
+ const rotAngle = Math.atan2(ordi, absc);
81
+
82
+ const shift = coordinateInfo?.originShift ?? { x: 0, y: 0, z: 0 };
83
+ const rtc = coordinateInfo?.wasmRtcOffset;
84
+ const rtcYup = rtc
85
+ ? { x: rtc.x, y: rtc.z, z: -rtc.y }
86
+ : { x: 0, y: 0, z: 0 };
87
+
88
+ const bounds = coordinateInfo?.originalBounds;
89
+ const modelVX = bounds ? (bounds.min.x + bounds.max.x) / 2 : 0;
90
+ const modelVY = bounds ? (bounds.min.y + bounds.max.y) / 2 : 0;
91
+ const modelVZ = bounds ? (bounds.min.z + bounds.max.z) / 2 : 0;
92
+
93
+ // ── Compute model origin in WGS84 ──
94
+ const owx = modelVX + shift.x + rtcYup.x;
95
+ const owy = modelVY + shift.y + rtcYup.y;
96
+ const owz = modelVZ + shift.z + rtcYup.z;
97
+ // Viewer Y-up → IFC Z-up
98
+ const oIfcX = owx;
99
+ const oIfcY = -owz;
100
+ const oIfcZ = owy;
101
+ const oEasting = mapConversion.eastings + hScale * (absc * oIfcX - ordi * oIfcY);
102
+ const oNorthing = mapConversion.northings + hScale * (ordi * oIfcX + absc * oIfcY);
103
+ const oHeight = mapConversion.orthogonalHeight + oIfcZ;
104
+
105
+ let originLon: number, originLat: number;
106
+ try {
107
+ const [lon, lat] = proj4(projDef, 'WGS84', [oEasting, oNorthing]);
108
+ if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;
109
+ originLon = lon;
110
+ originLat = lat;
111
+ } catch {
112
+ return null;
113
+ }
114
+
115
+ const modelOrigin: GeodesicPosition = {
116
+ longitude: originLon,
117
+ latitude: originLat,
118
+ height: oHeight,
119
+ };
120
+
121
+ // ── Build the viewer→ENU 3x3 rotation matrix ──
122
+ // This converts a DELTA vector from viewer space to ENU.
123
+ // Step 1: viewer Y-up → IFC Z-up: (vx, vy, vz) → (vx, -vz, vy)
124
+ // Step 2: Helmert rotation: (ifcX, ifcY) → (east, north) with scale
125
+ //
126
+ // Combined as a 3x3 matrix M where [east, north, up] = M * [vx, vy, vz]:
127
+ // east = hScale * (absc * vx - ordi * (-vz)) = hScale * (absc*vx + ordi*vz)
128
+ // north = hScale * (ordi * vx + absc * (-vz)) = hScale * (ordi*vx - absc*vz)
129
+ // up = vy (ifcZ = vy, vertical is viewer Y)
130
+ //
131
+ // So M = [hScale*absc, 0, hScale*ordi ]
132
+ // [hScale*ordi, 0, -hScale*absc ]
133
+ // [0, 1, 0 ]
134
+ const m00 = hScale * absc; // east from vx
135
+ const m01 = 0; // east from vy
136
+ const m02 = hScale * ordi; // east from vz
137
+ const m10 = hScale * ordi; // north from vx
138
+ const m11 = 0; // north from vy
139
+ const m12 = -hScale * absc; // north from vz
140
+ const m20 = 0; // up from vx
141
+ const m21 = 1; // up from vy
142
+ const m22 = 0; // up from vz
143
+
144
+ // ── Cache for ECEF objects ──
145
+ let viewerToEcefMatrix: InstanceType<typeof import('cesium').Matrix4> | null = null;
146
+ let modelOriginCartesian: InstanceType<typeof import('cesium').Cartesian3> | null = null;
147
+ let cachedClampUp: number | null = null;
148
+
149
+ function ensureEcefCache(Cesium: typeof import('cesium'), clampUp: number) {
150
+ if (cachedClampUp === clampUp && viewerToEcefMatrix !== null) return;
151
+ cachedClampUp = clampUp;
152
+
153
+ const originWithClamp = Cesium.Cartesian3.fromDegrees(
154
+ originLon, originLat, oHeight + clampUp,
155
+ );
156
+ modelOriginCartesian = originWithClamp;
157
+
158
+ // Get ENU→ECEF 4x4 matrix at model origin
159
+ const enuToEcef = Cesium.Transforms.eastNorthUpToFixedFrame(originWithClamp);
160
+
161
+ // Build viewer→ECEF = enuToEcef * viewerToENU
162
+ // viewerToENU is: translate(-modelCenter) then rotate by M
163
+ // As a 4x4: columns are the ENU directions of viewer axes, translation is -modelCenter in ENU
164
+ //
165
+ // viewerToENU_4x4 = [ m00 m01 m02 tx ]
166
+ // [ m10 m11 m12 ty ]
167
+ // [ m20 m21 m22 tz ]
168
+ // [ 0 0 0 1 ]
169
+ // where (tx, ty, tz) = M * (-modelVX, -modelVY, -modelVZ)
170
+ const tx = m00 * (-modelVX) + m01 * (-modelVY) + m02 * (-modelVZ);
171
+ const ty = m10 * (-modelVX) + m11 * (-modelVY) + m12 * (-modelVZ);
172
+ const tz = m20 * (-modelVX) + m21 * (-modelVY) + m22 * (-modelVZ);
173
+
174
+ // Cesium Matrix4 is column-major
175
+ const viewerToEnu = new Cesium.Matrix4(
176
+ m00, m01, m02, tx,
177
+ m10, m11, m12, ty,
178
+ m20, m21, m22, tz,
179
+ 0, 0, 0, 1,
180
+ );
181
+
182
+ // Compose: viewerToEcef = enuToEcef * viewerToEnu
183
+ viewerToEcefMatrix = Cesium.Matrix4.multiply(
184
+ enuToEcef, viewerToEnu, new Cesium.Matrix4(),
185
+ );
186
+ }
187
+
188
+ function syncCamera(
189
+ Cesium: typeof import('cesium'),
190
+ viewer: InstanceType<typeof import('cesium').Viewer>,
191
+ camPos: { x: number; y: number; z: number },
192
+ camTarget: { x: number; y: number; z: number },
193
+ camUp: { x: number; y: number; z: number },
194
+ fov: number,
195
+ terrainClampOffset?: number,
196
+ ): void {
197
+ const clampUp = terrainClampOffset ?? 0;
198
+ ensureEcefCache(Cesium, clampUp);
199
+ if (!viewerToEcefMatrix) return;
200
+
201
+ // Set the camera's reference frame to our viewer→ECEF transform.
202
+ // After this call, all camera properties (position, direction, up)
203
+ // are interpreted in IFC VIEWER coordinates, not ECEF.
204
+ viewer.camera.lookAtTransform(viewerToEcefMatrix);
205
+
206
+ // Now set camera in VIEWER coordinates — Cesium applies the transform
207
+ viewer.camera.position = new Cesium.Cartesian3(camPos.x, camPos.y, camPos.z);
208
+
209
+ const dirX = camTarget.x - camPos.x;
210
+ const dirY = camTarget.y - camPos.y;
211
+ const dirZ = camTarget.z - camPos.z;
212
+ const dirLen = Math.sqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
213
+ if (dirLen > 1e-8) {
214
+ viewer.camera.direction = new Cesium.Cartesian3(
215
+ dirX / dirLen, dirY / dirLen, dirZ / dirLen,
216
+ );
217
+ }
218
+
219
+ viewer.camera.up = new Cesium.Cartesian3(camUp.x, camUp.y, camUp.z);
220
+
221
+ // Recompute right = direction × up (maintain orthonormality)
222
+ const right = Cesium.Cartesian3.cross(
223
+ viewer.camera.direction, viewer.camera.up, new Cesium.Cartesian3(),
224
+ );
225
+ Cesium.Cartesian3.normalize(right, right);
226
+ viewer.camera.right = right;
227
+
228
+ // Sync FOV — CRITICAL for preventing model drift.
229
+ // IFC renderer uses `fov` as VERTICAL FOV always.
230
+ // Cesium's PerspectiveFrustum.fov is HORIZONTAL when aspect > 1 (landscape).
231
+ // If we set Cesium's fov = IFC's vertical fov, Cesium treats it as horizontal,
232
+ // producing a completely different projection — the model slides during orbit.
233
+ // Fix: convert vertical FOV → horizontal FOV.
234
+ const frustum = viewer.camera.frustum;
235
+ if (frustum instanceof Cesium.PerspectiveFrustum) {
236
+ const aspect = frustum.aspectRatio || (viewer.canvas.width / viewer.canvas.height);
237
+ if (aspect > 1) {
238
+ // Landscape: Cesium expects horizontal FOV
239
+ // horizontal_fov = 2 * atan(aspect * tan(vertical_fov / 2))
240
+ frustum.fov = 2 * Math.atan(aspect * Math.tan(fov / 2));
241
+ } else {
242
+ // Portrait: Cesium uses fov as vertical — pass through
243
+ frustum.fov = fov;
244
+ }
245
+ }
246
+
247
+ viewer.scene.requestRender();
248
+ }
249
+
250
+ async function queryTerrainHeight(
251
+ Cesium: typeof import('cesium'),
252
+ viewer: InstanceType<typeof import('cesium').Viewer>,
253
+ ): Promise<number | null> {
254
+ const position = Cesium.Cartographic.fromDegrees(originLon, originLat);
255
+
256
+ try {
257
+ const globeHeight = viewer.scene.globe.getHeight(position);
258
+ if (globeHeight !== undefined && Number.isFinite(globeHeight)) {
259
+ return globeHeight;
260
+ }
261
+ } catch { /* not available yet */ }
262
+
263
+ try {
264
+ const terrainProvider = viewer.terrainProvider;
265
+ if (terrainProvider) {
266
+ const results = await Cesium.sampleTerrainMostDetailed(terrainProvider, [position]);
267
+ if (results && results.length > 0 && Number.isFinite(results[0].height)) {
268
+ return results[0].height;
269
+ }
270
+ }
271
+ } catch { /* terrain sampling failed */ }
272
+
273
+ await new Promise(r => setTimeout(r, TERRAIN_QUERY_RETRY_DELAY_MS));
274
+ try {
275
+ const globeHeight = viewer.scene.globe.getHeight(position);
276
+ if (globeHeight !== undefined && Number.isFinite(globeHeight)) {
277
+ return globeHeight;
278
+ }
279
+ } catch { /* still not available */ }
280
+
281
+ return null;
282
+ }
283
+
284
+ function viewerToGeodetic(vx: number, vy: number, vz: number): GeodesicPosition | null {
285
+ const wx = vx + shift.x + rtcYup.x;
286
+ const wy = vy + shift.y + rtcYup.y;
287
+ const wz = vz + shift.z + rtcYup.z;
288
+ const ifcX = wx;
289
+ const ifcY = -wz;
290
+ const ifcZ = wy;
291
+ const easting = mapConversion.eastings + hScale * (absc * ifcX - ordi * ifcY);
292
+ const northing = mapConversion.northings + hScale * (ordi * ifcX + absc * ifcY);
293
+ const height = mapConversion.orthogonalHeight + ifcZ;
294
+ try {
295
+ const [lon, lat] = proj4(projDef!, 'WGS84', [easting, northing]);
296
+ if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;
297
+ return { longitude: lon, latitude: lat, height };
298
+ } catch {
299
+ return null;
300
+ }
301
+ }
302
+
303
+ return {
304
+ modelOrigin,
305
+ rotationAngle: rotAngle,
306
+ syncCamera,
307
+ queryTerrainHeight,
308
+ viewerToGeodetic,
309
+ };
310
+ }
@@ -0,0 +1,112 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+
5
+ /**
6
+ * KMZ Exporter — packages a GLB model with a KML file into a KMZ archive
7
+ * so Google Earth can display the 3D model at its correct geolocation.
8
+ *
9
+ * KMZ is just a ZIP archive containing:
10
+ * doc.kml — KML document with a <Model> positioned at lat/lon/alt
11
+ * model.glb — the 3D model in glTF binary format
12
+ *
13
+ * The KML <Model> element uses:
14
+ * <Location> — latitude, longitude, altitude from reprojected georef
15
+ * <Orientation> — heading derived from the angle-to-grid-north
16
+ * <Scale> — uniform scale (1:1)
17
+ * <Link> — relative path to the GLB inside the archive
18
+ */
19
+
20
+ import { zipSync } from 'fflate';
21
+ import type { LatLon } from './reproject';
22
+
23
+ export interface KmzOptions {
24
+ /** WGS84 coordinates of the model origin */
25
+ latLon: LatLon;
26
+ /** Orthogonal height (elevation) in metres */
27
+ altitude: number;
28
+ /** Heading in degrees clockwise from north (0 = north, 90 = east) */
29
+ heading: number;
30
+ /** GLB model binary data */
31
+ glb: Uint8Array;
32
+ /** Display name for the placemark */
33
+ name?: string;
34
+ }
35
+
36
+ /**
37
+ * Convert the IFC angle-to-grid-north (counterclockwise from east) into
38
+ * a KML heading (clockwise from north).
39
+ *
40
+ * IFC convention: atan2(XAxisOrdinate, XAxisAbscissa) gives the CCW angle
41
+ * from the map east axis to the local X axis.
42
+ *
43
+ * KML convention: heading is CW from north (0=N, 90=E, 180=S, 270=W).
44
+ */
45
+ export function ifcAngleToKmlHeading(
46
+ xAxisAbscissa?: number,
47
+ xAxisOrdinate?: number,
48
+ ): number {
49
+ if (xAxisAbscissa === undefined || xAxisOrdinate === undefined) return 0;
50
+ const angleFromEastCcw = Math.atan2(xAxisOrdinate, xAxisAbscissa) * (180 / Math.PI);
51
+ // Convert: heading = 90 - angle (CCW from east → CW from north)
52
+ const heading = 90 - angleFromEastCcw;
53
+ // Normalize to [0, 360)
54
+ return ((heading % 360) + 360) % 360;
55
+ }
56
+
57
+ function buildKml(opts: KmzOptions): string {
58
+ const name = escapeXml(opts.name ?? 'IFC Model');
59
+ return `<?xml version="1.0" encoding="UTF-8"?>
60
+ <kml xmlns="http://www.opengis.net/kml/2.2">
61
+ <Document>
62
+ <name>${name}</name>
63
+ <Placemark>
64
+ <name>${name}</name>
65
+ <Model id="model">
66
+ <altitudeMode>relativeToGround</altitudeMode>
67
+ <Location>
68
+ <longitude>${opts.latLon.lon}</longitude>
69
+ <latitude>${opts.latLon.lat}</latitude>
70
+ <altitude>${opts.altitude}</altitude>
71
+ </Location>
72
+ <Orientation>
73
+ <heading>${opts.heading}</heading>
74
+ <tilt>0</tilt>
75
+ <roll>0</roll>
76
+ </Orientation>
77
+ <Scale>
78
+ <x>1</x>
79
+ <y>1</y>
80
+ <z>1</z>
81
+ </Scale>
82
+ <Link>
83
+ <href>model.glb</href>
84
+ </Link>
85
+ </Model>
86
+ </Placemark>
87
+ </Document>
88
+ </kml>`;
89
+ }
90
+
91
+ function escapeXml(s: string): string {
92
+ return s
93
+ .replace(/&/g, '&amp;')
94
+ .replace(/</g, '&lt;')
95
+ .replace(/>/g, '&gt;')
96
+ .replace(/"/g, '&quot;')
97
+ .replace(/'/g, '&apos;');
98
+ }
99
+
100
+ /**
101
+ * Build a KMZ file (ZIP archive) containing doc.kml + model.glb.
102
+ * Returns the KMZ as a Uint8Array ready for download.
103
+ */
104
+ export function buildKmz(opts: KmzOptions): Uint8Array {
105
+ const kml = buildKml(opts);
106
+ const kmlBytes = new TextEncoder().encode(kml);
107
+
108
+ return zipSync({
109
+ 'doc.kml': kmlBytes,
110
+ 'model.glb': opts.glb,
111
+ });
112
+ }