@holoscript/core 7.0.0 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (345) hide show
  1. package/README.md +2 -2
  2. package/bin/holoscript.cjs +3 -0
  3. package/dist/GLTFPipeline-276GE64O.js +16 -0
  4. package/dist/GLTFPipeline-M7WSSJED.cjs +37 -0
  5. package/dist/HoloScriptPlusParser-7FBIFUFC.js +693 -0
  6. package/dist/HoloScriptPlusParser-A2W7OCN2.cjs +698 -0
  7. package/dist/HoloScriptPlusParser-F2Z56FJR.js +10 -0
  8. package/dist/HoloScriptPlusParser-WKHRIH6T.cjs +27 -0
  9. package/dist/HoloScriptRuntime-3URVTKPJ.js +10 -0
  10. package/dist/HoloScriptRuntime-SXEAEU2N.cjs +19 -0
  11. package/dist/USDZExporter-3FWJ25JI.cjs +1037 -0
  12. package/dist/USDZExporter-D2HQLQYK.js +1035 -0
  13. package/dist/agents/index.cjs +19 -0
  14. package/dist/agents/index.d.ts +100 -0
  15. package/dist/agents/index.js +17 -0
  16. package/dist/chunk-23J755AR.js +1046 -0
  17. package/dist/chunk-253GBQZY.cjs +627 -0
  18. package/dist/chunk-25IQCHTO.cjs +781 -0
  19. package/dist/chunk-2BSMSUCE.js +1941 -0
  20. package/dist/chunk-2M2DPHKB.js +762 -0
  21. package/dist/chunk-2YSNA2F2.cjs +1274 -0
  22. package/dist/chunk-3AO425MZ.cjs +886 -0
  23. package/dist/chunk-3FOKASKO.cjs +348 -0
  24. package/dist/chunk-3HYYMEXI.cjs +56578 -0
  25. package/dist/chunk-3NFFOWGG.js +4287 -0
  26. package/dist/chunk-3WZEJHUQ.cjs +116 -0
  27. package/dist/chunk-4C57PR42.js +468 -0
  28. package/dist/chunk-4N4SXXWF.js +769 -0
  29. package/dist/chunk-4PDEPEQW.cjs +41 -0
  30. package/dist/chunk-4R6SBXDB.js +45 -0
  31. package/dist/chunk-4V2E7U7Q.cjs +2015 -0
  32. package/dist/chunk-5FSKKMR7.cjs +2092 -0
  33. package/dist/chunk-5GLCTO44.js +161 -0
  34. package/dist/chunk-5JEU52DW.js +382 -0
  35. package/dist/chunk-5S7RKFGR.cjs +446 -0
  36. package/dist/chunk-5WUNN6ZN.cjs +428 -0
  37. package/dist/chunk-62FBK3B7.js +70 -0
  38. package/dist/chunk-6CTRH7HT.cjs +1985 -0
  39. package/dist/chunk-6DPSFNJB.cjs +847 -0
  40. package/dist/chunk-6EX3I5P4.cjs +130 -0
  41. package/dist/chunk-73FELZVJ.cjs +611 -0
  42. package/dist/chunk-7CUEMLDZ.cjs +6445 -0
  43. package/dist/chunk-7HIASF7S.cjs +814 -0
  44. package/dist/chunk-A6KINLZJ.js +236 -0
  45. package/dist/chunk-AIA52I7T.cjs +543 -0
  46. package/dist/chunk-ANXZFVY2.js +113 -0
  47. package/dist/chunk-AYBXB26F.js +2176 -0
  48. package/dist/chunk-B4TFTDG4.js +449 -0
  49. package/dist/chunk-BE4UJCQT.js +623 -0
  50. package/dist/chunk-BRQJKJGT.cjs +20 -0
  51. package/dist/chunk-C2A5DUMF.cjs +689 -0
  52. package/dist/chunk-C37BHB7N.cjs +636 -0
  53. package/dist/chunk-CBJY23VL.js +126 -0
  54. package/dist/chunk-CIWWXYHZ.cjs +50 -0
  55. package/dist/chunk-CXFDRBQU.cjs +672 -0
  56. package/dist/chunk-D54CNIAJ.cjs +413 -0
  57. package/dist/chunk-DAJXW4KX.js +725 -0
  58. package/dist/chunk-DTGBOSEM.cjs +319 -0
  59. package/dist/chunk-E7JP3BS3.cjs +61 -0
  60. package/dist/chunk-EKBKLK7P.js +1169 -0
  61. package/dist/chunk-EKYL4PE3.cjs +404 -0
  62. package/dist/chunk-EUDQTK7N.cjs +4310 -0
  63. package/dist/chunk-EXKSFGSX.cjs +274 -0
  64. package/dist/chunk-EXUP2BUM.cjs +1173 -0
  65. package/dist/chunk-F43YAA34.js +623 -0
  66. package/dist/chunk-FDSGHPAK.js +130 -0
  67. package/dist/chunk-FEWUHQNM.cjs +144 -0
  68. package/dist/chunk-FGGJQRLZ.js +270 -0
  69. package/dist/chunk-FHP6LXJS.js +415 -0
  70. package/dist/chunk-FJPADH77.cjs +666 -0
  71. package/dist/chunk-FYSPZT4V.cjs +169 -0
  72. package/dist/chunk-GIOYPNTH.js +5575 -0
  73. package/dist/chunk-GJNCFRJU.cjs +125 -0
  74. package/dist/chunk-GMP623FG.cjs +1508 -0
  75. package/dist/chunk-GQHQOPXZ.cjs +5580 -0
  76. package/dist/chunk-GQT4TYKY.cjs +4381 -0
  77. package/dist/chunk-GTU2Z2WW.cjs +262 -0
  78. package/dist/chunk-GYZE55MO.js +2007 -0
  79. package/dist/chunk-GZG4KA4E.js +529 -0
  80. package/dist/chunk-H652NHX5.js +600 -0
  81. package/dist/chunk-HCCQLAA4.cjs +74 -0
  82. package/dist/chunk-HINXWAOD.cjs +1049 -0
  83. package/dist/chunk-HYNTS5CP.js +422 -0
  84. package/dist/chunk-HZSPDCXV.cjs +457 -0
  85. package/dist/chunk-HZTDET3N.js +1399 -0
  86. package/dist/chunk-I6XZ5DZF.cjs +488 -0
  87. package/dist/chunk-ILRBGFVD.cjs +72 -0
  88. package/dist/chunk-IPWSXCCN.js +1183 -0
  89. package/dist/chunk-IUTY5WQ2.cjs +424 -0
  90. package/dist/chunk-IVSZDECV.js +882 -0
  91. package/dist/chunk-IVY74O6C.js +247 -0
  92. package/dist/chunk-IZM5VQZD.js +714 -0
  93. package/dist/chunk-J32ZJZJH.js +554 -0
  94. package/dist/chunk-J6M4FPK5.js +421 -0
  95. package/dist/chunk-JC5YBPSF.cjs +984 -0
  96. package/dist/chunk-JCLBKPMX.js +3813 -0
  97. package/dist/chunk-JD7CIZ33.js +1949 -0
  98. package/dist/chunk-JIYN45TV.cjs +2525 -0
  99. package/dist/chunk-JJBE3TIH.cjs +1189 -0
  100. package/dist/chunk-JX7YL6ZE.js +2252 -0
  101. package/dist/chunk-K4VVR7CN.cjs +2433 -0
  102. package/dist/chunk-KEFNV2WM.cjs +2257 -0
  103. package/dist/chunk-KH4CNH66.cjs +424 -0
  104. package/dist/chunk-KJLB4OPV.js +5731 -0
  105. package/dist/chunk-KKFZ3B6J.cjs +557 -0
  106. package/dist/chunk-KKP7JKN4.cjs +6002 -0
  107. package/dist/chunk-KPJL34Y7.cjs +186 -0
  108. package/dist/chunk-KQCN6AKJ.cjs +3042 -0
  109. package/dist/chunk-KVRSTFNH.cjs +72 -0
  110. package/dist/chunk-LICPB5HZ.cjs +1409 -0
  111. package/dist/chunk-LM2VU56C.cjs +37 -0
  112. package/dist/chunk-M56JSP4A.js +400 -0
  113. package/dist/chunk-MBOOR7X4.js +18 -0
  114. package/dist/chunk-MGE5Z4GS.js +608 -0
  115. package/dist/chunk-MXFUTKCO.js +56 -0
  116. package/dist/chunk-MYY4PMWX.cjs +264 -0
  117. package/dist/chunk-N75IH2HY.js +258 -0
  118. package/dist/chunk-NBMHU6SW.js +669 -0
  119. package/dist/chunk-NG77ATEW.cjs +778 -0
  120. package/dist/chunk-NGKREZ36.js +6384 -0
  121. package/dist/chunk-NHWSN2SD.cjs +718 -0
  122. package/dist/chunk-NV4VMVXU.js +421 -0
  123. package/dist/chunk-NW5G5FBQ.js +215 -0
  124. package/dist/chunk-NXZFOPVD.cjs +5737 -0
  125. package/dist/chunk-OBIYPYYS.cjs +1993 -0
  126. package/dist/chunk-OIQYIIO3.cjs +473 -0
  127. package/dist/chunk-OL46QLBJ.js +61 -0
  128. package/dist/chunk-OMXII44L.js +5386 -0
  129. package/dist/chunk-OR4Q2BGL.cjs +759 -0
  130. package/dist/chunk-OSYNRVOV.cjs +243 -0
  131. package/dist/chunk-PGANYCAG.cjs +220 -0
  132. package/dist/chunk-PHENW4MQ.js +65 -0
  133. package/dist/chunk-PHVRG4I2.js +844 -0
  134. package/dist/chunk-Q56TT7IL.js +483 -0
  135. package/dist/chunk-QPOQ7VPI.js +1491 -0
  136. package/dist/chunk-QPSKHBJP.js +5963 -0
  137. package/dist/chunk-QXH7QDSZ.js +1989 -0
  138. package/dist/chunk-R75BSDH7.cjs +50 -0
  139. package/dist/chunk-RARB3MBR.js +207 -0
  140. package/dist/chunk-RVBHAXFG.js +56160 -0
  141. package/dist/chunk-S3MDHNKB.cjs +490 -0
  142. package/dist/chunk-S4W6Z2MN.js +2426 -0
  143. package/dist/chunk-S6YWHCKV.cjs +410 -0
  144. package/dist/chunk-SIEXCILW.js +229 -0
  145. package/dist/chunk-SJBGLS25.cjs +2196 -0
  146. package/dist/chunk-SLU6UPJI.cjs +410 -0
  147. package/dist/chunk-SMIWS6DE.cjs +212 -0
  148. package/dist/chunk-T2QCTZMO.js +811 -0
  149. package/dist/chunk-T5J7ZKP3.cjs +4885 -0
  150. package/dist/chunk-TDCNJHWO.js +341 -0
  151. package/dist/chunk-TG7O4WBC.js +406 -0
  152. package/dist/chunk-THCK6ECW.js +2085 -0
  153. package/dist/chunk-TJHVSBP2.js +439 -0
  154. package/dist/chunk-TVHSPJ4N.cjs +606 -0
  155. package/dist/chunk-U44IKGG7.cjs +5390 -0
  156. package/dist/chunk-UJXISJBN.js +487 -0
  157. package/dist/chunk-UM6C3CGK.js +4375 -0
  158. package/dist/chunk-UMABK6SI.js +686 -0
  159. package/dist/chunk-UOIGFQXC.cjs +9750 -0
  160. package/dist/chunk-URG2SJLK.js +2521 -0
  161. package/dist/chunk-V6MKC2FZ.js +979 -0
  162. package/dist/chunk-VECQYRXL.js +474 -0
  163. package/dist/chunk-VJ3L7CHT.cjs +169 -0
  164. package/dist/chunk-VMLKSV26.js +1216 -0
  165. package/dist/chunk-VVKVQZI6.js +55 -0
  166. package/dist/chunk-W6RW64BB.cjs +1219 -0
  167. package/dist/chunk-W7VDOASB.cjs +639 -0
  168. package/dist/chunk-WDT3JTGM.cjs +483 -0
  169. package/dist/chunk-WJIHFLMJ.js +404 -0
  170. package/dist/chunk-WKX5AMOY.js +309 -0
  171. package/dist/chunk-WNNE3PO3.js +34 -0
  172. package/dist/chunk-WRKUDAZJ.js +3038 -0
  173. package/dist/chunk-WRLUBRKS.cjs +1943 -0
  174. package/dist/chunk-WRNEH5MO.js +3169 -0
  175. package/dist/chunk-WRWEX5ZF.js +658 -0
  176. package/dist/chunk-X3GJPRVK.cjs +3246 -0
  177. package/dist/chunk-XHIV6326.cjs +793 -0
  178. package/dist/chunk-XIVIE43A.cjs +729 -0
  179. package/dist/chunk-XJAN7CZG.cjs +432 -0
  180. package/dist/chunk-XKTPFXGA.js +164 -0
  181. package/dist/chunk-XL6INWKT.js +121 -0
  182. package/dist/chunk-XSFNHP2E.js +632 -0
  183. package/dist/chunk-XT6JY5W5.js +9684 -0
  184. package/dist/chunk-XUILI4KB.cjs +430 -0
  185. package/dist/chunk-XUUVDHIF.cjs +3962 -0
  186. package/dist/chunk-YF2I3MV3.js +46 -0
  187. package/dist/chunk-YIMN575O.js +4847 -0
  188. package/dist/chunk-YIVFJNYV.js +176 -0
  189. package/dist/chunk-YKGPCZEE.cjs +237 -0
  190. package/dist/chunk-YN6V7R3L.cjs +327 -0
  191. package/dist/chunk-YQELFNJV.js +39 -0
  192. package/dist/chunk-YYXH45E2.js +426 -0
  193. package/dist/chunk-ZBQXLH2L.js +756 -0
  194. package/dist/chunk-ZDSYWBIE.cjs +69 -0
  195. package/dist/chunk-ZU7NIRT6.js +325 -0
  196. package/dist/chunk-ZZ7RO2UQ.js +1243 -0
  197. package/dist/chunk-ZZEI7MV4.js +778 -0
  198. package/dist/cli/holoscript-runner.cjs +2255 -0
  199. package/dist/cli/holoscript-runner.js +2230 -0
  200. package/dist/codebase/index.cjs +336 -0
  201. package/dist/codebase/index.js +331 -0
  202. package/dist/compiler/agent-inference.cjs +31 -0
  203. package/dist/compiler/agent-inference.js +8 -0
  204. package/dist/compiler/android-xr.cjs +24 -0
  205. package/dist/compiler/android-xr.js +14 -0
  206. package/dist/compiler/android.cjs +24 -0
  207. package/dist/compiler/android.js +14 -0
  208. package/dist/compiler/ar.cjs +23 -0
  209. package/dist/compiler/ar.js +11 -0
  210. package/dist/compiler/babylon.cjs +21 -0
  211. package/dist/compiler/babylon.js +15 -0
  212. package/dist/compiler/business-quest.cjs +43 -0
  213. package/dist/compiler/business-quest.js +4 -0
  214. package/dist/compiler/coco.cjs +27 -0
  215. package/dist/compiler/coco.js +4 -0
  216. package/dist/compiler/context.cjs +25 -0
  217. package/dist/compiler/context.d.ts +28 -0
  218. package/dist/compiler/context.js +8 -0
  219. package/dist/compiler/domain-block-utils.cjs +605 -0
  220. package/dist/compiler/domain-block-utils.js +11 -0
  221. package/dist/compiler/dtdl.cjs +27 -0
  222. package/dist/compiler/dtdl.js +11 -0
  223. package/dist/compiler/gltf-pipeline.cjs +39 -0
  224. package/dist/compiler/gltf-pipeline.js +4 -0
  225. package/dist/compiler/godot.cjs +18 -0
  226. package/dist/compiler/godot.js +12 -0
  227. package/dist/compiler/incremental.cjs +34 -0
  228. package/dist/compiler/incremental.js +9 -0
  229. package/dist/compiler/index.cjs +5860 -0
  230. package/dist/compiler/index.d.ts +322 -21
  231. package/dist/compiler/index.js +5525 -0
  232. package/dist/compiler/ios.cjs +23 -0
  233. package/dist/compiler/ios.js +13 -0
  234. package/dist/compiler/llm-provider-capabilities.cjs +25 -0
  235. package/dist/compiler/llm-provider-capabilities.d.ts +43 -0
  236. package/dist/compiler/llm-provider-capabilities.js +8 -0
  237. package/dist/compiler/multi-layer.cjs +24 -0
  238. package/dist/compiler/multi-layer.js +15 -0
  239. package/dist/compiler/nodetoy.cjs +23 -0
  240. package/dist/compiler/nodetoy.js +4 -0
  241. package/dist/compiler/openxr.cjs +19 -0
  242. package/dist/compiler/openxr.js +13 -0
  243. package/dist/compiler/playcanvas.cjs +19 -0
  244. package/dist/compiler/playcanvas.js +13 -0
  245. package/dist/compiler/r3f.cjs +38 -0
  246. package/dist/compiler/r3f.d.ts +22 -0
  247. package/dist/compiler/r3f.js +16 -0
  248. package/dist/compiler/remotion.cjs +23 -0
  249. package/dist/compiler/remotion.js +4 -0
  250. package/dist/compiler/reproducibility.cjs +39 -0
  251. package/dist/compiler/reproducibility.js +4 -0
  252. package/dist/compiler/sdf.cjs +24 -0
  253. package/dist/compiler/sdf.js +12 -0
  254. package/dist/compiler/semantic-scene.cjs +31 -0
  255. package/dist/compiler/semantic-scene.js +4 -0
  256. package/dist/compiler/state.cjs +21 -0
  257. package/dist/compiler/state.js +11 -0
  258. package/dist/compiler/trait-composition.cjs +30 -0
  259. package/dist/compiler/trait-composition.js +9 -0
  260. package/dist/compiler/unity.cjs +19 -0
  261. package/dist/compiler/unity.js +13 -0
  262. package/dist/compiler/unreal.cjs +23 -0
  263. package/dist/compiler/unreal.js +13 -0
  264. package/dist/compiler/urdf.cjs +52 -0
  265. package/dist/compiler/urdf.js +12 -0
  266. package/dist/compiler/usd-physics.cjs +26 -0
  267. package/dist/compiler/usd-physics.js +9 -0
  268. package/dist/compiler/visionos.cjs +19 -0
  269. package/dist/compiler/visionos.js +13 -0
  270. package/dist/compiler/vrchat.cjs +22 -0
  271. package/dist/compiler/vrchat.js +12 -0
  272. package/dist/compiler/vrr.cjs +24 -0
  273. package/dist/compiler/vrr.js +12 -0
  274. package/dist/compiler/wasm.cjs +36 -0
  275. package/dist/compiler/wasm.js +12 -0
  276. package/dist/compiler/webgpu.cjs +18 -0
  277. package/dist/compiler/webgpu.js +12 -0
  278. package/dist/coordinators/index.cjs +1266 -0
  279. package/dist/coordinators/index.d.ts +72 -1
  280. package/dist/coordinators/index.js +1259 -0
  281. package/dist/debugger.cjs +24 -0
  282. package/dist/debugger.js +11 -0
  283. package/dist/entries/interop.cjs +64 -0
  284. package/dist/entries/interop.js +7 -0
  285. package/dist/entries/scripting.cjs +55 -0
  286. package/dist/entries/scripting.js +10 -0
  287. package/dist/hololand/index.cjs +146 -0
  288. package/dist/hololand/index.d.ts +70 -0
  289. package/dist/hololand/index.js +5 -0
  290. package/dist/index.cjs +43233 -0
  291. package/dist/index.d.ts +976 -21
  292. package/dist/index.js +39995 -0
  293. package/dist/math/tropical-spmv.cjs +45 -0
  294. package/dist/math/tropical-spmv.js +4 -0
  295. package/dist/math/vec3.cjs +57 -0
  296. package/dist/math/vec3.js +4 -0
  297. package/dist/ml-dsa-FSKBTE3W.cjs +1265 -0
  298. package/dist/ml-dsa-Z7JDKW4L.js +1265 -0
  299. package/dist/paper-0c-spike/index.cjs +150 -0
  300. package/dist/paper-0c-spike/index.js +141 -0
  301. package/dist/parser.cjs +61 -0
  302. package/dist/parser.d.ts +11 -0
  303. package/dist/parser.js +12 -0
  304. package/dist/playwright-3AT3AKTV.cjs +98673 -0
  305. package/dist/playwright-VZPDVUEQ.js +98660 -0
  306. package/dist/reconstruction/index.cjs +153 -0
  307. package/dist/reconstruction/index.d.ts +29 -2
  308. package/dist/reconstruction/index.js +8 -0
  309. package/dist/runtime.cjs +316 -0
  310. package/dist/runtime.d.ts +61 -0
  311. package/dist/runtime.js +31 -0
  312. package/dist/self-improvement/index.cjs +563 -0
  313. package/dist/self-improvement/index.js +545 -0
  314. package/dist/storage/index.cjs +38 -0
  315. package/dist/storage/index.js +5 -0
  316. package/dist/testing.cjs +25 -0
  317. package/dist/testing.d.ts +70 -0
  318. package/dist/testing.js +4 -0
  319. package/dist/traitDocs/traitDocs.cjs +33 -0
  320. package/dist/traitDocs/traitDocs.js +7 -0
  321. package/dist/traits/botanical-lotus.cjs +41 -0
  322. package/dist/traits/botanical-lotus.d.ts +172 -0
  323. package/dist/traits/botanical-lotus.js +4 -0
  324. package/dist/traits/engines/index.cjs +520 -0
  325. package/dist/traits/engines/index.js +380 -0
  326. package/dist/traits/index.cjs +24409 -0
  327. package/dist/traits/index.d.ts +171 -35
  328. package/dist/traits/index.js +21634 -0
  329. package/dist/traits/simulation-solver-factory.cjs +13 -0
  330. package/dist/traits/simulation-solver-factory.d.ts +23 -0
  331. package/dist/traits/simulation-solver-factory.js +4 -0
  332. package/dist/traits/webcam-gaze.cjs +35 -0
  333. package/dist/traits/webcam-gaze.d.ts +17 -0
  334. package/dist/traits/webcam-gaze.js +4 -0
  335. package/dist/type-checker.cjs +19 -0
  336. package/dist/type-checker.js +6 -0
  337. package/dist/world/index.cjs +947 -0
  338. package/dist/world/index.d.ts +147 -0
  339. package/dist/world/index.js +939 -0
  340. package/dist/world-model/index.cjs +1446 -0
  341. package/dist/world-model/index.d.ts +119 -0
  342. package/dist/world-model/index.js +1414 -0
  343. package/dist/wot/index.cjs +29 -0
  344. package/dist/wot/index.js +4 -0
  345. package/package.json +93 -49
@@ -0,0 +1,1049 @@
1
+ 'use strict';
2
+
3
+ var chunkAIA52I7T_cjs = require('./chunk-AIA52I7T.cjs');
4
+ var chunkXUUVDHIF_cjs = require('./chunk-XUUVDHIF.cjs');
5
+ var chunkKKP7JKN4_cjs = require('./chunk-KKP7JKN4.cjs');
6
+ var chunkHCCQLAA4_cjs = require('./chunk-HCCQLAA4.cjs');
7
+ var ans = require('@holoscript/core-types/ans');
8
+
9
+ // src/compiler/OpenXRCompiler.ts
10
+ var OpenXRCompiler_exports = {};
11
+ chunkHCCQLAA4_cjs.__export(OpenXRCompiler_exports, {
12
+ OpenXRCompiler: () => exports.OpenXRCompiler
13
+ });
14
+ exports.OpenXRCompiler = void 0;
15
+ var init_OpenXRCompiler = chunkHCCQLAA4_cjs.__esm({
16
+ "src/compiler/OpenXRCompiler.ts"() {
17
+ chunkKKP7JKN4_cjs.init_CompilerBase();
18
+ chunkAIA52I7T_cjs.init_PlatformConditionalCompilerMixin();
19
+ chunkXUUVDHIF_cjs.init_DomainBlockCompilerMixin();
20
+ exports.OpenXRCompiler = class extends chunkKKP7JKN4_cjs.CompilerBase {
21
+ constructor(options = {}) {
22
+ super();
23
+ this.compilerName = "OpenXRCompiler";
24
+ this.lines = [];
25
+ this.indentLevel = 0;
26
+ this.options = {
27
+ appName: options.appName || "HoloScriptApp",
28
+ renderBackend: options.renderBackend || "vulkan",
29
+ enableHandTracking: options.enableHandTracking ?? true,
30
+ enablePassthrough: options.enablePassthrough ?? false,
31
+ indent: options.indent || " "
32
+ };
33
+ }
34
+ getRequiredCapability() {
35
+ return ans.ANSCapabilityPath.OPENXR;
36
+ }
37
+ compile(composition, agentToken, outputPath) {
38
+ this.validateCompilerAccess(agentToken, outputPath);
39
+ composition = chunkAIA52I7T_cjs.filterCompositionForPlatform(composition, "quest3");
40
+ this.lines = [];
41
+ this.indentLevel = 0;
42
+ this.emit("// Auto-generated by HoloScript OpenXRCompiler");
43
+ this.emit(
44
+ `// Source: composition "${this.escapeStringValue(composition.name, "TypeScript")}"`
45
+ );
46
+ this.emit("// Do not edit manually -- regenerate from .holo source");
47
+ this.emit("");
48
+ this.emitIncludes();
49
+ this.emit("");
50
+ this.emit(`namespace ${this.sanitizeName(composition.name)} {`);
51
+ this.emit("");
52
+ this.indent();
53
+ this.emit("struct LightUBO {");
54
+ this.indent();
55
+ this.emit("glm::vec4 position;");
56
+ this.emit("glm::vec4 color;");
57
+ this.emit("float intensity;");
58
+ this.emit("float range;");
59
+ this.emit("float padding[2];");
60
+ this.dedent();
61
+ this.emit("};");
62
+ this.emit("");
63
+ this.emit("XrInstance instance = XR_NULL_HANDLE;");
64
+ this.emit("XrSession session = XR_NULL_HANDLE;");
65
+ this.emit("XrSpace appSpace = XR_NULL_HANDLE;");
66
+ this.emit("XrSwapchain swapchain = XR_NULL_HANDLE;");
67
+ this.emit("XrActionSet actionSet = XR_NULL_HANDLE;");
68
+ this.emit("XrAction grabAction = XR_NULL_HANDLE;");
69
+ this.emit("XrAction triggerAction = XR_NULL_HANDLE;");
70
+ this.emit("XrAction aimPoseAction = XR_NULL_HANDLE;");
71
+ this.emit("XrAction hapticAction = XR_NULL_HANDLE;");
72
+ if (this.options.enableHandTracking) {
73
+ this.emit("XrHandTrackerEXT handTrackerLeft = XR_NULL_HANDLE;");
74
+ this.emit("XrHandTrackerEXT handTrackerRight = XR_NULL_HANDLE;");
75
+ }
76
+ this.emit("bool sessionRunning = false;");
77
+ this.emit("");
78
+ this.emitInstanceInit(composition);
79
+ this.emit("");
80
+ this.emitSessionInit();
81
+ this.emit("");
82
+ this.emitActionSets();
83
+ this.emit("");
84
+ if (this.options.enableHandTracking) {
85
+ this.emitHandTracking();
86
+ this.emit("");
87
+ }
88
+ this.emitRenderPass();
89
+ this.emit("");
90
+ this.emit("void setupScene() {");
91
+ this.indent();
92
+ if (composition.environment) {
93
+ this.emitEnvironment(composition.environment);
94
+ }
95
+ for (const light of composition.lights ?? []) {
96
+ this.emitLight(light);
97
+ }
98
+ for (const obj of composition.objects ?? []) {
99
+ this.emitObject(obj);
100
+ }
101
+ for (const group of composition.spatialGroups ?? []) {
102
+ this.emitGroup(group);
103
+ }
104
+ if (composition.camera) {
105
+ this.emitCamera(composition.camera);
106
+ }
107
+ this.dedent();
108
+ this.emit("}");
109
+ this.emit("");
110
+ this.emitRenderLoop(composition);
111
+ this.emit("");
112
+ this.emit("int main() {");
113
+ this.indent();
114
+ this.emit("initInstance();");
115
+ this.emit("initSession();");
116
+ this.emit("initActionSets();");
117
+ if (this.options.enableHandTracking) {
118
+ this.emit("initHandTracking();");
119
+ }
120
+ this.emit("setupScene();");
121
+ this.emit("renderLoop();");
122
+ this.emit("");
123
+ this.emit("// Cleanup");
124
+ if (this.options.enableHandTracking) {
125
+ this.emit("xrDestroyHandTrackerEXT(handTrackerLeft);");
126
+ this.emit("xrDestroyHandTrackerEXT(handTrackerRight);");
127
+ }
128
+ this.emit("xrDestroySwapchain(swapchain);");
129
+ this.emit("xrDestroySpace(appSpace);");
130
+ this.emit("xrDestroySession(session);");
131
+ this.emit("xrDestroyInstance(instance);");
132
+ this.emit("return 0;");
133
+ this.dedent();
134
+ this.emit("}");
135
+ const domainBlocks = composition.domainBlocks ?? [];
136
+ if (domainBlocks.length > 0) {
137
+ this.emit("");
138
+ this.emit("// === v4.2 Domain Blocks ===");
139
+ const compiled = chunkXUUVDHIF_cjs.compileDomainBlocks(
140
+ // @ts-expect-error During migration
141
+ domainBlocks,
142
+ {
143
+ material: (block) => {
144
+ const m = chunkXUUVDHIF_cjs.compileMaterialBlock(block);
145
+ return `// Material: "${this.escapeStringValue(m.name, "TypeScript")}" type=${m.type} baseColor=${m.baseColor || "none"} roughness=${m.roughness ?? "default"} metallic=${m.metallic ?? "default"}`;
146
+ },
147
+ physics: (block) => {
148
+ const p = chunkXUUVDHIF_cjs.compilePhysicsBlock(block);
149
+ return `// Physics: ${p.keyword} "${p.name || ""}" colliders=${p.colliders?.length || 0} rigidbody=${!!p.rigidbody}`;
150
+ },
151
+ vfx: (block) => {
152
+ const ps = chunkXUUVDHIF_cjs.compileParticleBlock(block);
153
+ return `// Particles: "${this.escapeStringValue(ps.name, "TypeScript")}" rate=${ps.properties.rate || "default"} modules=${ps.modules.length}`;
154
+ },
155
+ postfx: (block) => {
156
+ const pp = chunkXUUVDHIF_cjs.compilePostProcessingBlock(block);
157
+ return `// PostFX: ${pp.keyword} effects=[${pp.effects.map((e) => e.type).join(", ")}]`;
158
+ },
159
+ audio: (block) => {
160
+ const a = chunkXUUVDHIF_cjs.compileAudioSourceBlock(block);
161
+ return `// Audio: "${this.escapeStringValue(a.name, "TypeScript")}" (${a.keyword}) clip=${a.properties.clip || "none"}`;
162
+ },
163
+ weather: (block) => {
164
+ const w = chunkXUUVDHIF_cjs.compileWeatherBlock(block);
165
+ return `// Weather: ${w.keyword} layers=[${w.layers.map((l) => l.type).join(", ")}]`;
166
+ }
167
+ },
168
+ (block) => `// Domain block: ${block.domain}/${block.keyword} "${this.escapeStringValue(block.name, "TypeScript")}"`
169
+ );
170
+ for (const line of compiled) {
171
+ for (const l of line.split("\n")) this.emit(l);
172
+ }
173
+ }
174
+ this.dedent();
175
+ this.emit("");
176
+ this.emit(`} // namespace ${this.sanitizeName(composition.name)}`);
177
+ return this.lines.join("\n");
178
+ }
179
+ // ---------------------------------------------------------------------------
180
+ // Includes
181
+ // ---------------------------------------------------------------------------
182
+ emitIncludes() {
183
+ this.emit("#include <openxr/openxr.h>");
184
+ this.emit("#include <openxr/openxr_platform.h>");
185
+ if (this.options.enableHandTracking) {
186
+ this.emit("#include <openxr/openxr_extension.h>");
187
+ }
188
+ this.emit("");
189
+ if (this.options.renderBackend === "vulkan") {
190
+ this.emit("#include <vulkan/vulkan.h>");
191
+ } else {
192
+ this.emit("#include <GLES3/gl3.h>");
193
+ this.emit("#include <EGL/egl.h>");
194
+ }
195
+ this.emit("");
196
+ this.emit("#include <glm/glm.hpp>");
197
+ this.emit("#include <glm/gtc/matrix_transform.hpp>");
198
+ this.emit("#include <glm/gtc/type_ptr.hpp>");
199
+ this.emit("");
200
+ this.emit("#include <vector>");
201
+ this.emit("#include <array>");
202
+ this.emit("#include <string>");
203
+ this.emit("#include <cstring>");
204
+ this.emit("#include <cmath>");
205
+ this.emit("#include <iostream>");
206
+ }
207
+ // ---------------------------------------------------------------------------
208
+ // Instance initialization
209
+ // ---------------------------------------------------------------------------
210
+ emitInstanceInit(composition) {
211
+ this.emit("void initInstance() {");
212
+ this.indent();
213
+ this.emit("std::vector<const char*> extensions = {");
214
+ this.indent();
215
+ if (this.options.renderBackend === "vulkan") {
216
+ this.emit("XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME,");
217
+ } else {
218
+ this.emit("XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME,");
219
+ }
220
+ if (this.options.enableHandTracking) {
221
+ this.emit("XR_EXT_HAND_TRACKING_EXTENSION_NAME,");
222
+ }
223
+ if (this.options.enablePassthrough) {
224
+ this.emit("XR_FB_PASSTHROUGH_EXTENSION_NAME,");
225
+ }
226
+ const needsAnchor = this.compositionUsesAnchor(composition);
227
+ if (needsAnchor) {
228
+ this.emit("XR_MSFT_SPATIAL_ANCHOR_EXTENSION_NAME,");
229
+ }
230
+ this.dedent();
231
+ this.emit("};");
232
+ this.emit("");
233
+ this.emit("XrInstanceCreateInfo createInfo{XR_TYPE_INSTANCE_CREATE_INFO};");
234
+ this.emit(
235
+ `std::strncpy(createInfo.applicationInfo.applicationName, "${this.options.appName}", XR_MAX_APPLICATION_NAME_SIZE);`
236
+ );
237
+ this.emit("createInfo.applicationInfo.apiVersion = XR_CURRENT_API_VERSION;");
238
+ this.emit("createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());");
239
+ this.emit("createInfo.enabledExtensionNames = extensions.data();");
240
+ this.emit("");
241
+ this.emit("XrResult result = xrCreateInstance(&createInfo, &instance);");
242
+ this.emit("if (XR_FAILED(result)) {");
243
+ this.indent();
244
+ this.emit('std::cerr << "Failed to create XR instance" << std::endl;');
245
+ this.emit("return;");
246
+ this.dedent();
247
+ this.emit("}");
248
+ this.dedent();
249
+ this.emit("}");
250
+ }
251
+ // ---------------------------------------------------------------------------
252
+ // Session initialization
253
+ // ---------------------------------------------------------------------------
254
+ emitSessionInit() {
255
+ this.emit("void initSession() {");
256
+ this.indent();
257
+ this.emit("// Get system");
258
+ this.emit("XrSystemId systemId = XR_NULL_SYSTEM_ID;");
259
+ this.emit("XrSystemGetInfo systemInfo{XR_TYPE_SYSTEM_GET_INFO};");
260
+ this.emit("systemInfo.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;");
261
+ this.emit("xrGetSystem(instance, &systemInfo, &systemId);");
262
+ this.emit("");
263
+ if (this.options.renderBackend === "vulkan") {
264
+ this.emit("// Vulkan graphics binding");
265
+ this.emit("XrGraphicsBindingVulkanKHR graphicsBinding{XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR};");
266
+ this.emit("graphicsBinding.instance = vkInstance;");
267
+ this.emit("graphicsBinding.physicalDevice = vkPhysicalDevice;");
268
+ this.emit("graphicsBinding.device = vkDevice;");
269
+ this.emit("graphicsBinding.queueFamilyIndex = graphicsQueueFamilyIndex;");
270
+ this.emit("graphicsBinding.queueIndex = 0;");
271
+ } else {
272
+ this.emit("// OpenGL ES graphics binding");
273
+ this.emit(
274
+ "XrGraphicsBindingOpenGLESAndroidKHR graphicsBinding{XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR};"
275
+ );
276
+ this.emit("graphicsBinding.display = eglDisplay;");
277
+ this.emit("graphicsBinding.config = eglConfig;");
278
+ this.emit("graphicsBinding.context = eglContext;");
279
+ }
280
+ this.emit("");
281
+ this.emit("// Create session");
282
+ this.emit("XrSessionCreateInfo sessionCreateInfo{XR_TYPE_SESSION_CREATE_INFO};");
283
+ this.emit("sessionCreateInfo.systemId = systemId;");
284
+ this.emit("sessionCreateInfo.next = &graphicsBinding;");
285
+ this.emit("xrCreateSession(instance, &sessionCreateInfo, &session);");
286
+ this.emit("");
287
+ this.emit("// Reference space (STAGE for room-scale)");
288
+ this.emit("XrReferenceSpaceCreateInfo refSpaceInfo{XR_TYPE_REFERENCE_SPACE_CREATE_INFO};");
289
+ this.emit("refSpaceInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE;");
290
+ this.emit("refSpaceInfo.poseInReferenceSpace.orientation = {0.0f, 0.0f, 0.0f, 1.0f};");
291
+ this.emit("refSpaceInfo.poseInReferenceSpace.position = {0.0f, 0.0f, 0.0f};");
292
+ this.emit("xrCreateReferenceSpace(session, &refSpaceInfo, &appSpace);");
293
+ this.emit("");
294
+ this.emit("// Swapchain");
295
+ this.emit("XrSwapchainCreateInfo swapchainInfo{XR_TYPE_SWAPCHAIN_CREATE_INFO};");
296
+ this.emit("swapchainInfo.usageFlags = XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;");
297
+ if (this.options.renderBackend === "vulkan") {
298
+ this.emit("swapchainInfo.format = VK_FORMAT_R8G8B8A8_SRGB;");
299
+ } else {
300
+ this.emit("swapchainInfo.format = GL_SRGB8_ALPHA8;");
301
+ }
302
+ this.emit("swapchainInfo.sampleCount = 1;");
303
+ this.emit("swapchainInfo.width = 1920;");
304
+ this.emit("swapchainInfo.height = 1920;");
305
+ this.emit("swapchainInfo.faceCount = 1;");
306
+ this.emit("swapchainInfo.arraySize = 2; // stereo");
307
+ this.emit("swapchainInfo.mipCount = 1;");
308
+ this.emit("xrCreateSwapchain(session, &swapchainInfo, &swapchain);");
309
+ this.emit("");
310
+ this.emit("sessionRunning = true;");
311
+ this.dedent();
312
+ this.emit("}");
313
+ }
314
+ // ---------------------------------------------------------------------------
315
+ // Action sets (input)
316
+ // ---------------------------------------------------------------------------
317
+ emitActionSets() {
318
+ this.emit("void initActionSets() {");
319
+ this.indent();
320
+ this.emit("XrActionSetCreateInfo actionSetInfo{XR_TYPE_ACTION_SET_CREATE_INFO};");
321
+ this.emit(
322
+ 'std::strncpy(actionSetInfo.actionSetName, "gameplay", XR_MAX_ACTION_SET_NAME_SIZE);'
323
+ );
324
+ this.emit(
325
+ 'std::strncpy(actionSetInfo.localizedActionSetName, "Gameplay", XR_MAX_LOCALIZED_ACTION_SET_NAME_SIZE);'
326
+ );
327
+ this.emit("xrCreateActionSet(instance, &actionSetInfo, &actionSet);");
328
+ this.emit("");
329
+ const actions = [
330
+ { name: "grabAction", id: "grab", localized: "Grab", type: "XR_ACTION_TYPE_FLOAT_INPUT" },
331
+ {
332
+ name: "triggerAction",
333
+ id: "trigger",
334
+ localized: "Trigger",
335
+ type: "XR_ACTION_TYPE_FLOAT_INPUT"
336
+ },
337
+ {
338
+ name: "aimPoseAction",
339
+ id: "aim_pose",
340
+ localized: "Aim Pose",
341
+ type: "XR_ACTION_TYPE_POSE_INPUT"
342
+ },
343
+ {
344
+ name: "hapticAction",
345
+ id: "haptic",
346
+ localized: "Haptic",
347
+ type: "XR_ACTION_TYPE_VIBRATION_OUTPUT"
348
+ }
349
+ ];
350
+ for (const action of actions) {
351
+ this.emit("{");
352
+ this.indent();
353
+ this.emit("XrActionCreateInfo info{XR_TYPE_ACTION_CREATE_INFO};");
354
+ this.emit(`info.actionType = ${action.type};`);
355
+ this.emit(
356
+ `std::strncpy(info.actionName, "${this.escapeStringValue(action.id, "TypeScript")}", XR_MAX_ACTION_NAME_SIZE);`
357
+ );
358
+ this.emit(
359
+ `std::strncpy(info.localizedActionName, "${action.localized}", XR_MAX_LOCALIZED_ACTION_NAME_SIZE);`
360
+ );
361
+ this.emit("info.countSubactionPaths = 0;");
362
+ this.emit(
363
+ `xrCreateAction(actionSet, &info, &${this.escapeStringValue(action.name, "TypeScript")});`
364
+ );
365
+ this.dedent();
366
+ this.emit("}");
367
+ }
368
+ this.emit("");
369
+ this.emit("// Attach action set to session");
370
+ this.emit("XrSessionActionSetsAttachInfo attachInfo{XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO};");
371
+ this.emit("attachInfo.countActionSets = 1;");
372
+ this.emit("attachInfo.actionSets = &actionSet;");
373
+ this.emit("xrAttachSessionActionSets(session, &attachInfo);");
374
+ this.dedent();
375
+ this.emit("}");
376
+ }
377
+ // ---------------------------------------------------------------------------
378
+ // Environment (clear color, fog)
379
+ // ---------------------------------------------------------------------------
380
+ emitEnvironment(env) {
381
+ this.emit("// === Environment ===");
382
+ for (const prop of env.properties) {
383
+ if (prop.key === "preset" || prop.key === "skybox") {
384
+ this.emit(`// Environment preset: "${prop.value}"`);
385
+ } else if (prop.key === "background" || prop.key === "clear_color") {
386
+ const color = this.toCppColor(prop.value);
387
+ this.emit(`glm::vec4 clearColor = ${color};`);
388
+ } else if (prop.key === "fog" && typeof prop.value === "object") {
389
+ const fog = prop.value;
390
+ const fogColor = fog.color ? this.toCppColor(fog.color) : "glm::vec4(0.5f, 0.5f, 0.5f, 1.0f)";
391
+ this.emit(`glm::vec4 fogColor = ${fogColor};`);
392
+ this.emit(`float fogNear = ${fog.near ?? 10}f;`);
393
+ this.emit(`float fogFar = ${fog.far ?? 100}f;`);
394
+ } else if (prop.key === "ambient_light") {
395
+ const intensity = typeof prop.value === "number" ? prop.value : 0.5;
396
+ this.emit(`float ambientIntensity = ${intensity}f;`);
397
+ } else if (prop.key === "gravity" && Array.isArray(prop.value)) {
398
+ this.emit(`glm::vec3 gravity = ${this.toCppVec3(prop.value)};`);
399
+ }
400
+ }
401
+ this.emit("");
402
+ }
403
+ // ---------------------------------------------------------------------------
404
+ // Object emission
405
+ // ---------------------------------------------------------------------------
406
+ emitObject(obj) {
407
+ const varName = this.sanitizeName(obj.name);
408
+ this.emit(`// Object: ${this.escapeStringValue(obj.name, "TypeScript")}`);
409
+ this.emit("{");
410
+ this.indent();
411
+ const meshType = this.findObjProp(obj, "mesh") || this.findObjProp(obj, "type") || "cube";
412
+ const pos = this.findObjProp(obj, "position");
413
+ const scale = this.findObjProp(obj, "scale");
414
+ const color = this.findObjProp(obj, "color");
415
+ const material = this.findObjProp(obj, "material");
416
+ this.emit(`auto ${varName}_vertices = ${this.mapShapeToVertexData(meshType)};`);
417
+ this.emit("");
418
+ this.emit(`glm::mat4 ${varName}_model = glm::mat4(1.0f);`);
419
+ if (pos && Array.isArray(pos)) {
420
+ this.emit(`${varName}_model = glm::translate(${varName}_model, ${this.toCppVec3(pos)});`);
421
+ }
422
+ if (scale) {
423
+ if (Array.isArray(scale)) {
424
+ this.emit(`${varName}_model = glm::scale(${varName}_model, ${this.toCppVec3(scale)});`);
425
+ } else {
426
+ this.emit(`${varName}_model = glm::scale(${varName}_model, glm::vec3(${scale}f));`);
427
+ }
428
+ }
429
+ this.emit("");
430
+ if (material && typeof material === "object") {
431
+ const mat = material;
432
+ const baseColor = mat.color ? this.toCppColor(mat.color) : "glm::vec4(1.0f)";
433
+ this.emit(`glm::vec4 ${varName}_color = ${baseColor};`);
434
+ this.emit(`float ${varName}_roughness = ${mat.roughness ?? 0.5}f;`);
435
+ this.emit(`float ${varName}_metallic = ${mat.metalness ?? mat.metallic ?? 0}f;`);
436
+ } else if (color) {
437
+ this.emit(`glm::vec4 ${varName}_color = ${this.toCppColor(color)};`);
438
+ } else {
439
+ this.emit(`glm::vec4 ${varName}_color = glm::vec4(1.0f);`);
440
+ }
441
+ this.emit("");
442
+ if (this.options.renderBackend === "vulkan") {
443
+ this.emit(
444
+ `// Create Vulkan vertex buffer for ${this.escapeStringValue(obj.name, "TypeScript")}`
445
+ );
446
+ this.emit(`VkBuffer ${varName}_vbo = VK_NULL_HANDLE;`);
447
+ this.emit(`VkDeviceMemory ${varName}_vboMemory = VK_NULL_HANDLE;`);
448
+ this.emit("{");
449
+ this.indent();
450
+ this.emit("VkBufferCreateInfo bufferInfo{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};");
451
+ this.emit(`bufferInfo.size = ${varName}_vertices.size() * sizeof(float);`);
452
+ this.emit("bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;");
453
+ this.emit("bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;");
454
+ this.emit(`vkCreateBuffer(vkDevice, &bufferInfo, nullptr, &${varName}_vbo);`);
455
+ this.emit("");
456
+ this.emit("VkMemoryRequirements memReqs;");
457
+ this.emit(`vkGetBufferMemoryRequirements(vkDevice, ${varName}_vbo, &memReqs);`);
458
+ this.emit("");
459
+ this.emit("VkMemoryAllocateInfo allocInfo{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};");
460
+ this.emit("allocInfo.allocationSize = memReqs.size;");
461
+ this.emit(
462
+ "allocInfo.memoryTypeIndex = findMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);"
463
+ );
464
+ this.emit(`vkAllocateMemory(vkDevice, &allocInfo, nullptr, &${varName}_vboMemory);`);
465
+ this.emit(`vkBindBufferMemory(vkDevice, ${varName}_vbo, ${varName}_vboMemory, 0);`);
466
+ this.emit("");
467
+ this.emit("// Upload vertex data");
468
+ this.emit("void* mapped = nullptr;");
469
+ this.emit(`vkMapMemory(vkDevice, ${varName}_vboMemory, 0, bufferInfo.size, 0, &mapped);`);
470
+ this.emit(`std::memcpy(mapped, ${varName}_vertices.data(), bufferInfo.size);`);
471
+ this.emit(`vkUnmapMemory(vkDevice, ${varName}_vboMemory);`);
472
+ this.dedent();
473
+ this.emit("}");
474
+ this.emit("");
475
+ this.emit(
476
+ `// Allocate descriptor set for ${this.escapeStringValue(obj.name, "TypeScript")}`
477
+ );
478
+ this.emit(`VkDescriptorSet ${varName}_desc = VK_NULL_HANDLE;`);
479
+ this.emit("{");
480
+ this.indent();
481
+ this.emit(
482
+ "VkDescriptorSetAllocateInfo descAllocInfo{VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO};"
483
+ );
484
+ this.emit("descAllocInfo.descriptorPool = descriptorPool;");
485
+ this.emit("descAllocInfo.descriptorSetCount = 1;");
486
+ this.emit("descAllocInfo.pSetLayouts = &descriptorSetLayout;");
487
+ this.emit(`vkAllocateDescriptorSets(vkDevice, &descAllocInfo, &${varName}_desc);`);
488
+ this.dedent();
489
+ this.emit("}");
490
+ } else {
491
+ this.emit(`GLuint ${varName}_vao, ${varName}_vbo;`);
492
+ this.emit(`glGenVertexArrays(1, &${varName}_vao);`);
493
+ this.emit(`glGenBuffers(1, &${varName}_vbo);`);
494
+ this.emit(`glBindVertexArray(${varName}_vao);`);
495
+ this.emit(`glBindBuffer(GL_ARRAY_BUFFER, ${varName}_vbo);`);
496
+ this.emit(
497
+ `glBufferData(GL_ARRAY_BUFFER, ${varName}_vertices.size() * sizeof(float), ${varName}_vertices.data(), GL_STATIC_DRAW);`
498
+ );
499
+ this.emit("glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);");
500
+ this.emit("glEnableVertexAttribArray(0);");
501
+ this.emit(
502
+ "glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));"
503
+ );
504
+ this.emit("glEnableVertexAttribArray(1);");
505
+ }
506
+ if (obj.traits) {
507
+ for (const trait of obj.traits) {
508
+ if (trait.name === "hand_tracking") {
509
+ this.emit("");
510
+ this.emit(`// Trait: hand_tracking -- joint data driven via XR_EXT_hand_tracking`);
511
+ this.emit(`// ${varName} position will be updated from hand joint locations each frame`);
512
+ } else if (trait.name === "anchor") {
513
+ this.emit("");
514
+ this.emit(`// Trait: anchor -- XR_MSFT_spatial_anchor`);
515
+ this.emit(`XrSpatialAnchorMSFT ${varName}_anchor = XR_NULL_HANDLE;`);
516
+ this.emit(
517
+ "XrSpatialAnchorCreateInfoMSFT anchorInfo{XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_MSFT};"
518
+ );
519
+ this.emit("anchorInfo.space = appSpace;");
520
+ this.emit("anchorInfo.time = predictedDisplayTime;");
521
+ if (pos && Array.isArray(pos)) {
522
+ this.emit(
523
+ `anchorInfo.pose.position = {${pos[0] ?? 0}f, ${pos[1] ?? 0}f, ${pos[2] ?? 0}f};`
524
+ );
525
+ } else {
526
+ this.emit("anchorInfo.pose.position = {0.0f, 0.0f, 0.0f};");
527
+ }
528
+ this.emit("anchorInfo.pose.orientation = {0.0f, 0.0f, 0.0f, 1.0f};");
529
+ this.emit(`xrCreateSpatialAnchorMSFT(session, &anchorInfo, &${varName}_anchor);`);
530
+ } else if (trait.name === "grabbable") {
531
+ this.emit("");
532
+ this.emit(
533
+ `// Trait: grabbable -- detect grip action on ${this.escapeStringValue(obj.name, "TypeScript")}`
534
+ );
535
+ this.emit(`bool ${varName}_grabbed = false;`);
536
+ } else if (trait.name === "physics") {
537
+ this.emit("");
538
+ this.emit(`// Trait: physics -- simulated via CPU/GPU physics step`);
539
+ this.emit(`glm::vec3 ${varName}_velocity(0.0f);`);
540
+ this.emit(`float ${varName}_mass = ${trait.config?.mass ?? 1}f;`);
541
+ }
542
+ }
543
+ }
544
+ this.dedent();
545
+ this.emit("}");
546
+ this.emit("");
547
+ if (obj.children) {
548
+ for (const child of obj.children) {
549
+ this.emitObject(child);
550
+ }
551
+ }
552
+ }
553
+ // ---------------------------------------------------------------------------
554
+ // Spatial group
555
+ // ---------------------------------------------------------------------------
556
+ emitGroup(group) {
557
+ const varName = this.sanitizeName(group.name);
558
+ this.emit(`// Spatial Group: ${this.escapeStringValue(group.name, "TypeScript")}`);
559
+ this.emit("{");
560
+ this.indent();
561
+ this.emit(`glm::mat4 ${varName}_transform = glm::mat4(1.0f);`);
562
+ for (const prop of group.properties) {
563
+ if (prop.key === "position" && Array.isArray(prop.value)) {
564
+ this.emit(
565
+ `${varName}_transform = glm::translate(${varName}_transform, ${this.toCppVec3(prop.value)});`
566
+ );
567
+ } else if (prop.key === "rotation" && Array.isArray(prop.value)) {
568
+ const r = prop.value;
569
+ this.emit(
570
+ `${varName}_transform = glm::rotate(${varName}_transform, glm::radians(${r[0] ?? 0}f), glm::vec3(1,0,0));`
571
+ );
572
+ this.emit(
573
+ `${varName}_transform = glm::rotate(${varName}_transform, glm::radians(${r[1] ?? 0}f), glm::vec3(0,1,0));`
574
+ );
575
+ this.emit(
576
+ `${varName}_transform = glm::rotate(${varName}_transform, glm::radians(${r[2] ?? 0}f), glm::vec3(0,0,1));`
577
+ );
578
+ } else if (prop.key === "scale") {
579
+ if (Array.isArray(prop.value)) {
580
+ this.emit(
581
+ `${varName}_transform = glm::scale(${varName}_transform, ${this.toCppVec3(prop.value)});`
582
+ );
583
+ } else {
584
+ this.emit(
585
+ `${varName}_transform = glm::scale(${varName}_transform, glm::vec3(${prop.value}f));`
586
+ );
587
+ }
588
+ }
589
+ }
590
+ this.emit(`// Push ${varName}_transform onto model matrix stack`);
591
+ this.emit("");
592
+ for (const obj of group.objects) {
593
+ this.emitObject(obj);
594
+ }
595
+ if (group.groups) {
596
+ for (const sub of group.groups) {
597
+ this.emitGroup(sub);
598
+ }
599
+ }
600
+ this.emit("// Pop model matrix stack");
601
+ this.dedent();
602
+ this.emit("}");
603
+ this.emit("");
604
+ }
605
+ // ---------------------------------------------------------------------------
606
+ // Light
607
+ // ---------------------------------------------------------------------------
608
+ emitLight(light) {
609
+ const varName = this.sanitizeName(light.name);
610
+ this.emit(
611
+ `// Light: ${this.escapeStringValue(light.name, "TypeScript")} (${light.lightType})`
612
+ );
613
+ this.emit("{");
614
+ this.indent();
615
+ this.emit(`LightUBO ${varName}_ubo;`);
616
+ const colorProp = light.properties.find((p) => p.key === "color");
617
+ const intensityProp = light.properties.find((p) => p.key === "intensity");
618
+ const posProp = light.properties.find((p) => p.key === "position");
619
+ if (posProp && Array.isArray(posProp.value)) {
620
+ const p = posProp.value;
621
+ const w = light.lightType === "directional" ? 0 : 1;
622
+ this.emit(`${varName}_ubo.position = glm::vec4(${p[0]}f, ${p[1]}f, ${p[2]}f, ${w}f);`);
623
+ } else {
624
+ const w = light.lightType === "directional" ? 0 : 1;
625
+ this.emit(`${varName}_ubo.position = glm::vec4(0.0f, 5.0f, 0.0f, ${w}f);`);
626
+ }
627
+ if (colorProp) {
628
+ this.emit(`${varName}_ubo.color = ${this.toCppColor(colorProp.value)};`);
629
+ } else {
630
+ this.emit(`${varName}_ubo.color = glm::vec4(1.0f);`);
631
+ }
632
+ this.emit(`${varName}_ubo.intensity = ${intensityProp?.value ?? 1}f;`);
633
+ this.emit(`${varName}_ubo.range = ${light.lightType === "directional" ? 0 : 50}f;`);
634
+ this.emit(`// Upload ${varName}_ubo to uniform buffer`);
635
+ this.dedent();
636
+ this.emit("}");
637
+ this.emit("");
638
+ }
639
+ // ---------------------------------------------------------------------------
640
+ // Camera (XR view-driven)
641
+ // ---------------------------------------------------------------------------
642
+ emitCamera(cam) {
643
+ this.emit("// Camera: view/projection derived from xrLocateViews");
644
+ this.emit("{");
645
+ this.indent();
646
+ this.emit("XrViewLocateInfo viewLocateInfo{XR_TYPE_VIEW_LOCATE_INFO};");
647
+ this.emit("viewLocateInfo.viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;");
648
+ this.emit("viewLocateInfo.displayTime = predictedDisplayTime;");
649
+ this.emit("viewLocateInfo.space = appSpace;");
650
+ this.emit("");
651
+ this.emit("XrViewState viewState{XR_TYPE_VIEW_STATE};");
652
+ this.emit("uint32_t viewCount = 2;");
653
+ this.emit("std::array<XrView, 2> views;");
654
+ this.emit("views[0].type = XR_TYPE_VIEW;");
655
+ this.emit("views[1].type = XR_TYPE_VIEW;");
656
+ this.emit(
657
+ "xrLocateViews(session, &viewLocateInfo, &viewState, viewCount, &viewCount, views.data());"
658
+ );
659
+ this.emit("");
660
+ this.emit("// Per-eye projection and view matrices");
661
+ this.emit("for (uint32_t eye = 0; eye < viewCount; eye++) {");
662
+ this.indent();
663
+ this.emit("const XrFovf& fov = views[eye].fov;");
664
+ for (const prop of cam.properties) {
665
+ if (prop.key === "near" || prop.key === "near_clip") {
666
+ this.emit(`float nearClip = ${prop.value}f;`);
667
+ } else if (prop.key === "far" || prop.key === "far_clip") {
668
+ this.emit(`float farClip = ${prop.value}f;`);
669
+ }
670
+ }
671
+ this.emit("// Build asymmetric projection from fov angles + near/far");
672
+ this.emit("// Build view matrix from views[eye].pose");
673
+ this.dedent();
674
+ this.emit("}");
675
+ this.dedent();
676
+ this.emit("}");
677
+ this.emit("");
678
+ }
679
+ // ---------------------------------------------------------------------------
680
+ // Render pass
681
+ // ---------------------------------------------------------------------------
682
+ emitRenderPass() {
683
+ if (this.options.renderBackend === "vulkan") {
684
+ this.emit(
685
+ "void beginRenderPass(VkCommandBuffer cmd, VkRenderPass renderPass, VkFramebuffer framebuffer, uint32_t width, uint32_t height) {"
686
+ );
687
+ this.indent();
688
+ this.emit("VkRenderPassBeginInfo rpInfo{VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO};");
689
+ this.emit("rpInfo.renderPass = renderPass;");
690
+ this.emit("rpInfo.framebuffer = framebuffer;");
691
+ this.emit("rpInfo.renderArea.extent = {width, height};");
692
+ this.emit("VkClearValue clearValue{};");
693
+ this.emit("clearValue.color = {{0.0f, 0.0f, 0.0f, 1.0f}};");
694
+ this.emit("rpInfo.clearValueCount = 1;");
695
+ this.emit("rpInfo.pClearValues = &clearValue;");
696
+ this.emit("vkCmdBeginRenderPass(cmd, &rpInfo, VK_SUBPASS_CONTENTS_INLINE);");
697
+ this.emit("");
698
+ this.emit("// Bind pipeline and draw objects here");
699
+ this.emit("");
700
+ this.emit("vkCmdEndRenderPass(cmd);");
701
+ this.dedent();
702
+ this.emit("}");
703
+ } else {
704
+ this.emit("void beginRenderPass(uint32_t framebuffer, uint32_t width, uint32_t height) {");
705
+ this.indent();
706
+ this.emit("glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);");
707
+ this.emit("glViewport(0, 0, width, height);");
708
+ this.emit("glClearColor(0.0f, 0.0f, 0.0f, 1.0f);");
709
+ this.emit("glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);");
710
+ this.emit("glEnable(GL_DEPTH_TEST);");
711
+ this.emit("");
712
+ this.emit("// Bind shader program and draw objects here");
713
+ this.emit("");
714
+ this.dedent();
715
+ this.emit("}");
716
+ }
717
+ }
718
+ // ---------------------------------------------------------------------------
719
+ // Render loop
720
+ // ---------------------------------------------------------------------------
721
+ emitRenderLoop(composition) {
722
+ this.emit("void renderLoop() {");
723
+ this.indent();
724
+ this.emit("while (sessionRunning) {");
725
+ this.indent();
726
+ this.emit("// Poll OpenXR events");
727
+ this.emit("XrEventDataBuffer event{XR_TYPE_EVENT_DATA_BUFFER};");
728
+ this.emit("while (xrPollEvent(instance, &event) == XR_SUCCESS) {");
729
+ this.indent();
730
+ this.emit("if (event.type == XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED) {");
731
+ this.indent();
732
+ this.emit("auto* stateEvent = reinterpret_cast<XrEventDataSessionStateChanged*>(&event);");
733
+ this.emit("if (stateEvent->state == XR_SESSION_STATE_STOPPING) {");
734
+ this.indent();
735
+ this.emit("sessionRunning = false;");
736
+ this.dedent();
737
+ this.emit("}");
738
+ this.dedent();
739
+ this.emit("}");
740
+ this.emit("event = {XR_TYPE_EVENT_DATA_BUFFER};");
741
+ this.dedent();
742
+ this.emit("}");
743
+ this.emit("if (!sessionRunning) break;");
744
+ this.emit("");
745
+ this.emit("// Sync actions");
746
+ this.emit("XrActiveActionSet activeActionSet{actionSet, XR_NULL_PATH};");
747
+ this.emit("XrActionsSyncInfo syncInfo{XR_TYPE_ACTIONS_SYNC_INFO};");
748
+ this.emit("syncInfo.countActiveActionSets = 1;");
749
+ this.emit("syncInfo.activeActionSets = &activeActionSet;");
750
+ this.emit("xrSyncActions(session, &syncInfo);");
751
+ this.emit("");
752
+ this.emit("// Wait frame");
753
+ this.emit("XrFrameWaitInfo waitInfo{XR_TYPE_FRAME_WAIT_INFO};");
754
+ this.emit("XrFrameState frameState{XR_TYPE_FRAME_STATE};");
755
+ this.emit("xrWaitFrame(session, &waitInfo, &frameState);");
756
+ this.emit("");
757
+ this.emit("// Begin frame");
758
+ this.emit("XrFrameBeginInfo beginInfo{XR_TYPE_FRAME_BEGIN_INFO};");
759
+ this.emit("xrBeginFrame(session, &beginInfo);");
760
+ this.emit("");
761
+ this.emit("XrTime predictedDisplayTime = frameState.predictedDisplayTime;");
762
+ this.emit("");
763
+ if (this.options.enableHandTracking) {
764
+ this.emit("// Hand tracking update");
765
+ this.emit("updateHandTracking(predictedDisplayTime);");
766
+ this.emit("");
767
+ }
768
+ this.emit("// Locate views for stereo rendering");
769
+ this.emit("XrViewLocateInfo viewLocateInfo{XR_TYPE_VIEW_LOCATE_INFO};");
770
+ this.emit("viewLocateInfo.viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;");
771
+ this.emit("viewLocateInfo.displayTime = predictedDisplayTime;");
772
+ this.emit("viewLocateInfo.space = appSpace;");
773
+ this.emit("XrViewState viewState{XR_TYPE_VIEW_STATE};");
774
+ this.emit("uint32_t viewCount = 2;");
775
+ this.emit("std::array<XrView, 2> views;");
776
+ this.emit("views[0].type = XR_TYPE_VIEW;");
777
+ this.emit("views[1].type = XR_TYPE_VIEW;");
778
+ this.emit(
779
+ "xrLocateViews(session, &viewLocateInfo, &viewState, viewCount, &viewCount, views.data());"
780
+ );
781
+ this.emit("");
782
+ this.emit("// Acquire and render to swapchain image");
783
+ this.emit("XrSwapchainImageAcquireInfo acquireInfo{XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO};");
784
+ this.emit("uint32_t imageIndex;");
785
+ this.emit("xrAcquireSwapchainImage(swapchain, &acquireInfo, &imageIndex);");
786
+ this.emit("");
787
+ this.emit("XrSwapchainImageWaitInfo swapWaitInfo{XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO};");
788
+ this.emit("swapWaitInfo.timeout = XR_INFINITE_DURATION;");
789
+ this.emit("xrWaitSwapchainImage(swapchain, &swapWaitInfo);");
790
+ this.emit("");
791
+ this.emit("// === Render scene objects ===");
792
+ if (this.options.renderBackend === "vulkan") {
793
+ this.emit(
794
+ "VkCommandBufferBeginInfo cmdBeginInfo{VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO};"
795
+ );
796
+ this.emit("cmdBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;");
797
+ this.emit("vkBeginCommandBuffer(commandBuffer, &cmdBeginInfo);");
798
+ this.emit("");
799
+ this.emit(
800
+ "beginRenderPass(commandBuffer, renderPass, framebuffers[imageIndex], 1920, 1920);"
801
+ );
802
+ this.emit("");
803
+ const allObjects = this.collectAllObjects(composition);
804
+ for (const obj of allObjects) {
805
+ const varName = this.sanitizeName(obj.name);
806
+ this.emit(`// Draw: ${this.escapeStringValue(obj.name, "TypeScript")}`);
807
+ this.emit(
808
+ `vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);`
809
+ );
810
+ this.emit(`VkDeviceSize ${varName}_offset = 0;`);
811
+ this.emit(
812
+ `vkCmdBindVertexBuffers(commandBuffer, 0, 1, &${varName}_vbo, &${varName}_offset);`
813
+ );
814
+ this.emit(
815
+ `vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &${varName}_desc, 0, nullptr);`
816
+ );
817
+ this.emit(
818
+ `vkCmdDraw(commandBuffer, static_cast<uint32_t>(${varName}_vertices.size() / 6), 1, 0, 0);`
819
+ );
820
+ this.emit("");
821
+ }
822
+ this.emit("vkCmdEndRenderPass(commandBuffer);");
823
+ this.emit("vkEndCommandBuffer(commandBuffer);");
824
+ this.emit("");
825
+ this.emit("// Submit command buffer");
826
+ this.emit("VkSubmitInfo submitInfo{VK_STRUCTURE_TYPE_SUBMIT_INFO};");
827
+ this.emit("submitInfo.commandBufferCount = 1;");
828
+ this.emit("submitInfo.pCommandBuffers = &commandBuffer;");
829
+ this.emit("vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);");
830
+ this.emit("vkQueueWaitIdle(graphicsQueue);");
831
+ } else {
832
+ const allObjects = this.collectAllObjects(composition);
833
+ for (const obj of allObjects) {
834
+ const varName = this.sanitizeName(obj.name);
835
+ this.emit(`// Draw: ${this.escapeStringValue(obj.name, "TypeScript")}`);
836
+ this.emit(`glBindVertexArray(${varName}_vao);`);
837
+ this.emit(
838
+ `glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(${varName}_vertices.size() / 6));`
839
+ );
840
+ this.emit("");
841
+ }
842
+ }
843
+ this.emit("");
844
+ this.emit("XrSwapchainImageReleaseInfo releaseInfo{XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO};");
845
+ this.emit("xrReleaseSwapchainImage(swapchain, &releaseInfo);");
846
+ this.emit("");
847
+ this.emit("// End frame");
848
+ this.emit("XrCompositionLayerProjection layer{XR_TYPE_COMPOSITION_LAYER_PROJECTION};");
849
+ this.emit("layer.space = appSpace;");
850
+ this.emit("std::array<XrCompositionLayerProjectionView, 2> projViews;");
851
+ this.emit("for (uint32_t eye = 0; eye < 2; eye++) {");
852
+ this.indent();
853
+ this.emit("projViews[eye] = {XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW};");
854
+ this.emit("projViews[eye].pose = views[eye].pose;");
855
+ this.emit("projViews[eye].fov = views[eye].fov;");
856
+ this.emit("projViews[eye].subImage.swapchain = swapchain;");
857
+ this.emit("projViews[eye].subImage.imageArrayIndex = eye;");
858
+ this.emit("projViews[eye].subImage.imageRect.offset = {0, 0};");
859
+ this.emit("projViews[eye].subImage.imageRect.extent = {1920, 1920};");
860
+ this.dedent();
861
+ this.emit("}");
862
+ this.emit("layer.viewCount = 2;");
863
+ this.emit("layer.views = projViews.data();");
864
+ this.emit("");
865
+ this.emit("const XrCompositionLayerBaseHeader* layers[] = {");
866
+ this.indent();
867
+ this.emit("reinterpret_cast<const XrCompositionLayerBaseHeader*>(&layer)");
868
+ this.dedent();
869
+ this.emit("};");
870
+ this.emit("XrFrameEndInfo endInfo{XR_TYPE_FRAME_END_INFO};");
871
+ this.emit("endInfo.displayTime = predictedDisplayTime;");
872
+ this.emit("endInfo.environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;");
873
+ this.emit("endInfo.layerCount = 1;");
874
+ this.emit("endInfo.layers = layers;");
875
+ this.emit("xrEndFrame(session, &endInfo);");
876
+ this.dedent();
877
+ this.emit("}");
878
+ this.dedent();
879
+ this.emit("}");
880
+ }
881
+ // ---------------------------------------------------------------------------
882
+ // Hand tracking
883
+ // ---------------------------------------------------------------------------
884
+ emitHandTracking() {
885
+ this.emit("void initHandTracking() {");
886
+ this.indent();
887
+ this.emit("XrHandTrackerCreateInfoEXT createInfo{XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT};");
888
+ this.emit("");
889
+ this.emit("createInfo.hand = XR_HAND_LEFT_EXT;");
890
+ this.emit("createInfo.handJointSet = XR_HAND_JOINT_SET_DEFAULT_EXT;");
891
+ this.emit("xrCreateHandTrackerEXT(session, &createInfo, &handTrackerLeft);");
892
+ this.emit("");
893
+ this.emit("createInfo.hand = XR_HAND_RIGHT_EXT;");
894
+ this.emit("xrCreateHandTrackerEXT(session, &createInfo, &handTrackerRight);");
895
+ this.dedent();
896
+ this.emit("}");
897
+ this.emit("");
898
+ this.emit("void updateHandTracking(XrTime displayTime) {");
899
+ this.indent();
900
+ this.emit("XrHandJointLocationsEXT locations{XR_TYPE_HAND_JOINT_LOCATIONS_EXT};");
901
+ this.emit(`std::array<XrHandJointLocationEXT, XR_HAND_JOINT_COUNT_EXT> jointLocations;`);
902
+ this.emit("locations.jointCount = static_cast<uint32_t>(jointLocations.size());");
903
+ this.emit("locations.jointLocations = jointLocations.data();");
904
+ this.emit("");
905
+ this.emit("XrHandJointsLocateInfoEXT locateInfo{XR_TYPE_HAND_JOINTS_LOCATE_INFO_EXT};");
906
+ this.emit("locateInfo.baseSpace = appSpace;");
907
+ this.emit("locateInfo.time = displayTime;");
908
+ this.emit("");
909
+ this.emit("// Left hand");
910
+ this.emit("xrLocateHandJointsEXT(handTrackerLeft, &locateInfo, &locations);");
911
+ this.emit("if (locations.isActive) {");
912
+ this.indent();
913
+ this.emit("// Process left hand joint positions");
914
+ this.emit("for (uint32_t j = 0; j < XR_HAND_JOINT_COUNT_EXT; j++) {");
915
+ this.indent();
916
+ this.emit("const auto& loc = jointLocations[j];");
917
+ this.emit("glm::vec3 pos(loc.pose.position[0], loc.pose.position[1], loc.pose.position[2]);");
918
+ this.emit("// Update hand-tracked object transforms from joint data");
919
+ this.dedent();
920
+ this.emit("}");
921
+ this.dedent();
922
+ this.emit("}");
923
+ this.emit("");
924
+ this.emit("// Right hand");
925
+ this.emit("xrLocateHandJointsEXT(handTrackerRight, &locateInfo, &locations);");
926
+ this.emit("if (locations.isActive) {");
927
+ this.indent();
928
+ this.emit("for (uint32_t j = 0; j < XR_HAND_JOINT_COUNT_EXT; j++) {");
929
+ this.indent();
930
+ this.emit("const auto& loc = jointLocations[j];");
931
+ this.emit("glm::vec3 pos(loc.pose.position[0], loc.pose.position[1], loc.pose.position[2]);");
932
+ this.emit("// Update hand-tracked object transforms from joint data");
933
+ this.dedent();
934
+ this.emit("}");
935
+ this.dedent();
936
+ this.emit("}");
937
+ this.dedent();
938
+ this.emit("}");
939
+ }
940
+ // ---------------------------------------------------------------------------
941
+ // Helpers
942
+ // ---------------------------------------------------------------------------
943
+ emit(line) {
944
+ this.lines.push(this.options.indent.repeat(this.indentLevel) + line);
945
+ }
946
+ indent() {
947
+ this.indentLevel++;
948
+ }
949
+ dedent() {
950
+ if (this.indentLevel > 0) this.indentLevel--;
951
+ }
952
+ sanitizeName(name) {
953
+ return name.replace(/[^a-zA-Z0-9_]/g, "_");
954
+ }
955
+ findObjProp(obj, key) {
956
+ return obj.properties?.find((p) => p.key === key)?.value;
957
+ }
958
+ // ---------------------------------------------------------------------------
959
+ // Value conversion helpers
960
+ // ---------------------------------------------------------------------------
961
+ toCppVec3(arr) {
962
+ if (Array.isArray(arr) && arr.length >= 3) {
963
+ return `glm::vec3(${arr[0]}f, ${arr[1]}f, ${arr[2]}f)`;
964
+ }
965
+ if (typeof arr === "number") {
966
+ return `glm::vec3(${arr}f)`;
967
+ }
968
+ return "glm::vec3(0.0f)";
969
+ }
970
+ toCppColor(hex) {
971
+ if (typeof hex === "string" && hex.startsWith("#")) {
972
+ const h = hex.slice(1);
973
+ const r = (parseInt(h.substring(0, 2), 16) / 255).toFixed(3);
974
+ const g = (parseInt(h.substring(2, 4), 16) / 255).toFixed(3);
975
+ const b = (parseInt(h.substring(4, 6), 16) / 255).toFixed(3);
976
+ return `glm::vec4(${r}f, ${g}f, ${b}f, 1.0f)`;
977
+ }
978
+ if (typeof hex === "string") {
979
+ return `glm::vec4(1.0f) /* ${hex} */`;
980
+ }
981
+ return "glm::vec4(1.0f)";
982
+ }
983
+ mapShapeToVertexData(type) {
984
+ switch (type) {
985
+ case "cube":
986
+ case "box":
987
+ return "generateCubeVertices()";
988
+ case "sphere":
989
+ case "orb":
990
+ return "generateSphereVertices(32, 32)";
991
+ case "plane":
992
+ return "generatePlaneVertices()";
993
+ case "cylinder":
994
+ return "generateCylinderVertices(32)";
995
+ case "cone":
996
+ case "pyramid":
997
+ return "generateConeVertices(32)";
998
+ case "torus":
999
+ return "generateTorusVertices(32, 16)";
1000
+ default:
1001
+ return "generateCubeVertices()";
1002
+ }
1003
+ }
1004
+ // ---------------------------------------------------------------------------
1005
+ // Composition analysis helpers
1006
+ // ---------------------------------------------------------------------------
1007
+ compositionUsesAnchor(composition) {
1008
+ const check = (objs) => {
1009
+ if (!objs) return false;
1010
+ return objs.some(
1011
+ (o) => o.traits?.some(
1012
+ (t) => t.name === "anchor" || t.name === "persistent_anchor" || t.name === "shared_anchor"
1013
+ ) || check(o.children)
1014
+ );
1015
+ };
1016
+ return check(composition.objects);
1017
+ }
1018
+ collectAllObjects(composition) {
1019
+ const result = [];
1020
+ const collect = (objs) => {
1021
+ if (!objs) return;
1022
+ for (const obj of objs) {
1023
+ result.push(obj);
1024
+ if (obj.children) {
1025
+ collect(obj.children);
1026
+ }
1027
+ }
1028
+ };
1029
+ collect(composition.objects);
1030
+ const collectFromGroups = (groups) => {
1031
+ if (!groups) return;
1032
+ for (const group of groups) {
1033
+ collect(group.objects);
1034
+ if (group.groups) {
1035
+ collectFromGroups(group.groups);
1036
+ }
1037
+ }
1038
+ };
1039
+ collectFromGroups(composition.spatialGroups);
1040
+ return result;
1041
+ }
1042
+ };
1043
+ }
1044
+ });
1045
+
1046
+ exports.OpenXRCompiler_exports = OpenXRCompiler_exports;
1047
+ exports.init_OpenXRCompiler = init_OpenXRCompiler;
1048
+ //# sourceMappingURL=chunk-HINXWAOD.cjs.map
1049
+ //# sourceMappingURL=chunk-HINXWAOD.cjs.map