@holoscript/core 8.0.7 → 8.0.9

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 (462) hide show
  1. package/bin/holoscript.cjs +5 -1
  2. package/dist/GLTFPipeline-L76YTXKA.js +15 -0
  3. package/dist/GLTFPipeline-ZWJN7GI6.cjs +36 -0
  4. package/dist/HoloCompositionParser-K76KTEEE.js +12 -0
  5. package/dist/HoloCompositionParser-UZH6Y4HO.cjs +45 -0
  6. package/dist/HoloScriptCodeParser-2D4ERFUZ.js +6 -0
  7. package/dist/HoloScriptCodeParser-UDRLDA7I.cjs +23 -0
  8. package/dist/HoloScriptPlusParser-FTMCGWXD.js +13 -0
  9. package/dist/HoloScriptPlusParser-LQR5GIKF.cjs +30 -0
  10. package/dist/HoloScriptRuntime-UTRLJI5L.js +12 -0
  11. package/dist/HoloScriptRuntime-YBYXJHJN.cjs +21 -0
  12. package/dist/SceneIRCompiler-63KA3M2F.js +17 -0
  13. package/dist/SceneIRCompiler-KWUFHZ4O.cjs +42 -0
  14. package/dist/{USDZExporter-AUHZODOF.cjs → USDZExporter-ML4UMIGC.cjs} +3 -3
  15. package/dist/{USDZExporter-GXB4AUSG.js → USDZExporter-ZFKLQ76G.js} +3 -3
  16. package/dist/agents/index.cjs +1 -1
  17. package/dist/agents/index.js +1 -1
  18. package/dist/audit/AuditLogger.d.ts +106 -0
  19. package/dist/audit/AuditQueryBuilder.d.ts +79 -0
  20. package/dist/audit/ComplianceReporter.d.ts +90 -0
  21. package/dist/audit/index.d.ts +13 -0
  22. package/dist/{chunk-FGMDMJM7.js → chunk-2BYAUHBO.js} +3 -3
  23. package/dist/{chunk-EDPYCLRC.cjs → chunk-2E6PP5UE.cjs} +83 -59
  24. package/dist/{chunk-GASCWJK5.js → chunk-2EGGAZT3.js} +65 -287
  25. package/dist/{chunk-SIEXCILW.js → chunk-2I3XAGMF.js} +3 -3
  26. package/dist/{chunk-OS533P33.cjs → chunk-2KKOYZYI.cjs} +1074 -1655
  27. package/dist/chunk-2MQKNDNH.js +51 -0
  28. package/dist/{chunk-7DMMMBCY.cjs → chunk-2X3IPCBK.cjs} +10 -10
  29. package/dist/chunk-2ZOTBO25.cjs +202 -0
  30. package/dist/chunk-356N4NPM.cjs +152 -0
  31. package/dist/{chunk-X3GJPRVK.cjs → chunk-36NPLOI4.cjs} +92 -81
  32. package/dist/{chunk-SLU6UPJI.cjs → chunk-37HHY7RH.cjs} +5 -5
  33. package/dist/{chunk-YDPEHCCI.cjs → chunk-3CDDRUER.cjs} +3 -118
  34. package/dist/chunk-3F7ZZWIN.js +1651 -0
  35. package/dist/chunk-3ILD7TKP.cjs +187 -0
  36. package/dist/{chunk-X27QRG4C.cjs → chunk-3IUHTGDD.cjs} +153 -41
  37. package/dist/{chunk-PXNZ6TME.js → chunk-4376VHNJ.js} +60 -36
  38. package/dist/{chunk-YKGPCZEE.cjs → chunk-4FIBOJW6.cjs} +10 -10
  39. package/dist/chunk-4Q7RKQQI.cjs +14195 -0
  40. package/dist/{chunk-YCM6QQRT.cjs → chunk-566ZB4LZ.cjs} +180 -8
  41. package/dist/{chunk-2Y3V22SG.js → chunk-5CURIYGT.js} +3 -3
  42. package/dist/{chunk-QBWNJXNR.js → chunk-5FYMCVBY.js} +5 -5
  43. package/dist/{chunk-ZA34AN3R.js → chunk-5LVFTGKH.js} +841 -12
  44. package/dist/chunk-63AUAIL6.js +48 -0
  45. package/dist/chunk-655FATJU.js +110 -0
  46. package/dist/{chunk-TQ377OLB.cjs → chunk-65S62L4D.cjs} +28 -22
  47. package/dist/chunk-6NTAZN5Z.cjs +502 -0
  48. package/dist/chunk-6TRX6AR2.js +9376 -0
  49. package/dist/chunk-6ZCCLKS2.cjs +51 -0
  50. package/dist/{chunk-MDR235RZ.js → chunk-734OB5SK.js} +721 -8
  51. package/dist/{chunk-Q2Q34NF3.js → chunk-77QI552M.js} +6 -6
  52. package/dist/{chunk-WKX5AMOY.js → chunk-7I74JWPW.js} +3 -3
  53. package/dist/{chunk-5FSKKMR7.cjs → chunk-7IDJDMPU.cjs} +232 -4
  54. package/dist/chunk-7VBKRGIZ.cjs +847 -0
  55. package/dist/{chunk-KCPHASCO.js → chunk-AATYYLYK.js} +5 -5
  56. package/dist/{chunk-WFKVS2K4.cjs → chunk-AUZRKIHQ.cjs} +1101 -55
  57. package/dist/{chunk-DTGBOSEM.cjs → chunk-AWXFEAQL.cjs} +12 -12
  58. package/dist/{chunk-THCK6ECW.js → chunk-B3CWTCK2.js} +231 -3
  59. package/dist/chunk-BCP4E7MD.cjs +997 -0
  60. package/dist/chunk-BG7RPYJP.js +91 -0
  61. package/dist/{chunk-VF257YKO.js → chunk-BP4KTMLY.js} +117 -5
  62. package/dist/{chunk-YN6IETRZ.js → chunk-BQJ3YBF3.js} +6424 -987
  63. package/dist/{chunk-KOUAQL2B.cjs → chunk-CANAL6CT.cjs} +1569 -168
  64. package/dist/{chunk-FDSGHPAK.js → chunk-CBSDJF3B.js} +3 -3
  65. package/dist/{chunk-FEWUHQNM.cjs → chunk-CFVK26P4.cjs} +4 -4
  66. package/dist/{chunk-M7K4LE66.cjs → chunk-CI33NINL.cjs} +4 -4
  67. package/dist/{chunk-2OWDB4FB.js → chunk-CKV5NYAE.js} +6 -6
  68. package/dist/{chunk-LPS5AMQD.cjs → chunk-CM4NHXVO.cjs} +24 -24
  69. package/dist/chunk-D3HSRXYB.js +115 -0
  70. package/dist/{chunk-FNHJRI32.js → chunk-DBH3D2MU.js} +1561 -160
  71. package/dist/{chunk-GW3LKD5C.js → chunk-DJNH4HFW.js} +3 -3
  72. package/dist/{chunk-2GCNOI2U.cjs → chunk-DN6F4DHH.cjs} +9 -3
  73. package/dist/chunk-DQRJ5RJG.js +432 -0
  74. package/dist/{chunk-C7ZBSV2Q.js → chunk-DUG3OQAS.js} +106 -43
  75. package/dist/chunk-ECUYJOJ2.cjs +199 -0
  76. package/dist/chunk-EEMTCAK7.js +182 -0
  77. package/dist/{chunk-3SKLAUDD.cjs → chunk-EI3J6LTW.cjs} +359 -581
  78. package/dist/{chunk-SSSN7VAM.js → chunk-EM2OGPYE.js} +4 -4
  79. package/dist/{chunk-56VOWURB.cjs → chunk-ENZCIQZC.cjs} +522 -453
  80. package/dist/chunk-ESBXUYOC.cjs +836 -0
  81. package/dist/{chunk-L5U4W6JC.js → chunk-ESSEF6U2.js} +4 -4
  82. package/dist/chunk-ET3AN4W3.js +824 -0
  83. package/dist/chunk-EXKSFGSX.cjs +14 -14
  84. package/dist/{chunk-I76GIKN7.cjs → chunk-F3YT6GUF.cjs} +17 -17
  85. package/dist/{chunk-WRWEX5ZF.js → chunk-F75DZBBI.js} +3 -3
  86. package/dist/{chunk-4JGRWHZJ.js → chunk-FG6PYGIZ.js} +12 -6
  87. package/dist/chunk-FGGJQRLZ.js +14 -14
  88. package/dist/{chunk-SXOSDZD6.js → chunk-FWCHPCD4.js} +128 -10
  89. package/dist/{chunk-XW6IXEQH.cjs → chunk-G35CAQ7I.cjs} +5 -5
  90. package/dist/{chunk-7VMGP2FW.js → chunk-G6KACNMO.js} +132 -188
  91. package/dist/{chunk-FJPADH77.cjs → chunk-GAWJJAGT.cjs} +6 -6
  92. package/dist/chunk-GGR7QUKK.cjs +4724 -0
  93. package/dist/chunk-GIBF4BHH.js +14098 -0
  94. package/dist/{chunk-AWB7QYY6.cjs → chunk-GILYQ5VH.cjs} +6 -6
  95. package/dist/{chunk-FWVYAMNW.cjs → chunk-GKFCHGCM.cjs} +4 -4
  96. package/dist/{chunk-Y3ZFVUUU.js → chunk-GLEJ2TLS.js} +3 -3
  97. package/dist/{chunk-3GWWJT7L.js → chunk-GP3OKSKT.js} +13 -13
  98. package/dist/chunk-GTIPOEHN.js +196 -0
  99. package/dist/{chunk-LMJ5EBV7.cjs → chunk-GZPUA2TL.cjs} +16 -15
  100. package/dist/{chunk-IELX2OKI.js → chunk-H4LJ4HEA.js} +3 -115
  101. package/dist/{chunk-ACVWFGBI.cjs → chunk-HCX4SMFK.cjs} +3 -3
  102. package/dist/{chunk-HYNTS5CP.js → chunk-HHRZ6STP.js} +24 -2
  103. package/dist/chunk-HIDEIEFG.js +48 -0
  104. package/dist/{chunk-W6RW64BB.cjs → chunk-HSWBIDZM.cjs} +228 -5
  105. package/dist/{chunk-GSOUNWEL.js → chunk-HVX7QQYK.js} +1035 -1616
  106. package/dist/{chunk-TRCGG42I.cjs → chunk-IFW5IW4L.cjs} +6502 -1019
  107. package/dist/{chunk-F5LKJ6F5.cjs → chunk-IJU6AS67.cjs} +32 -28
  108. package/dist/{chunk-TVANHNJ7.js → chunk-IK6Z2HNC.js} +173 -3
  109. package/dist/{chunk-QGMUTVVH.cjs → chunk-IS7NTKY5.cjs} +20 -20
  110. package/dist/{chunk-YFVQWSNJ.js → chunk-IXWGYWH6.js} +3 -3
  111. package/dist/chunk-J2DAS2PL.js +148 -0
  112. package/dist/chunk-JBQXZIWB.js +148 -0
  113. package/dist/chunk-JBYBMBMW.js +261 -0
  114. package/dist/{chunk-LWUOUCYL.js → chunk-JEJ7TT54.js} +5 -5
  115. package/dist/{chunk-DUCB6LGL.js → chunk-JOTCTHN5.js} +211 -5
  116. package/dist/{chunk-47RUFYKR.js → chunk-K56UVEXV.js} +3 -3
  117. package/dist/{chunk-XSFNHP2E.js → chunk-KB26H447.js} +3 -3
  118. package/dist/{chunk-3NGDZZR4.js → chunk-KEYG7HGY.js} +430 -37
  119. package/dist/{chunk-DY72BMU5.js → chunk-KFVNCW4Q.js} +4 -4
  120. package/dist/chunk-KPGC7SK2.js +192 -0
  121. package/dist/chunk-KROXXBK5.cjs +53 -0
  122. package/dist/{chunk-ZPZAVHXL.cjs → chunk-LB3ZZMKT.cjs} +137 -19
  123. package/dist/chunk-LDYZWNJW.cjs +1654 -0
  124. package/dist/{chunk-ULMSSHCJ.cjs → chunk-LMB555QB.cjs} +405 -38
  125. package/dist/{chunk-CBJY23VL.js → chunk-MD4IVS42.js} +3 -3
  126. package/dist/{chunk-VMLKSV26.js → chunk-MDDWEBCX.js} +226 -3
  127. package/dist/chunk-MUWH4QK5.cjs +94 -0
  128. package/dist/{chunk-T6W3Z3SH.cjs → chunk-N2ILK7BF.cjs} +4 -4
  129. package/dist/{chunk-6EX3I5P4.cjs → chunk-N74QRJGP.cjs} +6 -6
  130. package/dist/chunk-NFFHLX37.cjs +132 -0
  131. package/dist/chunk-NJSYWX7H.js +190 -0
  132. package/dist/{chunk-SH5PPVK7.cjs → chunk-NQN5LFN4.cjs} +165 -221
  133. package/dist/chunk-NTQRFOPP.cjs +56 -0
  134. package/dist/{chunk-YFWRJW4B.js → chunk-NWMJPTVL.js} +51 -55
  135. package/dist/{chunk-63ZGNR2T.cjs → chunk-OC6GV5QH.cjs} +42 -42
  136. package/dist/{chunk-7E7GCQCK.js → chunk-OG3MBHM3.js} +9 -3
  137. package/dist/chunk-OMNHTCS4.cjs +264 -0
  138. package/dist/chunk-OQXB6NNC.cjs +117 -0
  139. package/dist/{chunk-Y57W2CT5.cjs → chunk-OV46CCA2.cjs} +51 -55
  140. package/dist/{chunk-6PRZIHGL.cjs → chunk-OV6HHKLE.cjs} +21 -266
  141. package/dist/{chunk-C37BHB7N.cjs → chunk-P26YYPOO.cjs} +5 -5
  142. package/dist/{chunk-2BZHWUSR.cjs → chunk-P7JEKJTZ.cjs} +16 -16
  143. package/dist/{chunk-NGBXXZLL.cjs → chunk-PDXX5UI4.cjs} +45 -45
  144. package/dist/{chunk-FHQFPYV4.js → chunk-PJFTTSKE.js} +8 -7
  145. package/dist/{chunk-GVFJ6T4S.cjs → chunk-PVODJEJ7.cjs} +721 -8
  146. package/dist/{chunk-ZZ7RO2UQ.js → chunk-Q265VZJ4.js} +3 -3
  147. package/dist/{chunk-E7JP3BS3.cjs → chunk-Q47JEE2C.cjs} +4 -4
  148. package/dist/chunk-QBY7LRN2.js +281 -0
  149. package/dist/{chunk-Z6PMDS4G.js → chunk-QDQWKSU3.js} +1090 -53
  150. package/dist/{chunk-GH6C2QGW.cjs → chunk-QEDMOGF3.cjs} +857 -16
  151. package/dist/{chunk-5WUNN6ZN.cjs → chunk-QHSAVOOL.cjs} +24 -2
  152. package/dist/chunk-QJNCDVYM.cjs +137 -0
  153. package/dist/chunk-QM7FJB5W.js +4717 -0
  154. package/dist/chunk-QQFB4RT2.cjs +448 -0
  155. package/dist/chunk-QSYBHQAD.cjs +196 -0
  156. package/dist/{chunk-UGXHYIWT.cjs → chunk-QUJ3ZB55.cjs} +28 -28
  157. package/dist/{chunk-2YSNA2F2.cjs → chunk-QVJMDVYZ.cjs} +5 -5
  158. package/dist/chunk-RAJMAX6D.js +131 -0
  159. package/dist/{chunk-VVKVQZI6.js → chunk-RAN3ECAS.js} +3 -3
  160. package/dist/chunk-RKGUZBOC.js +79 -0
  161. package/dist/{chunk-HLFDZ35S.cjs → chunk-RRQIAJLQ.cjs} +8 -8
  162. package/dist/{chunk-PABONWKI.js → chunk-RXQNRZ5F.js} +3 -3
  163. package/dist/{chunk-7ZHYEITD.cjs → chunk-S4O7CFHQ.cjs} +10 -11
  164. package/dist/chunk-SE7ANBGN.js +128 -0
  165. package/dist/{chunk-X2AVEAZM.cjs → chunk-SJIRCTIS.cjs} +176 -2
  166. package/dist/{chunk-WXQ57LAO.js → chunk-SQXAZHDG.js} +4 -4
  167. package/dist/chunk-SR73L5ZP.cjs +84 -0
  168. package/dist/{chunk-OABEO6HH.js → chunk-SZOLTWWD.js} +2349 -214
  169. package/dist/{chunk-5JEU52DW.js → chunk-TPZ3BN2D.js} +3 -3
  170. package/dist/{chunk-QFU53KRH.js → chunk-TSTFYGGX.js} +4 -5
  171. package/dist/{chunk-EBS32AJI.cjs → chunk-TZCFKZ6Z.cjs} +5 -5
  172. package/dist/chunk-UCVZXQ63.js +724 -0
  173. package/dist/chunk-UGQ3QNV6.js +992 -0
  174. package/dist/chunk-UNMVGZVW.js +142 -0
  175. package/dist/{chunk-TEVX443G.js → chunk-UTUD6GJI.js} +178 -6
  176. package/dist/chunk-UXBYA7DV.cjs +155 -0
  177. package/dist/chunk-V6GXFSK7.cjs +443 -0
  178. package/dist/chunk-VHORVGCG.cjs +761 -0
  179. package/dist/{chunk-B4EKV6HQ.js → chunk-VKCTYLDN.js} +500 -442
  180. package/dist/{chunk-O3MGZDCT.cjs → chunk-VTEXJOSD.cjs} +63 -63
  181. package/dist/chunk-VVAAZITA.cjs +287 -0
  182. package/dist/{chunk-V7AKE5VT.cjs → chunk-W2GA3EQB.cjs} +435 -42
  183. package/dist/chunk-W4GABFCR.js +37 -0
  184. package/dist/chunk-WKEK4NCA.js +490 -0
  185. package/dist/{chunk-5A4TCHOC.cjs → chunk-WNYXT4TE.cjs} +4 -4
  186. package/dist/{chunk-S762UEV5.js → chunk-WTH23ISI.js} +6 -6
  187. package/dist/{chunk-BTKZGHAV.js → chunk-WWNCM473.js} +10 -6
  188. package/dist/{chunk-7X5PNIQJ.js → chunk-X3YFRH6K.js} +27 -25
  189. package/dist/{chunk-4YNYPHH3.cjs → chunk-X75H75UY.cjs} +2351 -213
  190. package/dist/{chunk-LYJJI7ZK.cjs → chunk-XCUDDFKC.cjs} +216 -9
  191. package/dist/chunk-YAO4HPJL.cjs +120 -0
  192. package/dist/chunk-YKY2JBER.cjs +9443 -0
  193. package/dist/chunk-YP5CHEYU.cjs +154 -0
  194. package/dist/{chunk-WRNEH5MO.js → chunk-YW3I2FQL.js} +18 -7
  195. package/dist/{chunk-BRNUPDHJ.js → chunk-Z557DVYN.js} +386 -19
  196. package/dist/{chunk-VSACG2AR.js → chunk-Z6LZUYZF.js} +21 -264
  197. package/dist/chunk-ZHPMP447.cjs +43 -0
  198. package/dist/{chunk-LODTHGST.cjs → chunk-ZK7KX5CD.cjs} +133 -70
  199. package/dist/{chunk-CCPSNT6B.cjs → chunk-ZRPALBQB.cjs} +5 -5
  200. package/dist/chunk-ZVFHPMC5.js +824 -0
  201. package/dist/chunk-ZVQMKUGJ.js +443 -0
  202. package/dist/cli/holoscript-runner.cjs +86 -48
  203. package/dist/cli/holoscript-runner.js +54 -16
  204. package/dist/codebase/index.cjs +1 -1
  205. package/dist/codebase/index.js +1 -1
  206. package/dist/compiler/agent-inference.cjs +11 -11
  207. package/dist/compiler/agent-inference.js +9 -6
  208. package/dist/compiler/android-xr.cjs +13 -12
  209. package/dist/compiler/android-xr.js +11 -10
  210. package/dist/compiler/android.cjs +12 -12
  211. package/dist/compiler/android.js +10 -10
  212. package/dist/compiler/business-quest.cjs +10 -10
  213. package/dist/compiler/business-quest.js +2 -2
  214. package/dist/compiler/coco.cjs +1 -1
  215. package/dist/compiler/coco.js +1 -1
  216. package/dist/compiler/context.cjs +9 -9
  217. package/dist/compiler/context.js +6 -6
  218. package/dist/compiler/daimon-seed.cjs +36 -0
  219. package/dist/compiler/daimon-seed.js +12 -0
  220. package/dist/compiler/domain-block-utils.cjs +205 -156
  221. package/dist/compiler/domain-block-utils.js +8 -7
  222. package/dist/compiler/dtdl.cjs +10 -10
  223. package/dist/compiler/dtdl.js +7 -7
  224. package/dist/compiler/gltf-pipeline.cjs +9 -9
  225. package/dist/compiler/gltf-pipeline.js +2 -2
  226. package/dist/compiler/godot.cjs +10 -9
  227. package/dist/compiler/godot.js +9 -8
  228. package/dist/compiler/incremental.cjs +11 -11
  229. package/dist/compiler/incremental.js +6 -6
  230. package/dist/compiler/index.cjs +2585 -3273
  231. package/dist/compiler/index.d.ts +149 -35
  232. package/dist/compiler/index.js +2197 -3102
  233. package/dist/compiler/ios.cjs +11 -11
  234. package/dist/compiler/ios.js +9 -9
  235. package/dist/compiler/llm-provider-capabilities.cjs +9 -9
  236. package/dist/compiler/llm-provider-capabilities.js +6 -6
  237. package/dist/compiler/nodetoy.cjs +1 -1
  238. package/dist/compiler/nodetoy.js +1 -1
  239. package/dist/compiler/openxr.cjs +11 -10
  240. package/dist/compiler/openxr.js +10 -9
  241. package/dist/compiler/remotion.cjs +1 -1
  242. package/dist/compiler/remotion.js +1 -1
  243. package/dist/compiler/reproducibility.cjs +1 -1
  244. package/dist/compiler/reproducibility.js +1 -1
  245. package/dist/compiler/sdf.cjs +11 -10
  246. package/dist/compiler/sdf.js +9 -8
  247. package/dist/compiler/semantic-scene.cjs +7 -7
  248. package/dist/compiler/semantic-scene.js +2 -2
  249. package/dist/compiler/state.cjs +9 -9
  250. package/dist/compiler/state.js +7 -7
  251. package/dist/compiler/trait-composition.cjs +11 -11
  252. package/dist/compiler/trait-composition.js +7 -7
  253. package/dist/compiler/traits/ProvenanceSemiring.d.ts +167 -0
  254. package/dist/compiler/traits/Semiring.d.ts +26 -0
  255. package/dist/compiler/unity.cjs +11 -10
  256. package/dist/compiler/unity.js +10 -9
  257. package/dist/compiler/unreal.cjs +12 -11
  258. package/dist/compiler/unreal.js +10 -9
  259. package/dist/compiler/urdf.cjs +18 -17
  260. package/dist/compiler/urdf.js +9 -8
  261. package/dist/compiler/usd-physics.cjs +11 -10
  262. package/dist/compiler/usd-physics.js +8 -7
  263. package/dist/compiler/visionos.cjs +11 -10
  264. package/dist/compiler/visionos.js +10 -9
  265. package/dist/compiler/vrchat.cjs +11 -10
  266. package/dist/compiler/vrchat.js +9 -8
  267. package/dist/compiler/wasm.cjs +14 -13
  268. package/dist/compiler/wasm.js +9 -8
  269. package/dist/compiler/webgpu.cjs +10 -9
  270. package/dist/compiler/webgpu.js +9 -8
  271. package/dist/constants.cjs +398 -0
  272. package/dist/constants.js +9 -0
  273. package/dist/coordinators/index.cjs +4 -1
  274. package/dist/coordinators/index.js +4 -1
  275. package/dist/debugger.cjs +11 -9
  276. package/dist/debugger.js +9 -7
  277. package/dist/{dist-ACXG6IH5.cjs → dist-GRMOP2UL.cjs} +341 -65
  278. package/dist/{dist-VD4L6V7Q.js → dist-ZBUKU2JG.js} +333 -63
  279. package/dist/entries/interop.cjs +23 -23
  280. package/dist/entries/interop.js +3 -3
  281. package/dist/entries/scripting.cjs +12 -11
  282. package/dist/entries/scripting.js +8 -7
  283. package/dist/evolution/index.cjs +66 -0
  284. package/dist/evolution/index.d.ts +162 -0
  285. package/dist/evolution/index.js +17 -0
  286. package/dist/hololand/index.cjs +41 -37
  287. package/dist/hololand/index.js +3 -3
  288. package/dist/index.cjs +12394 -3224
  289. package/dist/index.d.ts +260 -18
  290. package/dist/index.js +10755 -2182
  291. package/dist/keyword-registry/PluginKeywordRegistry.d.ts +138 -0
  292. package/dist/keyword-registry/index.cjs +29 -0
  293. package/dist/keyword-registry/index.d.ts +1 -0
  294. package/dist/keyword-registry/index.js +4 -0
  295. package/dist/math/tropical-spmv.cjs +11 -11
  296. package/dist/math/tropical-spmv.d.ts +1 -0
  297. package/dist/math/tropical-spmv.js +2 -2
  298. package/dist/math/tropicalSpmv.d.ts +43 -0
  299. package/dist/math/vec3.cjs +1 -1
  300. package/dist/math/vec3.js +1 -1
  301. package/dist/matter/StagedMatter.d.ts +82 -0
  302. package/dist/matter/index.cjs +17 -0
  303. package/dist/matter/index.d.ts +1 -0
  304. package/dist/matter/index.js +4 -0
  305. package/dist/{ml-dsa-Z7JDKW4L.js → ml-dsa-J6VKVT4K.js} +3 -3
  306. package/dist/{ml-dsa-FSKBTE3W.cjs → ml-dsa-MTIK4ZUQ.cjs} +23 -23
  307. package/dist/paper-0c-spike/index.cjs +1 -1
  308. package/dist/paper-0c-spike/index.js +1 -1
  309. package/dist/parameter-envelope/ParameterEnvelope.d.ts +128 -0
  310. package/dist/parameter-envelope/index.cjs +17 -0
  311. package/dist/parameter-envelope/index.d.ts +2 -0
  312. package/dist/parameter-envelope/index.js +4 -0
  313. package/dist/parser/HoloCompositionTypes.d.ts +2013 -0
  314. package/dist/parser/PipelineParser.d.ts +162 -0
  315. package/dist/parser.cjs +36 -20
  316. package/dist/parser.js +13 -9
  317. package/dist/plugin-manifest/ManifestAutoLoader.d.ts +35 -0
  318. package/dist/plugin-manifest/PluginManifest.d.ts +156 -0
  319. package/dist/plugin-manifest/index.cjs +25 -0
  320. package/dist/plugin-manifest/index.d.ts +2 -0
  321. package/dist/plugin-manifest/index.js +4 -0
  322. package/dist/plugin-solver-contract/PluginSolverContract.d.ts +288 -0
  323. package/dist/plugin-solver-contract/index.cjs +41 -0
  324. package/dist/plugin-solver-contract/index.d.ts +1 -0
  325. package/dist/plugin-solver-contract/index.js +4 -0
  326. package/dist/policy/ContentPolicyGate.d.ts +51 -0
  327. package/dist/policy/PolicyPack.d.ts +120 -0
  328. package/dist/policy/blocklist.d.ts +32 -0
  329. package/dist/policy/defaults.d.ts +44 -0
  330. package/dist/policy/index.cjs +106 -0
  331. package/dist/policy/index.d.ts +17 -0
  332. package/dist/policy/index.js +5 -0
  333. package/dist/policy/jsonLogic.d.ts +31 -0
  334. package/dist/policy/types.d.ts +174 -0
  335. package/dist/proof-composition/ProofCompositionLaw.d.ts +93 -0
  336. package/dist/proof-composition/index.cjs +25 -0
  337. package/dist/proof-composition/index.d.ts +1 -0
  338. package/dist/proof-composition/index.js +4 -0
  339. package/dist/receipts/hash-policy.d.ts +85 -0
  340. package/dist/reconstruction/index.cjs +75 -47
  341. package/dist/reconstruction/index.js +5 -5
  342. package/dist/runtime/plugin-trait-registrar.d.ts +36 -0
  343. package/dist/runtime.cjs +81 -79
  344. package/dist/runtime.js +9 -7
  345. package/dist/scene-presets-EDKYZ5GW.js +4 -0
  346. package/dist/scene-presets-NCW2CFRS.cjs +17 -0
  347. package/dist/self-improvement/index.cjs +1 -1
  348. package/dist/self-improvement/index.js +1 -1
  349. package/dist/{src-PT2FERDV.cjs → src-G3D7ZATQ.cjs} +545 -21
  350. package/dist/{src-J6CM4AUR.js → src-UXYA7HM6.js} +539 -16
  351. package/dist/storage/index.cjs +10 -10
  352. package/dist/storage/index.js +3 -3
  353. package/dist/testing.cjs +1 -1
  354. package/dist/testing.js +1 -1
  355. package/dist/tools/index.cjs +3631 -0
  356. package/dist/tools/index.js +3581 -0
  357. package/dist/traitDocs/traitDocs.cjs +9 -9
  358. package/dist/traitDocs/traitDocs.d.ts +1 -0
  359. package/dist/traitDocs/traitDocs.js +3 -3
  360. package/dist/traits/ControlLoopTrait.d.ts +154 -0
  361. package/dist/traits/KinematicChainTrait.d.ts +116 -0
  362. package/dist/traits/SensorSamplingTrait.d.ts +154 -0
  363. package/dist/traits/TraitTypes.d.ts +270 -0
  364. package/dist/traits/TransactionTrait.d.ts +121 -0
  365. package/dist/traits/botanical-lotus.cjs +54 -50
  366. package/dist/traits/botanical-lotus.js +2 -5
  367. package/dist/traits/control-loop.cjs +21 -0
  368. package/dist/traits/control-loop.d.ts +1 -0
  369. package/dist/traits/control-loop.js +4 -0
  370. package/dist/traits/engines/cloth-verlet.d.ts +65 -0
  371. package/dist/traits/engines/index.cjs +19 -19
  372. package/dist/traits/engines/index.d.ts +15 -275
  373. package/dist/traits/engines/index.js +3 -3
  374. package/dist/traits/engines/motion-data-schema.d.ts +119 -0
  375. package/dist/traits/engines/motion-matching.d.ts +102 -0
  376. package/dist/traits/engines/noise.d.ts +25 -0
  377. package/dist/traits/engines/onnx-adapter.d.ts +173 -0
  378. package/dist/traits/engines/onnx-motion-matching.d.ts +163 -0
  379. package/dist/traits/engines/pfnn-network.d.ts +92 -0
  380. package/dist/traits/engines/synthetic-walk-cycle.d.ts +38 -0
  381. package/dist/traits/engines/tensor-ops.d.ts +15 -0
  382. package/dist/traits/index.cjs +2789 -1259
  383. package/dist/traits/index.d.ts +35 -0
  384. package/dist/traits/index.js +1692 -411
  385. package/dist/traits/kinematic-chain.cjs +25 -0
  386. package/dist/traits/kinematic-chain.d.ts +1 -0
  387. package/dist/traits/kinematic-chain.js +4 -0
  388. package/dist/traits/sensor-sampling.cjs +33 -0
  389. package/dist/traits/sensor-sampling.d.ts +1 -0
  390. package/dist/traits/sensor-sampling.js +4 -0
  391. package/dist/traits/simulation-solver-factory.cjs +1 -1
  392. package/dist/traits/simulation-solver-factory.js +1 -1
  393. package/dist/traits/transaction.cjs +29 -0
  394. package/dist/traits/transaction.d.ts +1 -0
  395. package/dist/traits/transaction.js +4 -0
  396. package/dist/traits/webcam-gaze.cjs +1 -1
  397. package/dist/traits/webcam-gaze.js +1 -1
  398. package/dist/type-checker.cjs +7 -6
  399. package/dist/type-checker.js +5 -4
  400. package/dist/types/AdvancedTypeSystem.d.ts +489 -0
  401. package/dist/types/HoloScriptPlus.d.ts +810 -0
  402. package/dist/types/base.d.ts +248 -0
  403. package/dist/types.d.ts +799 -0
  404. package/dist/world/index.cjs +3 -4
  405. package/dist/world/index.js +3 -4
  406. package/dist/world-model/index.cjs +1 -1
  407. package/dist/world-model/index.js +1 -1
  408. package/dist/wot/index.cjs +1 -1
  409. package/dist/wot/index.js +1 -1
  410. package/package.json +80 -13
  411. package/dist/GLTFPipeline-3EJLL3TS.cjs +0 -38
  412. package/dist/GLTFPipeline-3OWJV2VK.js +0 -17
  413. package/dist/HoloScriptPlusParser-ADWRY5OS.cjs +0 -698
  414. package/dist/HoloScriptPlusParser-JLJDXHSC.js +0 -693
  415. package/dist/HoloScriptPlusParser-QCGFPWIL.cjs +0 -27
  416. package/dist/HoloScriptPlusParser-WENAFEFV.js +0 -10
  417. package/dist/HoloScriptRuntime-GGRVEU4T.cjs +0 -19
  418. package/dist/HoloScriptRuntime-GJK6VJPH.js +0 -10
  419. package/dist/chunk-22Q5A6RV.js +0 -979
  420. package/dist/chunk-4C57PR42.js +0 -468
  421. package/dist/chunk-4W5G5QVL.cjs +0 -847
  422. package/dist/chunk-5ET6L4NS.js +0 -487
  423. package/dist/chunk-C4GSLCHE.cjs +0 -7153
  424. package/dist/chunk-F2G6CWFT.js +0 -7089
  425. package/dist/chunk-G6PNEASF.cjs +0 -814
  426. package/dist/chunk-GTA4Q3A3.js +0 -1491
  427. package/dist/chunk-HCCQLAA4.cjs +0 -74
  428. package/dist/chunk-HFSVMKM3.cjs +0 -72
  429. package/dist/chunk-KAIVDEIG.cjs +0 -4539
  430. package/dist/chunk-KQU64CIX.cjs +0 -1508
  431. package/dist/chunk-MSYSQ2AJ.js +0 -4533
  432. package/dist/chunk-NHJLP37F.js +0 -70
  433. package/dist/chunk-NHYRRAGI.cjs +0 -490
  434. package/dist/chunk-OIQYIIO3.cjs +0 -473
  435. package/dist/chunk-OL46QLBJ.js +0 -61
  436. package/dist/chunk-SKZPC5AG.cjs +0 -984
  437. package/dist/chunk-SLHLXUMO.js +0 -445
  438. package/dist/chunk-UOIGFQXC.cjs +0 -9750
  439. package/dist/chunk-UOL6Y5TD.cjs +0 -759
  440. package/dist/chunk-UVFI7XIR.cjs +0 -452
  441. package/dist/chunk-VEPGBETF.js +0 -844
  442. package/dist/chunk-XQ5MWMP2.js +0 -756
  443. package/dist/chunk-XT6JY5W5.js +0 -9684
  444. package/dist/chunk-YRRAUB35.js +0 -811
  445. package/dist/compiler/GasOptimizationAnalyzer.d.ts +0 -73
  446. package/dist/compiler/NFTMarketplaceCompiler.d.ts +0 -23
  447. package/dist/compiler/ar.cjs +0 -23
  448. package/dist/compiler/ar.js +0 -11
  449. package/dist/compiler/babylon.cjs +0 -21
  450. package/dist/compiler/babylon.js +0 -15
  451. package/dist/compiler/multi-layer.cjs +0 -24
  452. package/dist/compiler/multi-layer.js +0 -15
  453. package/dist/compiler/playcanvas.cjs +0 -19
  454. package/dist/compiler/playcanvas.js +0 -13
  455. package/dist/compiler/r3f.cjs +0 -39
  456. package/dist/compiler/r3f.d.ts +0 -22
  457. package/dist/compiler/r3f.js +0 -17
  458. package/dist/compiler/vrr.cjs +0 -24
  459. package/dist/compiler/vrr.js +0 -12
  460. package/dist/parser/NFTMarketplaceTypes.d.ts +0 -191
  461. package/dist/playwright-3AT3AKTV.cjs +0 -98673
  462. package/dist/playwright-VZPDVUEQ.js +0 -98660
@@ -1,1015 +1,1014 @@
1
1
  'use strict';
2
2
 
3
- var chunkFEWUHQNM_cjs = require('./chunk-FEWUHQNM.cjs');
4
- var chunkLODTHGST_cjs = require('./chunk-LODTHGST.cjs');
5
- var chunkDTGBOSEM_cjs = require('./chunk-DTGBOSEM.cjs');
6
- var chunk6EX3I5P4_cjs = require('./chunk-6EX3I5P4.cjs');
7
- var chunkHCCQLAA4_cjs = require('./chunk-HCCQLAA4.cjs');
3
+ var chunkCFVK26P4_cjs = require('./chunk-CFVK26P4.cjs');
4
+ var chunkZK7KX5CD_cjs = require('./chunk-ZK7KX5CD.cjs');
5
+ var chunkAWXFEAQL_cjs = require('./chunk-AWXFEAQL.cjs');
6
+ var chunkN74QRJGP_cjs = require('./chunk-N74QRJGP.cjs');
7
+ var chunkZHPMP447_cjs = require('./chunk-ZHPMP447.cjs');
8
8
  var ans = require('@holoscript/core-types/ans');
9
9
 
10
- // src/compiler/AndroidFeatureGenerators.ts
11
- function hasGeoTraits(composition) {
12
- const geoTraitNames = [
13
- "geo_anchor",
14
- "geo_persist",
15
- "geo_radius",
16
- "geo_compass_heading",
17
- "geo_altitude",
18
- "geo_cloud_anchor",
19
- "geo_terrain_snap",
20
- "geo_session_continuity",
21
- "geo_proximity_trigger",
22
- "geo_discoverable",
23
- "geo_arcore_geospatial",
24
- "geo_arkit_geo_anchor",
25
- // ARCore Geospatial API traits (M.010.15)
26
- "geospatial_vps",
27
- "geospatial_anchor",
28
- "geospatial_terrain_anchor",
29
- "geospatial_rooftop_anchor",
30
- "geospatial_streetscape",
31
- "geospatial_heading"
32
- ];
33
- for (const obj of composition.objects || []) {
34
- for (const trait of obj.traits || []) {
35
- const name = typeof trait === "string" ? trait : trait.name;
36
- if (geoTraitNames.includes(name)) return true;
10
+ // src/compiler/AndroidSceneViewFeatureGenerators.ts
11
+ function objectsOf(composition) {
12
+ return composition.objects ?? [];
13
+ }
14
+ function traitsOf(obj) {
15
+ return obj.traits ?? [];
16
+ }
17
+ function traitName(trait) {
18
+ return typeof trait === "string" ? trait : trait.name ?? "";
19
+ }
20
+ function traitConfig(trait) {
21
+ if (!trait || typeof trait === "string") return {};
22
+ return trait.config ?? trait.params ?? {};
23
+ }
24
+ function findTrait(obj, name) {
25
+ return traitsOf(obj).find((trait) => traitName(trait) === name);
26
+ }
27
+ function hasAnyTrait(composition, names) {
28
+ return objectsOf(composition).some(
29
+ (obj) => traitsOf(obj).some((trait) => names.includes(traitName(trait)))
30
+ );
31
+ }
32
+ function collectUsedTraits(composition, names) {
33
+ const used = /* @__PURE__ */ new Set();
34
+ for (const obj of objectsOf(composition)) {
35
+ for (const trait of traitsOf(obj)) {
36
+ const name = traitName(trait);
37
+ if (names.includes(name)) used.add(name);
37
38
  }
38
39
  }
39
- return false;
40
+ return [...used].sort();
40
41
  }
41
- function hasGeospatialVPSTraits(composition) {
42
- const geospatialTraitNames = [
43
- "geospatial_vps",
44
- "geospatial_anchor",
45
- "geospatial_terrain_anchor",
46
- "geospatial_rooftop_anchor",
47
- "geospatial_streetscape",
48
- "geospatial_heading"
49
- ];
50
- for (const obj of composition.objects || []) {
51
- for (const trait of obj.traits || []) {
52
- const name = typeof trait === "string" ? trait : trait.name;
53
- if (geospatialTraitNames.includes(name)) return true;
54
- }
42
+ function numberConfig(config, keys, fallback) {
43
+ for (const key of keys) {
44
+ const raw = config[key];
45
+ const numeric = typeof raw === "number" ? raw : Number(raw);
46
+ if (Number.isFinite(numeric)) return numeric;
55
47
  }
56
- return false;
48
+ return fallback;
49
+ }
50
+ function floatLiteral(value) {
51
+ return `${Number.isInteger(value) ? value.toFixed(0) : value}f`;
52
+ }
53
+ function quotedKotlin(compiler, value) {
54
+ return `"${compiler.escapeStringValue(String(value), "Kotlin")}"`;
55
+ }
56
+ function emitHeader(compiler, composition, title, requirements) {
57
+ compiler.lines = [];
58
+ compiler.indentLevel = 0;
59
+ compiler.emit(`// Auto-generated by HoloScript AndroidCompiler - ${title}`);
60
+ compiler.emit(
61
+ `// Source: composition "${compiler.escapeStringValue(String(composition.name), "Kotlin")}"`
62
+ );
63
+ for (const requirement of requirements) {
64
+ compiler.emit(`// Requires ${requirement}`);
65
+ }
66
+ compiler.emit("// SceneView-native sidecar generated without legacy fragment or node factories.");
67
+ compiler.emit("");
68
+ compiler.emit(`package ${compiler.options.packageName}`);
69
+ compiler.emit("");
70
+ }
71
+ function finish(compiler) {
72
+ return `${compiler.lines.join("\n")}
73
+ `;
74
+ }
75
+ function emitUsedTraits(compiler, used) {
76
+ if (used.length === 0) {
77
+ compiler.emit("private val usedTraits = emptySet<String>()");
78
+ return;
79
+ }
80
+ compiler.emit(`private val usedTraits = setOf(${used.map((trait) => `"${trait}"`).join(", ")})`);
81
+ }
82
+ function hasGeoAnchorTraits(composition) {
83
+ return hasAnyTrait(composition, GEO_ANCHOR_TRAITS);
84
+ }
85
+ function hasGeoTraits(composition) {
86
+ return hasGeoAnchorTraits(composition) || hasGeospatialVPSTraits(composition);
87
+ }
88
+ function hasGeospatialVPSTraits(composition) {
89
+ return hasAnyTrait(composition, GEOSPATIAL_TRAITS);
90
+ }
91
+ function hasDepthScanTraits(composition) {
92
+ return hasAnyTrait(composition, chunkAWXFEAQL_cjs.DEPTH_SCANNER_TRAITS);
93
+ }
94
+ function hasPortalARTraits(composition) {
95
+ return hasAnyTrait(composition, chunkN74QRJGP_cjs.PORTAL_AR_TRAITS);
96
+ }
97
+ function hasHandTrackingTraits(composition) {
98
+ return hasAnyTrait(composition, chunkN74QRJGP_cjs.CAMERA_HAND_TRACKING_TRAITS);
57
99
  }
58
100
  function emitGeoAnchorSetup(compiler, composition) {
101
+ emitHeader(compiler, composition, "SceneView Geo-Anchor Setup", [
102
+ "ARCore Earth anchors",
103
+ "Google Play Services location"
104
+ ]);
105
+ compiler.emit("import android.content.Context");
106
+ compiler.emit("import android.util.Log");
107
+ compiler.emit("import com.google.ar.core.Anchor");
108
+ compiler.emit("import com.google.ar.core.Config");
109
+ compiler.emit("import com.google.ar.core.Earth");
110
+ compiler.emit("import com.google.ar.core.Session");
111
+ compiler.emit("import com.google.ar.core.TrackingState");
59
112
  compiler.emit("");
60
- compiler.emit("// === Geo-Anchor: GPS-pinned persistent holograms ===");
61
113
  compiler.emit(
62
- "private var fusedLocationClient: com.google.android.gms.location.FusedLocationProviderClient? = null"
114
+ `class ${compiler.options.className}GeoAnchorManager(private val context: Context) {`
63
115
  );
116
+ compiler.indentLevel++;
117
+ emitUsedTraits(compiler, collectUsedTraits(composition, GEO_ANCHOR_TRAITS));
64
118
  compiler.emit("private val geoAnchors = mutableMapOf<String, Anchor>()");
119
+ compiler.emit("private val requestedAnchors = listOf(");
120
+ compiler.indentLevel++;
121
+ const anchors = objectsOf(composition).filter((obj) => findTrait(obj, "geo_anchor"));
122
+ if (anchors.length === 0) {
123
+ compiler.emit("// No explicit geo_anchor objects; call createGeoAnchor at runtime.");
124
+ }
125
+ anchors.forEach((obj, index) => {
126
+ const geoConfig = traitConfig(findTrait(obj, "geo_anchor"));
127
+ const altitudeConfig = traitConfig(findTrait(obj, "geo_altitude"));
128
+ const headingConfig = traitConfig(findTrait(obj, "geo_compass_heading"));
129
+ const lat = numberConfig(geoConfig, ["latitude", "lat"], 0);
130
+ const lng = numberConfig(geoConfig, ["longitude", "lng"], 0);
131
+ const altitude = numberConfig(altitudeConfig, ["meters", "altitude"], 0);
132
+ const heading = numberConfig(headingConfig, ["degrees", "heading"], 0);
133
+ compiler.emit(
134
+ `SceneViewGeoAnchor(${quotedKotlin(compiler, obj.name)}, ${lat}, ${lng}, ${altitude}, ${floatLiteral(
135
+ heading
136
+ )})${index === anchors.length - 1 ? "" : ","}`
137
+ );
138
+ });
139
+ compiler.indentLevel--;
140
+ compiler.emit(")");
65
141
  compiler.emit("");
66
- compiler.emit("private fun setupGeoAnchors() {");
142
+ compiler.emit("fun setupGeoAnchors(session: Session, earth: Earth?) {");
143
+ compiler.indentLevel++;
144
+ compiler.emit("configureSessionForGeospatial(session)");
145
+ compiler.emit("val earthRef = earth ?: return");
146
+ compiler.emit("for (anchor in requestedAnchors) {");
67
147
  compiler.indentLevel++;
68
148
  compiler.emit(
69
- "fusedLocationClient = com.google.android.gms.location.LocationServices.getFusedLocationProviderClient(this)"
149
+ "createGeoAnchor(anchor.name, earthRef, anchor.latitude, anchor.longitude, anchor.altitude, anchor.heading)"
70
150
  );
71
- compiler.emit("");
72
- const usesGeospatial = compiler.compositionHasTrait(composition, "geo_arcore_geospatial");
73
- if (usesGeospatial) {
74
- compiler.emit("// Enable ARCore Geospatial API (VPS)");
75
- compiler.emit("val session = arFragment.arSceneView.session ?: return");
76
- compiler.emit("val config = session.config");
77
- compiler.emit("config.geospatialMode = Config.GeospatialMode.ENABLED");
78
- compiler.emit("session.configure(config)");
79
- compiler.emit("");
80
- }
81
- for (const obj of composition.objects || []) {
82
- const traits = obj.traits || [];
83
- const hasGeoAnchor = traits.some((t) => {
84
- const name = typeof t === "string" ? t : t.name;
85
- return name === "geo_anchor";
86
- });
87
- if (!hasGeoAnchor) continue;
88
- const geoAnchorTrait = traits.find((t) => {
89
- const name = typeof t === "string" ? t : t.name;
90
- return name === "geo_anchor";
91
- });
92
- const config = typeof geoAnchorTrait === "string" ? {} : geoAnchorTrait?.config || {};
93
- const lat = config.latitude ?? 0;
94
- const lng = config.longitude ?? 0;
95
- const altTrait = traits.find((t) => {
96
- const name = typeof t === "string" ? t : t.name;
97
- return name === "geo_altitude";
98
- });
99
- const altConfig = typeof altTrait === "string" ? {} : altTrait?.config || {};
100
- const alt = altConfig.meters ?? 0;
101
- const headingTrait = traits.find((t) => {
102
- const name = typeof t === "string" ? t : t.name;
103
- return name === "geo_compass_heading";
104
- });
105
- const headingConfig = typeof headingTrait === "string" ? {} : headingTrait?.config || {};
106
- const heading = headingConfig.degrees ?? 0;
107
- compiler.emit(`// Geo-anchor: ${compiler.escapeStringValue(obj.name, "Kotlin")}`);
108
- compiler.emit(
109
- `createGeoAnchor("${compiler.escapeStringValue(obj.name, "Kotlin")}", ${lat}, ${lng}, ${alt}, ${heading}f)`
110
- );
111
- }
112
- const usesPersist = compiler.compositionHasTrait(composition, "geo_persist");
113
- const usesCloud = compiler.compositionHasTrait(composition, "geo_cloud_anchor");
114
- if (usesPersist || usesCloud) {
115
- compiler.emit("");
116
- compiler.emit("// Restore persisted geo anchors");
117
- compiler.emit("restoreGeoAnchors()");
151
+ compiler.indentLevel--;
152
+ compiler.emit("}");
153
+ if (compiler.compositionHasTrait(composition, "geo_persist")) {
154
+ compiler.emit("restoreGeoAnchors { name, restored -> geoAnchors[name] = restored }");
118
155
  }
119
156
  compiler.indentLevel--;
120
157
  compiler.emit("}");
121
158
  compiler.emit("");
159
+ compiler.emit("fun configureSessionForGeospatial(session: Session) {");
160
+ compiler.indentLevel++;
161
+ compiler.emit("val config = session.config");
162
+ compiler.emit("config.geospatialMode = Config.GeospatialMode.ENABLED");
163
+ compiler.emit("session.configure(config)");
164
+ compiler.indentLevel--;
165
+ compiler.emit("}");
166
+ compiler.emit("");
122
167
  compiler.emit(
123
- "private fun createGeoAnchor(name: String, lat: Double, lng: Double, alt: Double, heading: Float) {"
168
+ "fun createGeoAnchor(name: String, earth: Earth, latitude: Double, longitude: Double, altitude: Double, heading: Float): Anchor? {"
124
169
  );
125
170
  compiler.indentLevel++;
126
- compiler.emit("val session = arFragment.arSceneView.session ?: return");
127
- compiler.emit("val earth = session.earth ?: return");
128
- compiler.emit("if (earth.trackingState != TrackingState.TRACKING) return");
129
- compiler.emit("");
171
+ compiler.emit("if (earth.trackingState != TrackingState.TRACKING) return null");
172
+ compiler.emit("val halfRadians = Math.toRadians(heading.toDouble()) / 2.0");
130
173
  compiler.emit(
131
- "val anchor = earth.createAnchor(lat, lng, alt, 0f, 0f, Math.sin(Math.toRadians(heading.toDouble() / 2)).toFloat(), Math.cos(Math.toRadians(heading.toDouble() / 2)).toFloat())"
174
+ "val anchor = earth.createAnchor(latitude, longitude, altitude, 0f, 0f, Math.sin(halfRadians).toFloat(), Math.cos(halfRadians).toFloat())"
132
175
  );
133
176
  compiler.emit("geoAnchors[name] = anchor");
177
+ compiler.emit('Log.d("HoloScript", "SceneView geo anchor created: " + name)');
178
+ if (compiler.compositionHasTrait(composition, "geo_cloud_anchor") || compiler.compositionHasTrait(composition, "geo_persist")) {
179
+ compiler.emit('saveGeoAnchorToCloud(name, anchor.cloudAnchorId ?: "")');
180
+ }
181
+ compiler.emit("return anchor");
182
+ compiler.indentLevel--;
183
+ compiler.emit("}");
134
184
  compiler.emit("");
135
- compiler.emit("val anchorNode = AnchorNode(anchor)");
136
- compiler.emit("anchorNode.setParent(arFragment.arSceneView.scene)");
137
- compiler.emit("");
138
- compiler.emit("NodeFactory.createDefaultNode(this) { renderable ->");
185
+ compiler.emit("fun saveGeoAnchorToCloud(name: String, cloudAnchorId: String) {");
139
186
  compiler.indentLevel++;
140
- compiler.emit("val node = TransformableNode(arFragment.transformationSystem)");
141
- compiler.emit("node.setParent(anchorNode)");
142
- compiler.emit("node.renderable = renderable");
143
- compiler.emit("placedNodes[name] = node");
144
- compiler.emit('android.util.Log.d("HoloScript", "Geo-anchored: $name at ($lat, $lng, $alt)")');
187
+ compiler.emit(
188
+ 'context.getSharedPreferences("sceneview_geo_anchors", Context.MODE_PRIVATE).edit().putString(name, cloudAnchorId).apply()'
189
+ );
145
190
  compiler.indentLevel--;
146
191
  compiler.emit("}");
192
+ compiler.emit("");
193
+ compiler.emit("fun restoreGeoAnchors(onRestore: (String, Anchor) -> Unit) {");
194
+ compiler.indentLevel++;
195
+ compiler.emit(
196
+ "// Cloud anchor resolution is provided by the app shell when network policy is available."
197
+ );
198
+ compiler.emit(
199
+ 'Log.d("HoloScript", "restoreGeoAnchors requested for " + usedTraits.joinToString())'
200
+ );
147
201
  compiler.indentLevel--;
148
202
  compiler.emit("}");
149
203
  compiler.emit("");
150
- if (usesPersist || usesCloud) {
151
- compiler.emit("private fun saveGeoAnchorToCloud(name: String, anchor: Anchor) {");
152
- compiler.indentLevel++;
153
- compiler.emit("val session = arFragment.arSceneView.session ?: return");
154
- compiler.emit("session.hostCloudAnchorAsync(anchor, 365) { cloudId, state ->");
155
- compiler.indentLevel++;
156
- compiler.emit("if (state == Anchor.CloudAnchorState.SUCCESS && cloudId != null) {");
157
- compiler.indentLevel++;
158
- compiler.emit('val prefs = getSharedPreferences("geo_anchors", MODE_PRIVATE)');
159
- compiler.emit("prefs.edit().putString(name, cloudId).apply()");
160
- compiler.emit('android.util.Log.d("HoloScript", "Cloud anchor saved: $name -> $cloudId")');
161
- compiler.indentLevel--;
162
- compiler.emit("}");
163
- compiler.indentLevel--;
164
- compiler.emit("}");
165
- compiler.indentLevel--;
166
- compiler.emit("}");
167
- compiler.emit("");
168
- compiler.emit("private fun restoreGeoAnchors() {");
169
- compiler.indentLevel++;
170
- compiler.emit('val prefs = getSharedPreferences("geo_anchors", MODE_PRIVATE)');
171
- compiler.emit("val session = arFragment.arSceneView.session ?: return");
172
- compiler.emit("for ((name, cloudId) in prefs.all) {");
173
- compiler.indentLevel++;
174
- compiler.emit("val id = cloudId as? String ?: continue");
175
- compiler.emit("session.resolveCloudAnchorAsync(id) { anchor, state ->");
176
- compiler.indentLevel++;
177
- compiler.emit("if (state == Anchor.CloudAnchorState.SUCCESS && anchor != null) {");
178
- compiler.indentLevel++;
179
- compiler.emit("geoAnchors[name] = anchor");
180
- compiler.emit("val anchorNode = AnchorNode(anchor)");
181
- compiler.emit("anchorNode.setParent(arFragment.arSceneView.scene)");
182
- compiler.emit('android.util.Log.d("HoloScript", "Restored cloud anchor: $name")');
183
- compiler.indentLevel--;
184
- compiler.emit("}");
185
- compiler.indentLevel--;
186
- compiler.emit("}");
187
- compiler.indentLevel--;
188
- compiler.emit("}");
189
- compiler.indentLevel--;
190
- compiler.emit("}");
191
- compiler.emit("");
192
- }
204
+ compiler.emit(
205
+ "data class SceneViewGeoAnchor(val name: String, val latitude: Double, val longitude: Double, val altitude: Double, val heading: Float)"
206
+ );
207
+ compiler.indentLevel--;
208
+ compiler.emit("}");
209
+ return finish(compiler);
193
210
  }
194
211
  function emitGeospatialVPSSetup(compiler, composition) {
212
+ emitHeader(compiler, composition, "SceneView Geospatial VPS Setup", [
213
+ "ARCore GeospatialMode",
214
+ "Google Play Services location"
215
+ ]);
216
+ compiler.emit("import android.util.Log");
217
+ compiler.emit("import com.google.ar.core.Anchor");
218
+ compiler.emit("import com.google.ar.core.Config");
219
+ compiler.emit("import com.google.ar.core.Earth");
220
+ compiler.emit("import com.google.ar.core.Session");
221
+ compiler.emit("import com.google.ar.core.StreetscapeGeometry");
222
+ compiler.emit("import com.google.ar.core.TrackingState");
195
223
  compiler.emit("");
196
- compiler.emit("// === ARCore Geospatial API: VPS street-level geo-anchoring ===");
224
+ compiler.emit(`class ${compiler.options.className}GeospatialVPSManager {`);
225
+ compiler.indentLevel++;
226
+ emitUsedTraits(compiler, collectUsedTraits(composition, GEOSPATIAL_TRAITS));
197
227
  compiler.emit("private var earth: Earth? = null");
198
228
  compiler.emit("private val geospatialAnchors = mutableMapOf<String, Anchor>()");
229
+ compiler.emit(
230
+ `private val horizontalAccuracyThreshold = ${chunkAWXFEAQL_cjs.GEOSPATIAL_DEFAULTS.vps.accuracyThreshold}.0`
231
+ );
232
+ compiler.emit(
233
+ `private val headingAccuracyThreshold = ${chunkAWXFEAQL_cjs.GEOSPATIAL_DEFAULTS.vps.headingAccuracyThreshold}.0`
234
+ );
199
235
  compiler.emit("");
200
- compiler.emit("private fun setupGeospatialVPS() {");
236
+ compiler.emit("fun setupGeospatialVPS(session: Session) {");
201
237
  compiler.indentLevel++;
202
- compiler.emit("val session = arFragment.arSceneView.session ?: return");
203
238
  compiler.emit("val config = session.config");
204
239
  compiler.emit("config.geospatialMode = Config.GeospatialMode.ENABLED");
205
- const usesStreetscape = compiler.compositionHasTrait(composition, "geospatial_streetscape");
206
- if (usesStreetscape) {
240
+ if (compiler.compositionHasTrait(composition, "geospatial_streetscape")) {
207
241
  compiler.emit("config.streetscapeGeometryMode = Config.StreetscapeGeometryMode.ENABLED");
208
242
  }
209
243
  compiler.emit("session.configure(config)");
244
+ compiler.emit("earth = session.earth");
245
+ compiler.indentLevel--;
246
+ compiler.emit("}");
210
247
  compiler.emit("");
211
- compiler.emit("// Monitor geospatial tracking state");
212
- compiler.emit("arFragment.arSceneView.scene.addOnUpdateListener {");
248
+ compiler.emit("fun updateEarthTracking(session: Session) {");
213
249
  compiler.indentLevel++;
214
- compiler.emit("val sessionRef = arFragment.arSceneView.session ?: return@addOnUpdateListener");
215
- compiler.emit("earth = sessionRef.earth");
216
- compiler.emit("val trackingState = earth?.trackingState ?: return@addOnUpdateListener");
217
- compiler.emit("if (trackingState != TrackingState.TRACKING) return@addOnUpdateListener");
218
- compiler.emit("");
219
- compiler.emit("val geospatialState = earth?.cameraGeospatialPose ?: return@addOnUpdateListener");
250
+ compiler.emit("earth = session.earth");
251
+ compiler.emit("val earthRef = earth ?: return");
252
+ compiler.emit("if (earthRef.trackingState != TrackingState.TRACKING) return");
253
+ compiler.emit("val geospatialState = earthRef.cameraGeospatialPose");
220
254
  compiler.emit("val horizontalAccuracy = geospatialState.horizontalAccuracy");
221
255
  compiler.emit("val headingAccuracy = geospatialState.headingAccuracy");
256
+ compiler.emit(
257
+ "if (horizontalAccuracy > horizontalAccuracyThreshold || headingAccuracy > headingAccuracyThreshold) return"
258
+ );
259
+ compiler.emit('Log.d("HoloScript", "cameraGeospatialPose localized")');
260
+ if (compiler.compositionHasTrait(composition, "geospatial_streetscape")) {
261
+ compiler.emit("processStreetscapeGeometry(session)");
262
+ }
263
+ compiler.indentLevel--;
264
+ compiler.emit("}");
222
265
  compiler.emit("");
223
266
  compiler.emit(
224
- `if (horizontalAccuracy > ${chunkDTGBOSEM_cjs.GEOSPATIAL_DEFAULTS.vps.accuracyThreshold} || headingAccuracy > ${chunkDTGBOSEM_cjs.GEOSPATIAL_DEFAULTS.vps.headingAccuracyThreshold}) {`
267
+ "fun createGeospatialAnchor(name: String, lat: Double, lng: Double, alt: Double, heading: Float): Anchor? {"
225
268
  );
226
269
  compiler.indentLevel++;
227
- compiler.emit("// Accuracy not yet sufficient for anchoring");
228
- compiler.emit("return@addOnUpdateListener");
270
+ compiler.emit("val earthRef = earth ?: return null");
271
+ compiler.emit("if (earthRef.trackingState != TrackingState.TRACKING) return null");
272
+ compiler.emit("val halfRadians = Math.toRadians(heading.toDouble()) / 2.0");
273
+ compiler.emit(
274
+ "val anchor = earthRef.createAnchor(lat, lng, alt, 0f, 0f, Math.sin(halfRadians).toFloat(), Math.cos(halfRadians).toFloat())"
275
+ );
276
+ compiler.emit("geospatialAnchors[name] = anchor");
277
+ compiler.emit("return anchor");
229
278
  compiler.indentLevel--;
230
279
  compiler.emit("}");
231
280
  compiler.emit("");
232
281
  compiler.emit(
233
- 'android.util.Log.d("HoloScript", "Geospatial tracking: accuracy=$horizontalAccuracy m, heading=$headingAccuracy deg")'
282
+ "fun resolveTerrainAnchor(name: String, lat: Double, lng: Double, altitudeOffset: Double, heading: Float) {"
283
+ );
284
+ compiler.indentLevel++;
285
+ compiler.emit("val earthRef = earth ?: return");
286
+ compiler.emit("val halfRadians = Math.toRadians(heading.toDouble()) / 2.0");
287
+ compiler.emit(
288
+ "earthRef.resolveAnchorOnTerrainAsync(lat, lng, altitudeOffset, 0f, Math.sin(halfRadians).toFloat(), 0f, Math.cos(halfRadians).toFloat()) { anchor, state ->"
289
+ );
290
+ compiler.indentLevel++;
291
+ compiler.emit(
292
+ "if (state == Anchor.TerrainAnchorState.SUCCESS && anchor != null) geospatialAnchors[name] = anchor"
234
293
  );
235
- if (usesStreetscape) {
236
- compiler.emit("");
237
- compiler.emit("// Process Streetscape Geometry meshes");
238
- compiler.emit("processStreetscapeGeometry(sessionRef)");
239
- }
240
294
  compiler.indentLevel--;
241
295
  compiler.emit("}");
242
296
  compiler.indentLevel--;
243
297
  compiler.emit("}");
244
298
  compiler.emit("");
245
299
  compiler.emit(
246
- "private fun createGeospatialAnchor(name: String, lat: Double, lng: Double, alt: Double, heading: Float) {"
300
+ "fun resolveRooftopAnchor(name: String, lat: Double, lng: Double, altitudeOffset: Double, heading: Float) {"
247
301
  );
248
302
  compiler.indentLevel++;
249
303
  compiler.emit("val earthRef = earth ?: return");
250
- compiler.emit("if (earthRef.trackingState != TrackingState.TRACKING) return");
251
- compiler.emit("");
304
+ compiler.emit("val halfRadians = Math.toRadians(heading.toDouble()) / 2.0");
252
305
  compiler.emit(
253
- "val anchor = earthRef.createAnchor(lat, lng, alt, 0f, 0f, Math.sin(Math.toRadians(heading.toDouble() / 2)).toFloat(), Math.cos(Math.toRadians(heading.toDouble() / 2)).toFloat())"
306
+ "earthRef.resolveAnchorOnRooftopAsync(lat, lng, altitudeOffset, 0f, Math.sin(halfRadians).toFloat(), 0f, Math.cos(halfRadians).toFloat()) { anchor, state ->"
254
307
  );
255
- compiler.emit("geospatialAnchors[name] = anchor");
256
- compiler.emit("");
257
- compiler.emit("val anchorNode = AnchorNode(anchor)");
258
- compiler.emit("anchorNode.setParent(arFragment.arSceneView.scene)");
259
- compiler.emit("");
260
- compiler.emit("NodeFactory.createDefaultNode(this) { renderable ->");
261
308
  compiler.indentLevel++;
262
- compiler.emit("val node = TransformableNode(arFragment.transformationSystem)");
263
- compiler.emit("node.setParent(anchorNode)");
264
- compiler.emit("node.renderable = renderable");
265
- compiler.emit("placedNodes[name] = node");
266
309
  compiler.emit(
267
- 'android.util.Log.d("HoloScript", "Geospatial anchor: $name at ($lat, $lng, $alt)")'
310
+ "if (state == Anchor.RooftopAnchorState.SUCCESS && anchor != null) geospatialAnchors[name] = anchor"
268
311
  );
269
312
  compiler.indentLevel--;
270
313
  compiler.emit("}");
271
314
  compiler.indentLevel--;
272
315
  compiler.emit("}");
273
316
  compiler.emit("");
274
- if (compiler.compositionHasTrait(composition, "geospatial_terrain_anchor")) {
275
- compiler.emit(
276
- "private fun resolveTerrainAnchor(name: String, lat: Double, lng: Double, altOffset: Double, heading: Float) {"
277
- );
278
- compiler.indentLevel++;
279
- compiler.emit("val earthRef = earth ?: return");
280
- compiler.emit("if (earthRef.trackingState != TrackingState.TRACKING) return");
281
- compiler.emit("");
282
- compiler.emit("val qx = 0f");
283
- compiler.emit("val qy = Math.sin(Math.toRadians(heading.toDouble() / 2)).toFloat()");
284
- compiler.emit("val qz = 0f");
285
- compiler.emit("val qw = Math.cos(Math.toRadians(heading.toDouble() / 2)).toFloat()");
286
- compiler.emit("");
287
- compiler.emit(
288
- "earthRef.resolveAnchorOnTerrainAsync(lat, lng, altOffset, qx, qy, qz, qw) { anchor, state ->"
289
- );
290
- compiler.indentLevel++;
291
- compiler.emit("if (state == Anchor.TerrainAnchorState.SUCCESS && anchor != null) {");
292
- compiler.indentLevel++;
293
- compiler.emit("geospatialAnchors[name] = anchor");
294
- compiler.emit("val anchorNode = AnchorNode(anchor)");
295
- compiler.emit("anchorNode.setParent(arFragment.arSceneView.scene)");
296
- compiler.emit("");
297
- compiler.emit(
298
- "NodeFactory.createDefaultNode(this@" + compiler.options.className + "Activity) { renderable ->"
299
- );
300
- compiler.indentLevel++;
301
- compiler.emit("val node = TransformableNode(arFragment.transformationSystem)");
302
- compiler.emit("node.setParent(anchorNode)");
303
- compiler.emit("node.renderable = renderable");
304
- compiler.emit("placedNodes[name] = node");
305
- compiler.emit('android.util.Log.d("HoloScript", "Terrain anchor resolved: $name")');
306
- compiler.indentLevel--;
307
- compiler.emit("}");
308
- compiler.indentLevel--;
309
- compiler.emit("}");
310
- compiler.indentLevel--;
311
- compiler.emit("}");
312
- compiler.indentLevel--;
313
- compiler.emit("}");
314
- compiler.emit("");
315
- }
316
- if (compiler.compositionHasTrait(composition, "geospatial_rooftop_anchor")) {
317
- compiler.emit(
318
- "private fun resolveRooftopAnchor(name: String, lat: Double, lng: Double, altOffset: Double, heading: Float) {"
319
- );
320
- compiler.indentLevel++;
321
- compiler.emit("val earthRef = earth ?: return");
322
- compiler.emit("if (earthRef.trackingState != TrackingState.TRACKING) return");
323
- compiler.emit("");
324
- compiler.emit("val qx = 0f");
325
- compiler.emit("val qy = Math.sin(Math.toRadians(heading.toDouble() / 2)).toFloat()");
326
- compiler.emit("val qz = 0f");
327
- compiler.emit("val qw = Math.cos(Math.toRadians(heading.toDouble() / 2)).toFloat()");
328
- compiler.emit("");
329
- compiler.emit(
330
- "earthRef.resolveAnchorOnRooftopAsync(lat, lng, altOffset, qx, qy, qz, qw) { anchor, state ->"
331
- );
332
- compiler.indentLevel++;
333
- compiler.emit("if (state == Anchor.RooftopAnchorState.SUCCESS && anchor != null) {");
334
- compiler.indentLevel++;
335
- compiler.emit("geospatialAnchors[name] = anchor");
336
- compiler.emit("val anchorNode = AnchorNode(anchor)");
337
- compiler.emit("anchorNode.setParent(arFragment.arSceneView.scene)");
338
- compiler.emit("");
339
- compiler.emit(
340
- "NodeFactory.createDefaultNode(this@" + compiler.options.className + "Activity) { renderable ->"
341
- );
342
- compiler.indentLevel++;
343
- compiler.emit("val node = TransformableNode(arFragment.transformationSystem)");
344
- compiler.emit("node.setParent(anchorNode)");
345
- compiler.emit("node.renderable = renderable");
346
- compiler.emit("placedNodes[name] = node");
347
- compiler.emit('android.util.Log.d("HoloScript", "Rooftop anchor resolved: $name")');
348
- compiler.indentLevel--;
349
- compiler.emit("}");
350
- compiler.indentLevel--;
351
- compiler.emit("}");
352
- compiler.indentLevel--;
353
- compiler.emit("}");
354
- compiler.indentLevel--;
355
- compiler.emit("}");
356
- compiler.emit("");
357
- }
358
- if (usesStreetscape) {
359
- compiler.emit("private fun processStreetscapeGeometry(session: Session) {");
360
- compiler.indentLevel++;
361
- compiler.emit(
362
- "val streetscapeGeometries = session.getAllTrackables(StreetscapeGeometry::class.java)"
363
- );
364
- compiler.emit("for (geometry in streetscapeGeometries) {");
365
- compiler.indentLevel++;
366
- compiler.emit("if (geometry.trackingState != TrackingState.TRACKING) continue");
367
- compiler.emit("");
368
- compiler.emit("val mesh = geometry.meshes.firstOrNull() ?: continue");
369
- compiler.emit("val type = geometry.type");
370
- compiler.emit(
371
- 'android.util.Log.d("HoloScript", "Streetscape geometry: type=$type, vertices=${mesh.vertexList.size}")'
372
- );
373
- compiler.emit("");
374
- compiler.emit("// Streetscape mesh available for occlusion, raycasting, or rendering");
375
- compiler.emit("// Type is TERRAIN or BUILDING");
376
- compiler.indentLevel--;
377
- compiler.emit("}");
378
- compiler.indentLevel--;
379
- compiler.emit("}");
380
- compiler.emit("");
381
- }
382
- }
383
- function hasDepthScanTraits(composition) {
384
- for (const obj of composition.objects || []) {
385
- for (const trait of obj.traits || []) {
386
- const name = typeof trait === "string" ? trait : trait.name;
387
- if (chunkDTGBOSEM_cjs.DEPTH_SCANNER_TRAITS.includes(name)) return true;
388
- }
389
- }
390
- return false;
317
+ compiler.emit("fun processStreetscapeGeometry(session: Session) {");
318
+ compiler.indentLevel++;
319
+ compiler.emit("val geometries = session.getAllTrackables(StreetscapeGeometry::class.java)");
320
+ compiler.emit("for (geometry in geometries) {");
321
+ compiler.indentLevel++;
322
+ compiler.emit("if (geometry.trackingState != TrackingState.TRACKING) continue");
323
+ compiler.emit('Log.d("HoloScript", "Streetscape geometry: " + geometry.type)');
324
+ compiler.indentLevel--;
325
+ compiler.emit("}");
326
+ compiler.indentLevel--;
327
+ compiler.emit("}");
328
+ compiler.emit("");
329
+ compiler.emit(
330
+ "data class SceneViewGeospatialAnchor(val name: String, val latitude: Double, val longitude: Double, val altitude: Double, val heading: Float)"
331
+ );
332
+ compiler.indentLevel--;
333
+ compiler.emit("}");
334
+ return finish(compiler);
391
335
  }
392
336
  function emitDepthScanSetup(compiler, composition) {
393
- const hasMlArcore = compiler.compositionHasTrait(composition, "depth_ml_arcore");
394
- const hasConfidence = compiler.compositionHasTrait(composition, "depth_confidence_map");
395
- const hasAutoSelect = compiler.compositionHasTrait(composition, "depth_auto_select");
396
- const hasMeshGenerate = compiler.compositionHasTrait(composition, "depth_mesh_generate");
397
- const hasMeshToHolo = compiler.compositionHasTrait(composition, "depth_mesh_to_holo");
398
- const hasRealtime = compiler.compositionHasTrait(composition, "depth_realtime");
399
- const hasExport = compiler.compositionHasTrait(composition, "depth_export");
400
- compiler.emit("");
401
- compiler.emit("// === Depth Scanner: ARCore depth, ToF, stereo (M.010.02b) ===");
337
+ emitHeader(compiler, composition, "SceneView Depth Scanner Setup", ["ARCore Depth API"]);
338
+ compiler.emit("import android.media.Image");
339
+ compiler.emit("import android.util.Log");
340
+ compiler.emit("import com.google.ar.core.Config");
341
+ compiler.emit("import com.google.ar.core.Frame");
342
+ compiler.emit("import com.google.ar.core.Session");
343
+ compiler.emit("");
344
+ compiler.emit(`class ${compiler.options.className}DepthScanner {`);
345
+ compiler.indentLevel++;
346
+ emitUsedTraits(compiler, collectUsedTraits(composition, chunkAWXFEAQL_cjs.DEPTH_SCANNER_TRAITS));
402
347
  compiler.emit(
403
- `private val depthConfidenceThreshold = ${chunkDTGBOSEM_cjs.DEPTH_SCANNER_DEFAULTS.scan.confidenceThreshold}`
348
+ `private val depthConfidenceThreshold = ${chunkAWXFEAQL_cjs.DEPTH_SCANNER_DEFAULTS.scan.confidenceThreshold}`
349
+ );
350
+ compiler.emit(
351
+ `private val depthMaxMeters = ${floatLiteral(chunkAWXFEAQL_cjs.DEPTH_SCANNER_DEFAULTS.scan.maxDepthMeters)}`
352
+ );
353
+ compiler.emit(
354
+ `private val depthMeshDecimation = ${floatLiteral(chunkAWXFEAQL_cjs.DEPTH_SCANNER_DEFAULTS.scan.meshDecimation)}`
404
355
  );
405
- compiler.emit(`private val depthMaxMeters = ${chunkDTGBOSEM_cjs.DEPTH_SCANNER_DEFAULTS.scan.maxDepthMeters}f`);
406
- compiler.emit(`private val depthMeshDecimation = ${chunkDTGBOSEM_cjs.DEPTH_SCANNER_DEFAULTS.scan.meshDecimation}f`);
407
- compiler.emit("private var depthImage: android.media.Image? = null");
408
- if (hasConfidence) {
409
- compiler.emit("private var depthConfidenceImage: android.media.Image? = null");
410
- }
411
356
  compiler.emit("");
412
- compiler.emit("private fun setupDepthScanner() {");
357
+ compiler.emit("fun setupDepthScanner(session: Session) = configureDepthSession(session)");
358
+ compiler.emit("");
359
+ compiler.emit("fun configureDepthSession(session: Session) {");
413
360
  compiler.indentLevel++;
414
- compiler.emit("val session = arFragment.arSceneView.session ?: return");
415
- compiler.emit("val config = session.config");
416
361
  compiler.emit("if (!session.isDepthModeSupported(Config.DepthMode.AUTOMATIC)) {");
417
362
  compiler.indentLevel++;
418
- compiler.emit(
419
- 'android.util.Log.w("HoloScript", "Depth scanner unavailable: ARCore DepthMode.AUTOMATIC is not supported on this device")'
420
- );
363
+ compiler.emit('Log.w("HoloScript", "ARCore DepthMode.AUTOMATIC is unavailable")');
421
364
  compiler.emit("return");
422
365
  compiler.indentLevel--;
423
366
  compiler.emit("}");
367
+ compiler.emit("val config = session.config");
424
368
  compiler.emit("config.depthMode = Config.DepthMode.AUTOMATIC");
425
369
  compiler.emit("session.configure(config)");
426
- compiler.emit('android.util.Log.d("HoloScript", "Depth scanner: DepthMode.AUTOMATIC enabled")');
370
+ compiler.indentLevel--;
371
+ compiler.emit("}");
427
372
  compiler.emit("");
428
- if (hasAutoSelect) {
429
- compiler.emit("// Auto-select best depth source: ToF > ARCore ML > Stereo");
430
- compiler.emit("detectDepthSource()");
431
- compiler.emit("");
373
+ compiler.emit("fun processDepthFrame(frame: Frame): List<DepthPoint> {");
374
+ compiler.indentLevel++;
375
+ compiler.emit("val depthImage = frame.acquireDepthImage16Bits()");
376
+ compiler.emit("val confidenceImage = acquireConfidenceImage(frame)");
377
+ compiler.emit("val source = detectDepthSource()");
378
+ compiler.emit("val mesh = generateMeshFromDepth(depthImage, confidenceImage, source)");
379
+ if (compiler.compositionHasTrait(composition, "depth_mesh_to_holo")) {
380
+ compiler.emit("convertDepthMeshToHolo(mesh)");
432
381
  }
433
- if (hasRealtime) {
434
- compiler.emit("// Continuous depth frame processing in render loop");
435
- compiler.emit("arFragment.arSceneView.scene.addOnUpdateListener { _ ->");
436
- compiler.indentLevel++;
437
- compiler.emit("val frame = arFragment.arSceneView.arFrame ?: return@addOnUpdateListener");
438
- compiler.emit("processDepthFrame(frame)");
439
- compiler.indentLevel--;
440
- compiler.emit("}");
382
+ if (compiler.compositionHasTrait(composition, "depth_export")) {
383
+ compiler.emit("exportDepthMesh(mesh)");
441
384
  }
385
+ compiler.emit("depthImage.close()");
386
+ compiler.emit("confidenceImage?.close()");
387
+ compiler.emit("return mesh");
442
388
  compiler.indentLevel--;
443
389
  compiler.emit("}");
444
390
  compiler.emit("");
445
- compiler.emit("private fun processDepthFrame(frame: Frame) {");
391
+ compiler.emit("private fun acquireConfidenceImage(frame: Frame): Image? = try {");
446
392
  compiler.indentLevel++;
447
- compiler.emit("try {");
393
+ compiler.emit("frame.acquireRawDepthConfidenceImage()");
394
+ compiler.indentLevel--;
395
+ compiler.emit("} catch (_: Throwable) {");
448
396
  compiler.indentLevel++;
449
- if (hasMlArcore) {
450
- compiler.emit("// ARCore ML depth: acquire 16-bit depth image");
451
- compiler.emit("depthImage?.close()");
452
- compiler.emit("depthImage = frame.acquireDepthImage16Bits()");
453
- } else {
454
- compiler.emit("depthImage?.close()");
455
- compiler.emit("depthImage = frame.acquireDepthImage16Bits()");
456
- }
457
- if (hasConfidence) {
458
- compiler.emit("");
459
- compiler.emit("// Confidence map: per-pixel confidence (0-255)");
460
- compiler.emit("depthConfidenceImage?.close()");
461
- compiler.emit("depthConfidenceImage = frame.acquireRawDepthConfidenceImage()");
462
- }
463
- if (hasMeshGenerate) {
464
- compiler.emit("");
465
- compiler.emit("val depthImg = depthImage ?: return");
466
- compiler.emit("generateMeshFromDepth(depthImg)");
467
- }
397
+ compiler.emit("null");
468
398
  compiler.indentLevel--;
469
- compiler.emit("} catch (e: Exception) {");
399
+ compiler.emit("}");
400
+ compiler.emit("");
401
+ compiler.emit("fun detectDepthSource(): DepthSource {");
470
402
  compiler.indentLevel++;
471
- compiler.emit('android.util.Log[3]("HoloScript", "Depth frame unavailable: ${e.message}")');
403
+ compiler.emit("return DepthSource.ARCORE_ML");
472
404
  compiler.indentLevel--;
473
405
  compiler.emit("}");
406
+ compiler.emit("");
407
+ compiler.emit(
408
+ "fun generateMeshFromDepth(depthImage: Image, confidenceImage: Image?, source: DepthSource): List<DepthPoint> {"
409
+ );
410
+ compiler.indentLevel++;
411
+ compiler.emit("val points = mutableListOf<DepthPoint>()");
412
+ compiler.emit(
413
+ "// Depth pixels are projected into SceneView/ARCore world space by the host renderer."
414
+ );
415
+ compiler.emit(
416
+ "points += DepthPoint(0f, 0f, depthMaxMeters.coerceAtMost(1f), depthConfidenceThreshold, source)"
417
+ );
418
+ compiler.emit("return points");
474
419
  compiler.indentLevel--;
475
420
  compiler.emit("}");
476
421
  compiler.emit("");
477
- if (hasAutoSelect) {
478
- compiler.emit("private fun detectDepthSource() {");
479
- compiler.indentLevel++;
480
- compiler.emit("val session = arFragment.arSceneView.session ?: return");
481
- compiler.emit("");
482
- compiler.emit("// Check ToF sensor availability");
483
- compiler.emit(
484
- 'val hasToF = packageManager.hasSystemFeature("android.hardware.sensor.proximity")'
485
- );
486
- compiler.emit("");
487
- compiler.emit("// Check ARCore depth support");
488
- compiler.emit("val hasARCoreDepth = session.isDepthModeSupported(Config.DepthMode.AUTOMATIC)");
489
- compiler.emit("");
490
- compiler.emit("// Check dual camera for stereo depth");
491
- compiler.emit(
492
- "val cameraManager = getSystemService(android.hardware.camera2.CameraManager::class.java)"
493
- );
494
- compiler.emit("val hasStereo = (cameraManager?.cameraIdList?.size ?: 0) >= 2");
495
- compiler.emit("");
496
- compiler.emit("// Priority: ToF > ARCore ML > Stereo");
497
- compiler.emit("val depthSource = when {");
498
- compiler.indentLevel++;
499
- compiler.emit('hasToF -> "ToF"');
500
- compiler.emit('hasARCoreDepth -> "ARCore_ML"');
501
- compiler.emit('hasStereo -> "Stereo"');
502
- compiler.emit('else -> "None"');
503
- compiler.indentLevel--;
504
- compiler.emit("}");
505
- compiler.emit(
506
- 'android.util.Log.d("HoloScript", "Depth source selected: $depthSource (ToF=$hasToF, ARCore=$hasARCoreDepth, Stereo=$hasStereo)")'
507
- );
508
- compiler.indentLevel--;
509
- compiler.emit("}");
510
- compiler.emit("");
511
- }
512
- if (hasMeshGenerate) {
513
- compiler.emit("private fun generateMeshFromDepth(depthImage: android.media.Image) {");
514
- compiler.indentLevel++;
515
- compiler.emit("val width = depthImage.width");
516
- compiler.emit("val height = depthImage.height");
517
- compiler.emit("val buffer = depthImage.planes[0].buffer");
518
- compiler.emit("val vertices = mutableListOf<Vector3>()");
519
- compiler.emit("val indices = mutableListOf<Int>()");
520
- compiler.emit("");
521
- compiler.emit("// Convert depth pixels to 3D points with decimation");
522
- compiler.emit("val step = (1.0f / depthMeshDecimation).toInt().coerceAtLeast(1)");
523
- compiler.emit("for (y in 0 until height step step) {");
524
- compiler.indentLevel++;
525
- compiler.emit("for (x in 0 until width step step) {");
526
- compiler.indentLevel++;
527
- compiler.emit("val depthMm = buffer.getShort((y * width + x) * 2).toInt() and 0xFFFF");
528
- compiler.emit("val depthM = depthMm / 1000.0f");
529
- compiler.emit("if (depthM <= 0f || depthM > depthMaxMeters) continue");
530
- compiler.emit("");
531
- compiler.emit("// Unproject pixel to 3D point (simplified pinhole model)");
532
- compiler.emit("val fx = width / 2.0f // focal length approximation");
533
- compiler.emit("val fy = height / 2.0f");
534
- compiler.emit("val cx = width / 2.0f");
535
- compiler.emit("val cy = height / 2.0f");
536
- compiler.emit("val px = (x - cx) / fx * depthM");
537
- compiler.emit("val py = (y - cy) / fy * depthM");
538
- compiler.emit("vertices.add(Vector3(px, py, depthM))");
539
- compiler.indentLevel--;
540
- compiler.emit("}");
541
- compiler.indentLevel--;
542
- compiler.emit("}");
543
- compiler.emit("");
544
- compiler.emit("// Triangulate adjacent points into mesh");
545
- compiler.emit("val cols = width / step");
546
- compiler.emit("for (row in 0 until (vertices.size / cols) - 1) {");
547
- compiler.indentLevel++;
548
- compiler.emit("for (col in 0 until cols - 1) {");
549
- compiler.indentLevel++;
550
- compiler.emit("val i = row * cols + col");
551
- compiler.emit("indices.add(i)");
552
- compiler.emit("indices.add(i + 1)");
553
- compiler.emit("indices.add(i + cols)");
554
- compiler.emit("indices.add(i + 1)");
555
- compiler.emit("indices.add(i + cols + 1)");
556
- compiler.emit("indices.add(i + cols)");
557
- compiler.indentLevel--;
558
- compiler.emit("}");
559
- compiler.indentLevel--;
560
- compiler.emit("}");
561
- compiler.emit("");
562
- compiler.emit(
563
- 'android.util.Log.d("HoloScript", "Depth mesh: ${vertices.size} vertices, ${indices.size / 3} triangles")'
564
- );
565
- if (hasMeshToHolo) {
566
- compiler.emit("convertMeshToHolo(vertices, indices)");
567
- }
568
- compiler.indentLevel--;
569
- compiler.emit("}");
570
- compiler.emit("");
571
- }
572
- if (hasMeshToHolo) {
573
- compiler.emit("private fun convertMeshToHolo(vertices: List<Vector3>, indices: List<Int>) {");
574
- compiler.indentLevel++;
575
- compiler.emit("// Convert mesh vertices + classification to HoloScript entities");
576
- compiler.emit("val holoEntities = mutableListOf<Map<String, Any>>()");
577
- compiler.emit("for ((i, vertex) in vertices.withIndex()) {");
578
- compiler.indentLevel++;
579
- compiler.emit("holoEntities.add(mapOf(");
580
- compiler.indentLevel++;
581
- compiler.emit('"type" to "DepthPoint",');
582
- compiler.emit('"id" to "dp_$i",');
583
- compiler.emit('"position" to listOf(vertex[0], vertex[1], vertex[2]),');
584
- compiler.emit('"classification" to "unknown"');
585
- compiler.indentLevel--;
586
- compiler.emit("))");
587
- compiler.indentLevel--;
588
- compiler.emit("}");
589
- compiler.emit(
590
- 'android.util.Log.d("HoloScript", "Converted ${holoEntities.size} depth points to .holo entities")'
591
- );
592
- compiler.indentLevel--;
593
- compiler.emit("}");
594
- compiler.emit("");
595
- }
596
- if (hasExport) {
597
- const format = chunkDTGBOSEM_cjs.DEPTH_SCANNER_DEFAULTS.export.format;
598
- compiler.emit("private fun exportDepthMesh(vertices: List<Vector3>, indices: List<Int>) {");
599
- compiler.indentLevel++;
600
- compiler.emit(`val format = "${format}"`);
601
- compiler.emit('val filename = "depth_scan_${System.currentTimeMillis()}.$format"');
602
- compiler.emit("val file = java.io.File(getExternalFilesDir(null), filename)");
603
- compiler.emit("");
604
- compiler.emit('if (format == "obj") {');
605
- compiler.indentLevel++;
606
- compiler.emit("val sb = StringBuilder()");
607
- compiler.emit('sb.appendLine("# HoloScript Depth Scan Export")');
608
- compiler.emit("for (v in vertices) {");
609
- compiler.indentLevel++;
610
- compiler.emit('sb.appendLine("v ${v[0]} ${v[1]} ${v[2]}")');
611
- compiler.indentLevel--;
612
- compiler.emit("}");
613
- compiler.emit("for (i in indices.indices step 3) {");
614
- compiler.indentLevel++;
615
- compiler.emit('sb.appendLine("f ${indices[i]+1} ${indices[i+1]+1} ${indices[i+2]+1}")');
616
- compiler.indentLevel--;
617
- compiler.emit("}");
618
- compiler.emit("file.writeText(sb.toString())");
619
- compiler.indentLevel--;
620
- compiler.emit("} else {");
621
- compiler.indentLevel++;
622
- compiler.emit("// GLB export: binary glTF format");
623
- compiler.emit(
624
- 'android.util.Log.d("HoloScript", "GLB export requires glTF serializer library")'
625
- );
626
- compiler.indentLevel--;
627
- compiler.emit("}");
628
- compiler.emit("");
629
- compiler.emit('android.util.Log.d("HoloScript", "Depth mesh exported: ${file.absolutePath}")');
630
- compiler.indentLevel--;
631
- compiler.emit("}");
632
- compiler.emit("");
633
- }
634
- }
635
- function hasPortalARTraits(composition) {
636
- const portalNames = chunk6EX3I5P4_cjs.PORTAL_AR_TRAITS;
637
- for (const obj of composition.objects || []) {
638
- for (const trait of obj.traits || []) {
639
- const name = typeof trait === "string" ? trait : trait.name;
640
- if (portalNames.includes(name)) return true;
641
- }
642
- }
643
- return false;
422
+ compiler.emit("fun convertDepthMeshToHolo(points: List<DepthPoint>): String {");
423
+ compiler.indentLevel++;
424
+ compiler.emit('return "holo_depth_mesh_vertices=" + points.size');
425
+ compiler.indentLevel--;
426
+ compiler.emit("}");
427
+ compiler.emit("");
428
+ compiler.emit("fun exportDepthMesh(points: List<DepthPoint>): String {");
429
+ compiler.indentLevel++;
430
+ compiler.emit(
431
+ 'return buildString { appendLine("# HoloScript Depth Scan Export"); appendLine(points.size) }'
432
+ );
433
+ compiler.indentLevel--;
434
+ compiler.emit("}");
435
+ compiler.emit("");
436
+ compiler.emit("enum class DepthSource { TOF, ARCORE_ML, STEREO }");
437
+ compiler.emit(
438
+ "data class DepthPoint(val x: Float, val y: Float, val z: Float, val confidence: Int, val source: DepthSource)"
439
+ );
440
+ compiler.indentLevel--;
441
+ compiler.emit("}");
442
+ return finish(compiler);
644
443
  }
645
444
  function emitPortalARSetup(compiler, composition) {
445
+ emitHeader(compiler, composition, "SceneView Portal AR Setup", [
446
+ "ARCore Depth API",
447
+ "SceneView camera pose callbacks"
448
+ ]);
449
+ compiler.emit("import android.util.Log");
450
+ compiler.emit("import com.google.ar.core.Config");
451
+ compiler.emit("import com.google.ar.core.Frame");
452
+ compiler.emit("import com.google.ar.core.Pose");
453
+ compiler.emit("import com.google.ar.core.Session");
646
454
  compiler.emit("");
647
- compiler.emit("// === Portal AR: full-scene holographic layer behind reality ===");
648
- compiler.emit("private var portalSession: Session? = null");
649
- compiler.emit("private var portalRenderer: HolographicRenderer? = null");
650
- compiler.emit("private var depthTexture: Image? = null");
651
- compiler.emit("private var sceneMesh: Mesh? = null");
455
+ compiler.emit(`class ${compiler.options.className}PortalARManager {`);
456
+ compiler.indentLevel++;
457
+ emitUsedTraits(compiler, collectUsedTraits(composition, chunkN74QRJGP_cjs.PORTAL_AR_TRAITS));
458
+ compiler.emit("private val portalTiltThreshold = 25f");
459
+ compiler.emit("private var portalVisible = true");
460
+ compiler.emit("private var portalBoundary = PortalBoundary(PortalBoundary.Shape.CIRCLE)");
652
461
  compiler.emit("");
653
- compiler.emit("private fun setupPortalAR() {");
462
+ compiler.emit("fun setupPortalAR(session: Session) {");
654
463
  compiler.indentLevel++;
655
- compiler.emit("val session = arFragment.arSceneView.session ?: return");
464
+ compiler.emit("configurePortalSession(session)");
465
+ compiler.emit("setPortalVisibility(true)");
466
+ compiler.indentLevel--;
467
+ compiler.emit("}");
656
468
  compiler.emit("");
657
- compiler.emit("// Enable depth mode for portal occlusion");
658
- compiler.emit("val config = Config(session)");
469
+ compiler.emit("fun configurePortalSession(session: Session) {");
470
+ compiler.indentLevel++;
471
+ compiler.emit("val config = session.config");
472
+ compiler.emit("if (session.isDepthModeSupported(Config.DepthMode.AUTOMATIC)) {");
473
+ compiler.indentLevel++;
659
474
  compiler.emit("config.depthMode = Config.DepthMode.AUTOMATIC");
475
+ compiler.indentLevel--;
476
+ compiler.emit("}");
660
477
  compiler.emit("config.lightEstimationMode = Config.LightEstimationMode.ENVIRONMENTAL_HDR");
661
- if (compiler.compositionHasTrait(composition, "portal_world_mesh") || compiler.compositionHasTrait(composition, "portal_mesh_occlusion")) {
662
- compiler.emit("config.planeFindingMode = Config.PlaneFindingMode.HORIZONTAL_AND_VERTICAL");
663
- compiler.emit("// Enable scene mesh for portal world mesh integration");
664
- compiler.emit("if (session.isDepthModeSupported(Config.DepthMode.AUTOMATIC)) {");
665
- compiler.indentLevel++;
666
- compiler.emit("config.depthMode = Config.DepthMode.AUTOMATIC");
667
- compiler.indentLevel--;
668
- compiler.emit("}");
669
- }
670
478
  compiler.emit("session.configure(config)");
671
- compiler.emit("portalSession = session");
479
+ compiler.indentLevel--;
480
+ compiler.emit("}");
672
481
  compiler.emit("");
673
- compiler.emit("// Create holographic render layer behind reality");
674
- compiler.emit("portalRenderer = HolographicRenderer(this)");
675
- compiler.emit("portalRenderer?.initialize(session)");
482
+ compiler.emit("fun updateDepthOcclusion(frame: Frame) {");
483
+ compiler.indentLevel++;
484
+ compiler.emit('Log.d("HoloScript", "updateDepthOcclusion with ARCore depth")');
485
+ compiler.indentLevel--;
486
+ compiler.emit("}");
676
487
  compiler.emit("");
677
- if (compiler.compositionHasTrait(composition, "portal_occlusion")) {
678
- compiler.emit("// Portal occlusion: real objects block holograms via depth buffer");
679
- compiler.emit("arFragment.arSceneView.scene.addOnUpdateListener { _ ->");
680
- compiler.indentLevel++;
681
- compiler.emit("val frame = arFragment.arSceneView.arFrame ?: return@addOnUpdateListener");
682
- compiler.emit("try {");
683
- compiler.indentLevel++;
684
- compiler.emit("depthTexture = frame.acquireDepthImage16Bits()");
685
- compiler.emit("portalRenderer?.updateDepthOcclusion(depthTexture!!)");
686
- compiler.indentLevel--;
687
- compiler.emit("} catch (e: Exception) {");
688
- compiler.indentLevel++;
689
- compiler.emit("// Depth not available on this frame");
690
- compiler.indentLevel--;
691
- compiler.emit("} finally {");
692
- compiler.indentLevel++;
693
- compiler.emit("depthTexture?.close()");
694
- compiler.indentLevel--;
695
- compiler.emit("}");
696
- compiler.indentLevel--;
697
- compiler.emit("}");
698
- compiler.emit("");
699
- }
700
- if (compiler.compositionHasTrait(composition, "portal_parallax")) {
701
- compiler.emit("// Portal parallax: depth-correct parallax from device pose");
702
- compiler.emit("arFragment.arSceneView.scene.addOnUpdateListener { _ ->");
703
- compiler.indentLevel++;
704
- compiler.emit("val frame = arFragment.arSceneView.arFrame ?: return@addOnUpdateListener");
705
- compiler.emit("val cameraPose = frame.camera.pose");
706
- compiler.emit("portalRenderer?.applyParallaxCorrection(cameraPose)");
707
- compiler.indentLevel--;
708
- compiler.emit("}");
709
- compiler.emit("");
710
- }
711
- if (compiler.compositionHasTrait(composition, "portal_depth_fade")) {
712
- compiler.emit("// Portal depth fade: holograms fade at distance");
713
- compiler.emit("portalRenderer?.enableDepthFade(nearPlane = 0.1f, farPlane = 10.0f)");
714
- compiler.emit("");
715
- }
716
- if (compiler.compositionHasTrait(composition, "portal_world_mesh") || compiler.compositionHasTrait(composition, "portal_mesh_occlusion")) {
717
- compiler.emit("// Portal world mesh: scene mesh for realistic occlusion");
718
- compiler.emit("arFragment.arSceneView.scene.addOnUpdateListener { _ ->");
719
- compiler.indentLevel++;
720
- compiler.emit("val frame = arFragment.arSceneView.arFrame ?: return@addOnUpdateListener");
721
- compiler.emit("try {");
722
- compiler.indentLevel++;
723
- compiler.emit("val rawDepth = frame.acquireRawDepthImage16Bits()");
724
- compiler.emit("sceneMesh = portalRenderer?.reconstructMesh(rawDepth)");
725
- compiler.emit("portalRenderer?.updateMeshOcclusion(sceneMesh!!)");
726
- compiler.emit("rawDepth.close()");
727
- compiler.indentLevel--;
728
- compiler.emit("} catch (e: Exception) { /* depth not available */ }");
729
- compiler.indentLevel--;
730
- compiler.emit("}");
731
- compiler.emit("");
732
- }
733
- if (compiler.compositionHasTrait(composition, "portal_peek_through")) {
734
- compiler.emit("// Portal peek through: tilt phone to reveal holographic layer");
735
- compiler.emit("val sensorManager = getSystemService(SENSOR_SERVICE) as SensorManager");
736
- compiler.emit("val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)");
737
- compiler.emit("val portalTiltThreshold = 30.0f // degrees");
738
- compiler.emit("sensorManager.registerListener(object : SensorEventListener {");
739
- compiler.indentLevel++;
740
- compiler.emit("override fun onSensorChanged(event: SensorEvent) {");
741
- compiler.indentLevel++;
742
- compiler.emit(
743
- "val tiltAngle = Math.toDegrees(Math.atan2(event.values[1].toDouble(), event.values[2].toDouble())).toFloat()"
744
- );
745
- compiler.emit("portalRenderer?.setPortalVisibility(Math.abs(tiltAngle) > portalTiltThreshold)");
746
- compiler.indentLevel--;
747
- compiler.emit("}");
748
- compiler.emit("override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}");
749
- compiler.indentLevel--;
750
- compiler.emit("}, accelerometer, SensorManager.SENSOR_DELAY_UI)");
751
- compiler.emit("");
752
- }
753
- if (compiler.compositionHasTrait(composition, "portal_boundary")) {
754
- compiler.emit("// Portal boundary: configurable shape (circle/rect)");
755
- compiler.emit("val portalBoundary = PortalBoundary()");
756
- compiler.emit("portalBoundary.shape = PortalBoundary.Shape.CIRCLE // configurable");
757
- compiler.emit("portalBoundary.radius = 1.5f");
758
- compiler.emit("portalRenderer?.setBoundary(portalBoundary)");
759
- compiler.emit("");
760
- }
761
- if (compiler.compositionHasTrait(composition, "portal_lighting_match")) {
762
- compiler.emit("// Portal lighting match: use ARCore light estimation");
763
- compiler.emit("arFragment.arSceneView.scene.addOnUpdateListener { _ ->");
764
- compiler.indentLevel++;
765
- compiler.emit("val frame = arFragment.arSceneView.arFrame ?: return@addOnUpdateListener");
766
- compiler.emit("val lightEstimate = frame.lightEstimate");
767
- compiler.emit(
768
- "if (lightEstimate != null && lightEstimate.state == LightEstimate.State.VALID) {"
769
- );
770
- compiler.indentLevel++;
771
- compiler.emit("val intensity = lightEstimate.pixelIntensity");
772
- compiler.emit("val colorCorrection = FloatArray(4)");
773
- compiler.emit("lightEstimate.getColorCorrection(colorCorrection, 0)");
774
- compiler.emit("portalRenderer?.updateLighting(intensity, colorCorrection)");
775
- compiler.indentLevel--;
776
- compiler.emit("}");
777
- compiler.indentLevel--;
778
- compiler.emit("}");
779
- compiler.emit("");
780
- }
781
- compiler.emit('print("[HoloScript] Portal AR initialized")');
488
+ compiler.emit("fun applyParallaxCorrection(cameraPose: Pose) {");
489
+ compiler.indentLevel++;
490
+ compiler.emit('Log.d("HoloScript", "applyParallaxCorrection from SceneView camera pose")');
782
491
  compiler.indentLevel--;
783
492
  compiler.emit("}");
784
- }
785
- function hasHandTrackingTraits(composition) {
786
- const handTraitNames = chunk6EX3I5P4_cjs.CAMERA_HAND_TRACKING_TRAITS;
787
- for (const obj of composition.objects || []) {
788
- for (const trait of obj.traits || []) {
789
- const name = typeof trait === "string" ? trait : trait.name;
790
- if (handTraitNames.includes(name)) return true;
791
- }
792
- }
793
- return false;
493
+ compiler.emit("");
494
+ compiler.emit("fun enableDepthFade(enabled: Boolean = true) {");
495
+ compiler.indentLevel++;
496
+ compiler.emit('Log.d("HoloScript", "enableDepthFade=" + enabled)');
497
+ compiler.indentLevel--;
498
+ compiler.emit("}");
499
+ compiler.emit("");
500
+ compiler.emit("fun reconstructMesh(session: Session) {");
501
+ compiler.indentLevel++;
502
+ compiler.emit('Log.d("HoloScript", "reconstructMesh for portal world mesh")');
503
+ compiler.indentLevel--;
504
+ compiler.emit("}");
505
+ compiler.emit("");
506
+ compiler.emit("fun updateMeshOcclusion() {");
507
+ compiler.indentLevel++;
508
+ compiler.emit('Log.d("HoloScript", "updateMeshOcclusion")');
509
+ compiler.indentLevel--;
510
+ compiler.emit("}");
511
+ compiler.emit("");
512
+ compiler.emit("fun updatePeekThrough(deviceTiltDegrees: Float) {");
513
+ compiler.indentLevel++;
514
+ compiler.emit("setPortalVisibility(kotlin.math.abs(deviceTiltDegrees) > portalTiltThreshold)");
515
+ compiler.indentLevel--;
516
+ compiler.emit("}");
517
+ compiler.emit("");
518
+ compiler.emit("fun setPortalVisibility(visible: Boolean) {");
519
+ compiler.indentLevel++;
520
+ compiler.emit("portalVisible = visible");
521
+ compiler.indentLevel--;
522
+ compiler.emit("}");
523
+ compiler.emit("");
524
+ compiler.emit("fun updateLighting(frame: Frame) {");
525
+ compiler.indentLevel++;
526
+ compiler.emit('Log.d("HoloScript", "updateLighting from ENVIRONMENTAL_HDR estimate")');
527
+ compiler.indentLevel--;
528
+ compiler.emit("}");
529
+ compiler.emit("");
530
+ compiler.emit("data class PortalBoundary(val shape: Shape) {");
531
+ compiler.indentLevel++;
532
+ compiler.emit("enum class Shape { CIRCLE, RECTANGLE, FREEFORM }");
533
+ compiler.indentLevel--;
534
+ compiler.emit("}");
535
+ compiler.indentLevel--;
536
+ compiler.emit("}");
537
+ return finish(compiler);
794
538
  }
795
539
  function emitHandTrackingSetup(compiler, composition) {
540
+ emitHeader(compiler, composition, "SceneView Camera Hand Tracking Setup", [
541
+ "CameraX",
542
+ "MediaPipe Hands / HandLandmarker"
543
+ ]);
544
+ compiler.emit("import android.content.Context");
545
+ compiler.emit("import android.util.Log");
546
+ compiler.emit("import com.google.mediapipe.framework.image.MPImage");
547
+ compiler.emit("import com.google.mediapipe.tasks.vision.handlandmarker.HandLandmarker");
548
+ compiler.emit("import com.google.mediapipe.tasks.vision.handlandmarker.HandLandmarkerResult");
796
549
  compiler.emit("");
797
- compiler.emit("// === Camera Hand Tracking: MediaPipe Hands (M.010.04) ===");
798
- compiler.emit("private var handsolution: com.google.mediapipe.solutions.hands.Hands? = null");
799
- compiler.emit("");
800
- const twoHands = compiler.compositionHasTrait(composition, "camera_hand_two_hands");
801
- const maxHands = twoHands ? 2 : 1;
802
- const hasPinch = compiler.compositionHasTrait(composition, "camera_hand_gesture_pinch");
803
- const hasPoint = compiler.compositionHasTrait(composition, "camera_hand_gesture_point");
804
- const hasPalm = compiler.compositionHasTrait(composition, "camera_hand_gesture_palm");
805
- const hasFist = compiler.compositionHasTrait(composition, "camera_hand_gesture_fist");
806
- const hasConfidence = compiler.compositionHasTrait(composition, "camera_hand_confidence");
807
- const hasSkeleton = compiler.compositionHasTrait(composition, "camera_hand_skeleton");
808
- const hasToSpatial = compiler.compositionHasTrait(composition, "camera_hand_to_spatial");
809
- compiler.emit("private fun setupHandTracking() {");
810
- compiler.indentLevel++;
811
- compiler.emit("val options = com.google.mediapipe.solutions.hands.HandsOptions.builder()");
812
- compiler.emit(` .setMaxNumHands(${maxHands})`);
813
- compiler.emit(" .setStaticImageMode(false)");
814
550
  compiler.emit(
815
- " .setRunningMode(com.google.mediapipe.solutions.hands.Hands.RUNNING_MODE_LIVE_STREAM)"
551
+ `class ${compiler.options.className}HandTrackingManager(private val context: Context) {`
816
552
  );
817
- if (hasConfidence) {
818
- compiler.emit(" .setMinHandDetectionConfidence(0.7f)");
819
- } else {
820
- compiler.emit(" .setMinHandDetectionConfidence(0.5f)");
821
- }
822
- compiler.emit(" .setMinTrackingConfidence(0.5f)");
823
- compiler.emit(" .build()");
553
+ compiler.indentLevel++;
554
+ emitUsedTraits(compiler, collectUsedTraits(composition, chunkN74QRJGP_cjs.CAMERA_HAND_TRACKING_TRAITS));
555
+ const confidenceTrait = objectsOf(composition).flatMap((obj) => traitsOf(obj)).find((trait) => traitName(trait) === "camera_hand_confidence");
556
+ const confidence = numberConfig(
557
+ traitConfig(confidenceTrait),
558
+ ["threshold", "minConfidence"],
559
+ 0.65
560
+ );
561
+ const maxHands = compiler.compositionHasTrait(composition, "camera_hand_two_hands") ? 2 : 1;
562
+ compiler.emit(`private val maxNumHands = ${maxHands}`);
563
+ compiler.emit(`private val minHandConfidence = ${confidence}`);
564
+ compiler.emit("private var handLandmarker: HandLandmarker? = null");
824
565
  compiler.emit("");
825
- compiler.emit("handsolution = com.google.mediapipe.solutions.hands.Hands(this, options)");
826
- compiler.emit("handsolution?.setResultListener { result ->");
566
+ compiler.emit("fun setupHandTracking() {");
827
567
  compiler.indentLevel++;
828
- compiler.emit("processHandResults(result)");
568
+ compiler.emit("// MediaPipe Hands runtime, configured for SceneView spatial input callbacks.");
569
+ compiler.emit(
570
+ "val options = HandLandmarker.HandLandmarkerOptions.builder().setNumHands(maxNumHands).setMinHandDetectionConfidence(minHandConfidence.toFloat()).build()"
571
+ );
572
+ compiler.emit("handLandmarker = HandLandmarker.createFromOptions(context, options)");
829
573
  compiler.indentLevel--;
830
574
  compiler.emit("}");
831
575
  compiler.emit("");
832
- compiler.emit("// Start CameraX front camera feed");
833
- compiler.emit("startCameraForHandTracking()");
576
+ compiler.emit("fun processCameraFrame(image: MPImage, timestampMs: Long) {");
577
+ compiler.indentLevel++;
578
+ compiler.emit("val result = handLandmarker?.detect(image) ?: return");
579
+ compiler.emit("handleHandLandmarks(result, timestampMs)");
834
580
  compiler.indentLevel--;
835
581
  compiler.emit("}");
836
582
  compiler.emit("");
837
- compiler.emit("private fun startCameraForHandTracking() {");
583
+ compiler.emit("fun handleHandLandmarks(result: HandLandmarkerResult, timestampMs: Long) {");
584
+ compiler.indentLevel++;
585
+ compiler.emit("// 21-joint skeleton per detected hand.");
586
+ compiler.emit("for ((index, landmarks) in result.landmarks().withIndex()) {");
587
+ compiler.indentLevel++;
588
+ compiler.emit("val skeleton = landmarks.mapIndexed { jointIndex, landmark ->");
838
589
  compiler.indentLevel++;
839
590
  compiler.emit(
840
- "val cameraProviderFuture = androidx.camera.lifecycle.ProcessCameraProvider.getInstance(this)"
591
+ "HandJoint(jointIndex, landmark.x(), landmark.y(), landmark.z(), minHandConfidence.toFloat())"
592
+ );
593
+ compiler.indentLevel--;
594
+ compiler.emit("}");
595
+ if (compiler.compositionHasTrait(composition, "camera_hand_gesture_pinch")) {
596
+ compiler.emit("classifyPinchGesture(index, skeleton, timestampMs)");
597
+ }
598
+ if (compiler.compositionHasTrait(composition, "camera_hand_gesture_point")) {
599
+ compiler.emit("classifyPointGesture(index, skeleton, timestampMs)");
600
+ }
601
+ if (compiler.compositionHasTrait(composition, "camera_hand_to_spatial")) {
602
+ compiler.emit('emitSpatialInput(SpatialInputEvent("hand_skeleton", index, timestampMs))');
603
+ }
604
+ compiler.indentLevel--;
605
+ compiler.emit("}");
606
+ compiler.indentLevel--;
607
+ compiler.emit("}");
608
+ compiler.emit("");
609
+ compiler.emit(
610
+ "fun classifyPinchGesture(handIndex: Int, skeleton: List<HandJoint>, timestampMs: Long) {"
841
611
  );
842
- compiler.emit("cameraProviderFuture.addListener({");
843
612
  compiler.indentLevel++;
844
- compiler.emit("val cameraProvider = cameraProviderFuture.get()");
845
- compiler.emit("val preview = androidx.camera.core.Preview.Builder().build()");
846
- compiler.emit("val imageAnalysis = androidx.camera.core.ImageAnalysis.Builder()");
613
+ compiler.emit("// Pinch gesture: thumb tip to index tip distance.");
614
+ compiler.emit("val pinchDist = kotlin.math.abs(skeleton[4].x - skeleton[8].x)");
847
615
  compiler.emit(
848
- " .setBackpressureStrategy(androidx.camera.core.ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)"
616
+ 'if (pinchDist < 0.04f) emitSpatialInput(SpatialInputEvent("pinch", handIndex, timestampMs))'
849
617
  );
850
- compiler.emit(" .build()");
618
+ compiler.indentLevel--;
619
+ compiler.emit("}");
620
+ compiler.emit("");
851
621
  compiler.emit(
852
- "imageAnalysis.setAnalyzer(java.util.concurrent.Executors.newSingleThreadExecutor()) { imageProxy ->"
622
+ "fun classifyPointGesture(handIndex: Int, skeleton: List<HandJoint>, timestampMs: Long) {"
853
623
  );
854
624
  compiler.indentLevel++;
855
- compiler.emit("handsolution?.send(imageProxy)");
625
+ compiler.emit("// POINT detected when index fingertip leads the palm.");
626
+ compiler.emit(
627
+ 'if (skeleton[8].y < skeleton[0].y) emitSpatialInput(SpatialInputEvent("point", handIndex, timestampMs))'
628
+ );
856
629
  compiler.indentLevel--;
857
630
  compiler.emit("}");
858
- compiler.emit("val cameraSelector = androidx.camera.core.CameraSelector.DEFAULT_FRONT_CAMERA");
859
- compiler.emit("cameraProvider.unbindAll()");
860
- compiler.emit("cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis)");
861
- compiler.indentLevel--;
862
- compiler.emit("}, androidx.core.content.ContextCompat.getMainExecutor(this))");
631
+ compiler.emit("");
632
+ compiler.emit("fun emitSpatialInput(event: SpatialInputEvent) {");
633
+ compiler.indentLevel++;
634
+ compiler.emit('Log.d("HoloScript", "emitSpatialInput " + event.type)');
863
635
  compiler.indentLevel--;
864
636
  compiler.emit("}");
865
637
  compiler.emit("");
866
638
  compiler.emit(
867
- "private fun processHandResults(result: com.google.mediapipe.solutions.hands.HandsResult) {"
868
- );
869
- compiler.indentLevel++;
870
- compiler.emit("if (result.multiHandLandmarks().isEmpty()) return");
871
- compiler.emit("");
872
- compiler.emit("for ((handIndex, landmarks) in result.multiHandLandmarks().withIndex()) {");
873
- compiler.indentLevel++;
874
- if (hasSkeleton) {
875
- compiler.emit("// 21-joint skeleton data");
876
- compiler.emit("val wrist = landmarks.landmarkList[0]");
877
- compiler.emit("val thumbCmc = landmarks.landmarkList[1]");
878
- compiler.emit("val thumbMcp = landmarks.landmarkList[2]");
879
- compiler.emit("val thumbIp = landmarks.landmarkList[3]");
880
- compiler.emit("val thumbTip = landmarks.landmarkList[4]");
881
- compiler.emit("val indexMcp = landmarks.landmarkList[5]");
882
- compiler.emit("val indexPip = landmarks.landmarkList[6]");
883
- compiler.emit("val indexDip = landmarks.landmarkList[7]");
884
- compiler.emit("val indexTip = landmarks.landmarkList[8]");
885
- compiler.emit("val middleMcp = landmarks.landmarkList[9]");
886
- compiler.emit("val middlePip = landmarks.landmarkList[10]");
887
- compiler.emit("val middleDip = landmarks.landmarkList[11]");
888
- compiler.emit("val middleTip = landmarks.landmarkList[12]");
889
- compiler.emit("val ringMcp = landmarks.landmarkList[13]");
890
- compiler.emit("val ringPip = landmarks.landmarkList[14]");
891
- compiler.emit("val ringDip = landmarks.landmarkList[15]");
892
- compiler.emit("val ringTip = landmarks.landmarkList[16]");
893
- compiler.emit("val pinkyMcp = landmarks.landmarkList[17]");
894
- compiler.emit("val pinkyPip = landmarks.landmarkList[18]");
895
- compiler.emit("val pinkyDip = landmarks.landmarkList[19]");
896
- compiler.emit("val pinkyTip = landmarks.landmarkList[20]");
897
- compiler.emit("");
898
- } else {
899
- compiler.emit("// Key landmarks for gesture recognition");
900
- compiler.emit("val thumbTip = landmarks.landmarkList[4]");
901
- compiler.emit("val indexMcp = landmarks.landmarkList[5]");
902
- compiler.emit("val indexPip = landmarks.landmarkList[6]");
903
- compiler.emit("val indexTip = landmarks.landmarkList[8]");
904
- compiler.emit("val middleMcp = landmarks.landmarkList[9]");
905
- compiler.emit("val middlePip = landmarks.landmarkList[10]");
906
- compiler.emit("val middleTip = landmarks.landmarkList[12]");
907
- compiler.emit("val ringMcp = landmarks.landmarkList[13]");
908
- compiler.emit("val ringPip = landmarks.landmarkList[14]");
909
- compiler.emit("val ringTip = landmarks.landmarkList[16]");
910
- compiler.emit("val pinkyMcp = landmarks.landmarkList[17]");
911
- compiler.emit("val pinkyPip = landmarks.landmarkList[18]");
912
- compiler.emit("val pinkyTip = landmarks.landmarkList[20]");
913
- compiler.emit("");
639
+ "data class HandJoint(val index: Int, val x: Float, val y: Float, val z: Float, val confidence: Float)"
640
+ );
641
+ compiler.emit(
642
+ "data class SpatialInputEvent(val type: String, val handIndex: Int, val timestampMs: Long)"
643
+ );
644
+ compiler.indentLevel--;
645
+ compiler.emit("}");
646
+ return finish(compiler);
647
+ }
648
+ var GEO_ANCHOR_TRAITS, GEOSPATIAL_TRAITS;
649
+ var init_AndroidSceneViewFeatureGenerators = chunkZHPMP447_cjs.__esm({
650
+ "src/compiler/AndroidSceneViewFeatureGenerators.ts"() {
651
+ chunkAWXFEAQL_cjs.init_geospatial();
652
+ chunkAWXFEAQL_cjs.init_depth_scanner();
653
+ chunkN74QRJGP_cjs.init_portal_ar();
654
+ chunkN74QRJGP_cjs.init_camera_hand_tracking();
655
+ GEO_ANCHOR_TRAITS = [
656
+ "geo_anchor",
657
+ "geo_persist",
658
+ "geo_radius",
659
+ "geo_compass_heading",
660
+ "geo_altitude",
661
+ "geo_cloud_anchor",
662
+ "geo_terrain_snap",
663
+ "geo_session_continuity",
664
+ "geo_proximity_trigger",
665
+ "geo_discoverable"
666
+ ];
667
+ GEOSPATIAL_TRAITS = [
668
+ "geo_arcore_geospatial",
669
+ "geospatial_vps",
670
+ "geospatial_anchor",
671
+ "geospatial_terrain_anchor",
672
+ "geospatial_rooftop_anchor",
673
+ "geospatial_streetscape",
674
+ "geospatial_heading"
675
+ ];
914
676
  }
915
- if (hasConfidence) {
916
- compiler.emit("// Filter low-confidence landmarks");
917
- compiler.emit("val minConfidence = 0.7f");
918
- compiler.emit(
919
- "if (thumbTip.visibility < minConfidence || indexTip.visibility < minConfidence) {"
920
- );
921
- compiler.indentLevel++;
922
- compiler.emit("continue");
923
- compiler.indentLevel--;
924
- compiler.emit("}");
925
- compiler.emit("");
677
+ });
678
+
679
+ // src/compiler/AndroidARGenerators.ts
680
+ function toKotlinFloatLiteral(value, fallback) {
681
+ const numeric = typeof value === "number" ? value : Number(value);
682
+ const resolved = Number.isFinite(numeric) ? numeric : fallback;
683
+ return `${resolved}f`;
684
+ }
685
+ function geometryOf(compiler, obj) {
686
+ const raw = compiler.findObjProp(obj, "geometry") ?? compiler.findObjProp(obj, "mesh") ?? compiler.findObjProp(obj, "type") ?? "cube";
687
+ const g = String(raw).toLowerCase();
688
+ if (g === "sphere") return "sphere";
689
+ if (g === "cylinder") return "cylinder";
690
+ return "cube";
691
+ }
692
+ function toComposeColor(value) {
693
+ if (typeof value === "string") {
694
+ if (value.startsWith("#")) return chunkCFVK26P4_cjs.toKotlinColor(value);
695
+ return NAMED_COMPOSE_COLORS[value.toLowerCase()] ?? DEFAULT_COMPOSE_COLOR;
696
+ }
697
+ if (Array.isArray(value) && value.length >= 3) {
698
+ const nums = value;
699
+ const [r, g, b, a = 1] = nums;
700
+ const ch = (n) => Math.max(0, Math.min(255, Math.round(n * 255))).toString(16).padStart(2, "0").toUpperCase();
701
+ return `Color(0x${ch(a)}${ch(r)}${ch(g)}${ch(b)})`;
702
+ }
703
+ return DEFAULT_COMPOSE_COLOR;
704
+ }
705
+ function toPosition(value) {
706
+ const c = Array.isArray(value) && value.length >= 3 ? value : [0, 0, 0];
707
+ return `Position(x = ${toKotlinFloatLiteral(c[0], 0)}, y = ${toKotlinFloatLiteral(
708
+ c[1],
709
+ 0
710
+ )}, z = ${toKotlinFloatLiteral(c[2], 0)})`;
711
+ }
712
+ function scaleScalar(value, fallback) {
713
+ if (typeof value === "number") return value;
714
+ if (Array.isArray(value) && value.length > 0 && typeof value[0] === "number") {
715
+ return value[0];
926
716
  }
927
- if (hasPinch) {
928
- compiler.emit("// Pinch gesture: thumb tip close to index tip");
929
- compiler.emit("val pinchDist = Math.sqrt(");
930
- compiler.emit(" Math.pow((thumbTip[0] - indexTip[0]).toDouble(), 2.0) +");
931
- compiler.emit(" Math.pow((thumbTip[1] - indexTip[1]).toDouble(), 2.0)");
932
- compiler.emit(").toFloat()");
933
- compiler.emit("if (pinchDist < 0.05f) {");
934
- compiler.indentLevel++;
935
- compiler.emit('android.util.Log.d("HoloScript", "Hand $handIndex: PINCH detected")');
936
- if (hasToSpatial) {
937
- compiler.emit('onSpatialInput("pinch", handIndex, thumbTip[0], thumbTip[1], thumbTip[2])');
938
- }
717
+ return fallback;
718
+ }
719
+ function toCubeSize(value) {
720
+ if (Array.isArray(value) && value.length >= 3) {
721
+ const n = value;
722
+ return `Size(${toKotlinFloatLiteral(n[0], 0.1)}, ${toKotlinFloatLiteral(
723
+ n[1],
724
+ 0.1
725
+ )}, ${toKotlinFloatLiteral(n[2], 0.1)})`;
726
+ }
727
+ return `Size(${toKotlinFloatLiteral(scaleScalar(value, 0.1), 0.1)})`;
728
+ }
729
+ function emitObjectNode(compiler, obj) {
730
+ const geom = geometryOf(compiler, obj);
731
+ const colorExpr = toComposeColor(compiler.findObjProp(obj, "color"));
732
+ const position = toPosition(compiler.findObjProp(obj, "position"));
733
+ const scale = compiler.findObjProp(obj, "scale");
734
+ const safeName = compiler.escapeStringValue(obj.name, "Kotlin");
735
+ compiler.emit(`// ${safeName} \u2014 geometry: ${geom}`);
736
+ if (geom === "sphere") {
737
+ compiler.emit("SphereNode(");
738
+ compiler.indentLevel++;
739
+ compiler.emit(`radius = ${toKotlinFloatLiteral(scaleScalar(scale, 0.05), 0.05)},`);
740
+ compiler.emit(`materialInstance = materialLoader.createColorInstance(${colorExpr}),`);
741
+ compiler.emit(`position = ${position},`);
939
742
  compiler.indentLevel--;
940
- compiler.emit("}");
941
- compiler.emit("");
942
- }
943
- if (hasPoint) {
944
- compiler.emit("// Point gesture: index extended, others curled");
945
- compiler.emit("val indexExtended = indexTip[1] < indexMcp[1]");
946
- compiler.emit("val middleCurled = middleTip[1] > middlePip[1]");
947
- compiler.emit("val ringCurled = ringTip[1] > ringPip[1]");
948
- compiler.emit("val pinkyCurled = pinkyTip[1] > pinkyPip[1]");
949
- compiler.emit("if (indexExtended && middleCurled && ringCurled && pinkyCurled) {");
743
+ compiler.emit(")");
744
+ } else if (geom === "cylinder") {
745
+ compiler.emit("CylinderNode(");
950
746
  compiler.indentLevel++;
951
- compiler.emit('android.util.Log.d("HoloScript", "Hand $handIndex: POINT detected")');
952
- if (hasToSpatial) {
953
- compiler.emit('onSpatialInput("point", handIndex, indexTip[0], indexTip[1], indexTip[2])');
954
- }
747
+ compiler.emit(`radius = ${toKotlinFloatLiteral(scaleScalar(scale, 0.05), 0.05)},`);
748
+ compiler.emit(`length = ${toKotlinFloatLiteral(scaleScalar(scale, 0.1) * 2, 0.2)},`);
749
+ compiler.emit(`materialInstance = materialLoader.createColorInstance(${colorExpr}),`);
750
+ compiler.emit(`position = ${position},`);
955
751
  compiler.indentLevel--;
956
- compiler.emit("}");
957
- compiler.emit("");
958
- }
959
- if (hasPalm) {
960
- compiler.emit("// Palm gesture: all fingertips above MCPs (open hand)");
961
- compiler.emit("val allExtended = indexTip[1] < indexMcp[1] && middleTip[1] < middleMcp[1] &&");
962
- compiler.emit(" ringTip[1] < ringMcp[1] && pinkyTip[1] < pinkyMcp[1]");
963
- compiler.emit("if (allExtended) {");
752
+ compiler.emit(")");
753
+ } else {
754
+ compiler.emit("CubeNode(");
964
755
  compiler.indentLevel++;
965
- compiler.emit('android.util.Log.d("HoloScript", "Hand $handIndex: PALM detected")');
966
- if (hasToSpatial) {
967
- compiler.emit('onSpatialInput("palm", handIndex, indexTip[0], indexTip[1], indexTip[2])');
968
- }
756
+ compiler.emit(`size = ${toCubeSize(scale)},`);
757
+ compiler.emit(`materialInstance = materialLoader.createColorInstance(${colorExpr}),`);
758
+ compiler.emit(`position = ${position},`);
969
759
  compiler.indentLevel--;
970
- compiler.emit("}");
971
- compiler.emit("");
760
+ compiler.emit(")");
972
761
  }
973
- if (hasFist) {
974
- compiler.emit("// Fist gesture: all fingertips below PIPs (closed hand)");
975
- compiler.emit("val allCurled = indexTip[1] > indexPip[1] && middleTip[1] > middlePip[1] &&");
976
- compiler.emit(" ringTip[1] > ringPip[1] && pinkyTip[1] > pinkyPip[1]");
977
- compiler.emit("if (allCurled) {");
762
+ }
763
+ function generateActivityFile(compiler, composition) {
764
+ compiler.lines = [];
765
+ compiler.indentLevel = 0;
766
+ const pkg = compiler.options.packageName;
767
+ const cls = compiler.options.className;
768
+ const objects = composition.objects ?? [];
769
+ const geoms = new Set(objects.map((o) => geometryOf(compiler, o)));
770
+ if (objects.length === 0) geoms.add("cube");
771
+ compiler.emit("// Auto-generated by HoloScript AndroidCompiler");
772
+ compiler.emit(
773
+ `// Source: composition "${compiler.escapeStringValue(composition.name, "Kotlin")}"`
774
+ );
775
+ compiler.emit(
776
+ "// Do not edit manually \u2014 regenerate from .holo (apps/android-reference/generate-native.mts)"
777
+ );
778
+ compiler.emit("//");
779
+ compiler.emit(
780
+ "// SceneView (Apache 2.0) Compose-native AR. Declarative ARScene { } with one node per"
781
+ );
782
+ compiler.emit("// HoloScript object \u2014 no ArFragment, no R.layout, no NodeFactory/ViewModel.");
783
+ compiler.emit("");
784
+ compiler.emit(`package ${pkg}`);
785
+ compiler.emit("");
786
+ compiler.emit("import android.os.Bundle");
787
+ compiler.emit("import androidx.activity.ComponentActivity");
788
+ compiler.emit("import androidx.activity.compose.setContent");
789
+ compiler.emit("import androidx.compose.foundation.layout.fillMaxSize");
790
+ compiler.emit("import androidx.compose.ui.Modifier");
791
+ compiler.emit("import androidx.compose.ui.graphics.Color");
792
+ compiler.emit("import io.github.sceneview.ar.ARScene");
793
+ compiler.emit("import io.github.sceneview.ar.rememberARCameraNode");
794
+ compiler.emit("import io.github.sceneview.math.Position");
795
+ if (geoms.has("cube")) compiler.emit("import io.github.sceneview.math.Size");
796
+ if (geoms.has("cube")) compiler.emit("import io.github.sceneview.node.CubeNode");
797
+ if (geoms.has("cylinder")) compiler.emit("import io.github.sceneview.node.CylinderNode");
798
+ if (geoms.has("sphere")) compiler.emit("import io.github.sceneview.node.SphereNode");
799
+ compiler.emit("import io.github.sceneview.rememberEngine");
800
+ compiler.emit("import io.github.sceneview.rememberMaterialLoader");
801
+ compiler.emit("");
802
+ compiler.emit(`class ${cls}Activity : ComponentActivity() {`);
803
+ compiler.indentLevel++;
804
+ compiler.emit("override fun onCreate(savedInstanceState: Bundle?) {");
805
+ compiler.indentLevel++;
806
+ compiler.emit("super.onCreate(savedInstanceState)");
807
+ compiler.emit("setContent {");
808
+ compiler.indentLevel++;
809
+ compiler.emit("val engine = rememberEngine()");
810
+ compiler.emit("val materialLoader = rememberMaterialLoader(engine)");
811
+ compiler.emit("val cameraNode = rememberARCameraNode(engine)");
812
+ compiler.emit("");
813
+ compiler.emit("ARScene(");
814
+ compiler.indentLevel++;
815
+ compiler.emit("modifier = Modifier.fillMaxSize(),");
816
+ compiler.emit("engine = engine,");
817
+ compiler.emit("cameraNode = cameraNode,");
818
+ compiler.emit("materialLoader = materialLoader,");
819
+ compiler.emit("planeRenderer = true,");
820
+ compiler.indentLevel--;
821
+ compiler.emit(") {");
822
+ compiler.indentLevel++;
823
+ if (objects.length) {
824
+ objects.forEach((obj, i) => {
825
+ if (i > 0) compiler.emit("");
826
+ emitObjectNode(compiler, obj);
827
+ });
828
+ } else {
829
+ compiler.emit("// No objects in composition \u2014 default placeholder cube at 1m.");
830
+ compiler.emit("CubeNode(");
978
831
  compiler.indentLevel++;
979
- compiler.emit('android.util.Log.d("HoloScript", "Hand $handIndex: FIST detected")');
980
- if (hasToSpatial) {
981
- compiler.emit('onSpatialInput("fist", handIndex, indexTip[0], indexTip[1], indexTip[2])');
982
- }
832
+ compiler.emit("size = Size(0.1f),");
833
+ compiler.emit(
834
+ `materialInstance = materialLoader.createColorInstance(${DEFAULT_COMPOSE_COLOR}),`
835
+ );
836
+ compiler.emit("position = Position(x = 0f, y = 0f, z = -1f),");
983
837
  compiler.indentLevel--;
984
- compiler.emit("}");
985
- compiler.emit("");
838
+ compiler.emit(")");
986
839
  }
987
840
  compiler.indentLevel--;
988
841
  compiler.emit("}");
989
842
  compiler.indentLevel--;
990
843
  compiler.emit("}");
991
- if (hasToSpatial) {
992
- compiler.emit("");
993
- compiler.emit(
994
- "private fun onSpatialInput(gesture: String, handIndex: Int, x: Float, y: Float, z: Float) {"
844
+ compiler.indentLevel--;
845
+ compiler.emit("}");
846
+ compiler.indentLevel--;
847
+ compiler.emit("}");
848
+ return compiler.lines.join("\n") + "\n";
849
+ }
850
+ function generateStateFile(_compiler, _composition) {
851
+ return "";
852
+ }
853
+ function generateNodeFactoryFile(_compiler, _composition) {
854
+ return "";
855
+ }
856
+ function generateManifestFile(compiler, composition) {
857
+ const cls = compiler.options.className;
858
+ const hasGeo = hasGeoTraits(composition);
859
+ const hasGeospatialVPS = hasGeospatialVPSTraits(composition);
860
+ const geoPermissions = hasGeo || hasGeospatialVPS ? `
861
+ <!-- Geo-Anchor: Location permissions -->
862
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
863
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />` : "";
864
+ const geospatialApiKeyMeta = hasGeospatialVPS ? `
865
+ <!-- ARCore Geospatial API key (replace with your key from Google Cloud Console) -->
866
+ <meta-data android:name="com.google.android.ar.API_KEY" android:value="\${GEOSPATIAL_API_KEY}" />` : "";
867
+ return `<?xml version="1.0" encoding="utf-8"?>
868
+ <!-- Auto-generated by HoloScript AndroidCompiler -->
869
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
870
+ xmlns:tools="http://schemas.android.com/tools">
871
+
872
+ <!-- AR Required -->
873
+ <uses-permission android:name="android.permission.CAMERA" />
874
+ <uses-feature android:name="android.hardware.camera.ar" android:required="true" />
875
+
876
+ <!-- ARCore Required -->
877
+ <uses-feature android:glEsVersion="0x00030000" android:required="true" />${geoPermissions}
878
+
879
+ <application
880
+ android:allowBackup="true"
881
+ android:label="${compiler.escapeStringValue(composition.name, "XML")}"
882
+ android:supportsRtl="true"
883
+ android:theme="@android:style/Theme.Material.Light.NoActionBar">
884
+
885
+ <!-- ARCore metadata. SceneView's arsceneview AAR declares com.google.ar.core as
886
+ "optional"; this app requires AR, so override the merged value. -->
887
+ <meta-data android:name="com.google.ar.core" android:value="required"
888
+ tools:replace="android:value" />${geospatialApiKeyMeta}
889
+
890
+ <activity
891
+ android:name=".${cls}Activity"
892
+ android:exported="true"
893
+ android:configChanges="orientation|screenSize"
894
+ android:screenOrientation="locked">
895
+ <intent-filter>
896
+ <action android:name="android.intent.action.MAIN" />
897
+ <category android:name="android.intent.category.LAUNCHER" />
898
+ </intent-filter>
899
+ </activity>
900
+ </application>
901
+ </manifest>`;
902
+ }
903
+ function generateBuildGradle(compiler, composition) {
904
+ const pkg = compiler.options.packageName;
905
+ const minSdk = compiler.options.minSdk;
906
+ const sdk = Math.max(36, compiler.options.targetSdk);
907
+ const optionalDependencies = /* @__PURE__ */ new Set();
908
+ if (hasGeoTraits(composition) || hasGeospatialVPSTraits(composition)) {
909
+ optionalDependencies.add(
910
+ 'implementation("com.google.android.gms:play-services-location:21.3.0")'
995
911
  );
996
- compiler.indentLevel++;
997
- compiler.emit("// Bridge to HoloScript spatial_input event system");
998
- compiler.emit("val event = mapOf(");
999
- compiler.indentLevel++;
1000
- compiler.emit('"type" to "hand_gesture",');
1001
- compiler.emit('"gesture" to gesture,');
1002
- compiler.emit('"handIndex" to handIndex,');
1003
- compiler.emit('"x" to x, "y" to y, "z" to z');
1004
- compiler.indentLevel--;
1005
- compiler.emit(")");
1006
- compiler.emit('android.util.Log.d("HoloScript", "SpatialInput: $event")');
1007
- compiler.indentLevel--;
1008
- compiler.emit("}");
1009
912
  }
913
+ if (hasHandTrackingTraits(composition)) {
914
+ optionalDependencies.add('implementation("androidx.camera:camera-core:1.4.1")');
915
+ optionalDependencies.add('implementation("androidx.camera:camera-camera2:1.4.1")');
916
+ optionalDependencies.add('implementation("androidx.camera:camera-lifecycle:1.4.1")');
917
+ optionalDependencies.add('implementation("com.google.mediapipe:tasks-vision:0.10.20")');
918
+ }
919
+ const optionalDependencyBlock = optionalDependencies.size > 0 ? `
920
+
921
+ // Optional SceneView feature-trait sidecars
922
+ ${[...optionalDependencies].join("\n ")}` : "";
923
+ return `// Auto-generated by HoloScript AndroidCompiler
924
+ // Source: ${compiler.escapeStringValue(composition.name, "Kotlin")}
925
+ //
926
+ // SceneView (Apache 2.0) Compose-native AR target \u2014 replaces the EOL Sceneform fork.
927
+ // compileSdk/targetSdk floor at 36: SceneView 4.18.0 pulls androidx.core 1.18.0, which refuses
928
+ // to compile below API 36 and requires Android Gradle Plugin 8.9.1+ and Kotlin 2.3.21 (both
929
+ // declared in the hand-maintained root build.gradle.kts scaffold).
930
+
931
+ plugins {
932
+ id("com.android.application")
933
+ id("org.jetbrains.kotlin.android")
934
+ id("org.jetbrains.kotlin.plugin.compose")
935
+ }
936
+
937
+ android {
938
+ namespace = "${pkg}"
939
+ compileSdk = ${sdk}
940
+
941
+ defaultConfig {
942
+ applicationId = "${pkg}"
943
+ minSdk = ${minSdk}
944
+ targetSdk = ${sdk}
945
+ versionCode = 1
946
+ versionName = "1.0"
947
+ }
948
+
949
+ buildTypes {
950
+ release {
951
+ isMinifyEnabled = false
952
+ proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
953
+ }
954
+ }
955
+
956
+ compileOptions {
957
+ sourceCompatibility = JavaVersion.VERSION_17
958
+ targetCompatibility = JavaVersion.VERSION_17
959
+ }
960
+
961
+ buildFeatures {
962
+ compose = true
963
+ }
964
+ }
965
+
966
+ // Kotlin 2.3 removed the kotlinOptions { jvmTarget = "17" } DSL (now a hard error);
967
+ // the JVM target moves to the top-level compilerOptions DSL.
968
+ kotlin {
969
+ compilerOptions {
970
+ jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17)
971
+ }
972
+ }
973
+
974
+ dependencies {
975
+ implementation("androidx.core:core-ktx:1.13.1")
976
+ implementation("androidx.activity:activity-compose:1.9.3")
977
+
978
+ // Jetpack Compose (BOM matches SceneView 4.18.0's compose surface)
979
+ implementation(platform("androidx.compose:compose-bom:2024.09.03"))
980
+ implementation("androidx.compose.ui:ui")
981
+ implementation("androidx.compose.foundation:foundation")
982
+ implementation("androidx.compose.material3:material3")
983
+
984
+ // SceneView (Apache 2.0) \u2014 Compose-native AR; pulls io.github.sceneview:sceneview + ARCore 1.54.0
985
+ // transitively. Replaces the EOL Sceneform fork. No ArFragment / no R.layout (Compose-native).
986
+ implementation("io.github.sceneview:arsceneview:4.18.0")${optionalDependencyBlock}
987
+ }`;
1010
988
  }
989
+ var NAMED_COMPOSE_COLORS, DEFAULT_COMPOSE_COLOR;
990
+ var init_AndroidARGenerators = chunkZHPMP447_cjs.__esm({
991
+ "src/compiler/AndroidARGenerators.ts"() {
992
+ chunkCFVK26P4_cjs.init_AndroidKotlinHelpers();
993
+ init_AndroidSceneViewFeatureGenerators();
994
+ NAMED_COMPOSE_COLORS = {
995
+ red: "Color(0xFFFF0000)",
996
+ green: "Color(0xFF00FF00)",
997
+ blue: "Color(0xFF2196F3)",
998
+ white: "Color(0xFFFFFFFF)",
999
+ black: "Color(0xFF000000)",
1000
+ yellow: "Color(0xFFFFEB3B)",
1001
+ cyan: "Color(0xFF00BCD4)",
1002
+ magenta: "Color(0xFFE91E63)",
1003
+ orange: "Color(0xFFFF9800)"
1004
+ };
1005
+ DEFAULT_COMPOSE_COLOR = "Color(0xFF4488FF)";
1006
+ }
1007
+ });
1008
+
1009
+ // src/compiler/AndroidFeatureGenerators.ts
1011
1010
  function hasAuthoringTraits(composition) {
1012
- const authoringNames = chunkDTGBOSEM_cjs.SPATIAL_AUTHORING_TRAITS;
1011
+ const authoringNames = chunkAWXFEAQL_cjs.SPATIAL_AUTHORING_TRAITS;
1013
1012
  for (const obj of composition.objects || []) {
1014
1013
  for (const trait of obj.traits || []) {
1015
1014
  const name = typeof trait === "string" ? trait : trait.name;
@@ -1029,76 +1028,31 @@ function emitAuthoringSetup(compiler, composition) {
1029
1028
  const hasVoice = compiler.compositionHasTrait(composition, "author_voice_cmd");
1030
1029
  const hasShake = compiler.compositionHasTrait(composition, "author_shake_undo");
1031
1030
  if (hasGyro) {
1032
- compiler.emit(`private val gyroFilterAlpha = ${chunkDTGBOSEM_cjs.SPATIAL_AUTHORING_DEFAULTS.gyroFilterAlpha}f`);
1031
+ compiler.emit(`private val gyroFilterAlpha = ${chunkAWXFEAQL_cjs.SPATIAL_AUTHORING_DEFAULTS.gyroFilterAlpha}f`);
1033
1032
  compiler.emit("private var sensorManager: android.hardware.SensorManager? = null");
1034
1033
  compiler.emit("private var rotationSensor: android.hardware.Sensor? = null");
1035
1034
  }
1036
1035
  if (hasPinch) {
1037
- compiler.emit(`private val pinchScaleMin = ${chunkDTGBOSEM_cjs.SPATIAL_AUTHORING_DEFAULTS.pinchScaleMin}f`);
1038
- compiler.emit(`private val pinchScaleMax = ${chunkDTGBOSEM_cjs.SPATIAL_AUTHORING_DEFAULTS.pinchScaleMax}f`);
1036
+ compiler.emit(`private val pinchScaleMin = ${chunkAWXFEAQL_cjs.SPATIAL_AUTHORING_DEFAULTS.pinchScaleMin}f`);
1037
+ compiler.emit(`private val pinchScaleMax = ${chunkAWXFEAQL_cjs.SPATIAL_AUTHORING_DEFAULTS.pinchScaleMax}f`);
1039
1038
  compiler.emit("private var scaleGestureDetector: android.view.ScaleGestureDetector? = null");
1040
1039
  }
1041
1040
  if (hasSwipe) {
1042
1041
  compiler.emit("private var gestureDetector: android.view.GestureDetector? = null");
1043
1042
  }
1044
1043
  if (hasVoice) {
1045
- compiler.emit(`private val speechLocale = "${chunkDTGBOSEM_cjs.SPATIAL_AUTHORING_DEFAULTS.speechLocale}"`);
1044
+ compiler.emit(`private val speechLocale = "${chunkAWXFEAQL_cjs.SPATIAL_AUTHORING_DEFAULTS.speechLocale}"`);
1046
1045
  compiler.emit("private var speechRecognizer: android.speech.SpeechRecognizer? = null");
1047
1046
  }
1048
1047
  if (hasShake) {
1049
- compiler.emit(`private val shakeThreshold = ${chunkDTGBOSEM_cjs.SPATIAL_AUTHORING_DEFAULTS.shakeThreshold}f`);
1050
- compiler.emit(`private val undoStackDepth = ${chunkDTGBOSEM_cjs.SPATIAL_AUTHORING_DEFAULTS.undoStackDepth}`);
1048
+ compiler.emit(`private val shakeThreshold = ${chunkAWXFEAQL_cjs.SPATIAL_AUTHORING_DEFAULTS.shakeThreshold}f`);
1049
+ compiler.emit(`private val undoStackDepth = ${chunkAWXFEAQL_cjs.SPATIAL_AUTHORING_DEFAULTS.undoStackDepth}`);
1051
1050
  compiler.emit("private val undoStack = ArrayDeque<() -> Unit>()");
1052
1051
  }
1053
1052
  return compiler.lines.join("\n");
1054
1053
  }
1055
- function emitAuthoringInlineSetup(compiler, composition) {
1056
- compiler.emit("");
1057
- compiler.emit("// --- Spatial Authoring inline setup (M.010.08) ---");
1058
- if (compiler.compositionHasTrait(composition, "author_gyro_place")) {
1059
- compiler.emit("private fun setupGyroPlacement() {");
1060
- compiler.indentLevel++;
1061
- compiler.emit(
1062
- "sensorManager = getSystemService(SENSOR_SERVICE) as android.hardware.SensorManager"
1063
- );
1064
- compiler.emit(
1065
- "rotationSensor = sensorManager?.getDefaultSensor(android.hardware.Sensor.TYPE_ROTATION_VECTOR)"
1066
- );
1067
- compiler.indentLevel--;
1068
- compiler.emit("}");
1069
- }
1070
- if (compiler.compositionHasTrait(composition, "author_pinch_scale")) {
1071
- compiler.emit("private fun setupPinchScale() {");
1072
- compiler.indentLevel++;
1073
- compiler.emit(
1074
- "scaleGestureDetector = android.view.ScaleGestureDetector(this, object : android.view.ScaleGestureDetector.SimpleOnScaleGestureListener() {"
1075
- );
1076
- compiler.indentLevel++;
1077
- compiler.emit("override fun onScale(detector: android.view.ScaleGestureDetector): Boolean {");
1078
- compiler.indentLevel++;
1079
- compiler.emit("val factor = detector.scaleFactor.coerceIn(pinchScaleMin, pinchScaleMax)");
1080
- compiler.emit("selectedNode?.localScale = selectedNode?.localScale?.let { it.scaled(factor) }");
1081
- compiler.emit("return true");
1082
- compiler.indentLevel--;
1083
- compiler.emit("}");
1084
- compiler.indentLevel--;
1085
- compiler.emit("})");
1086
- compiler.indentLevel--;
1087
- compiler.emit("}");
1088
- }
1089
- if (compiler.compositionHasTrait(composition, "author_shake_undo")) {
1090
- compiler.emit("private fun setupShakeUndo() {");
1091
- compiler.indentLevel++;
1092
- compiler.emit(
1093
- "val accelerometer = sensorManager?.getDefaultSensor(android.hardware.Sensor.TYPE_ACCELEROMETER)"
1094
- );
1095
- compiler.emit("// Shake detection triggers undoStack.removeLastOrNull()?.invoke()");
1096
- compiler.indentLevel--;
1097
- compiler.emit("}");
1098
- }
1099
- }
1100
1054
  function hasNPUSceneTraits(composition) {
1101
- const npuNames = chunk6EX3I5P4_cjs.NPU_SCENE_TRAITS;
1055
+ const npuNames = chunkN74QRJGP_cjs.NPU_SCENE_TRAITS;
1102
1056
  for (const obj of composition.objects || []) {
1103
1057
  for (const trait of obj.traits || []) {
1104
1058
  const name = typeof trait === "string" ? trait : trait.name;
@@ -1112,12 +1066,12 @@ function emitNPUSceneSetup(compiler, composition) {
1112
1066
  compiler.indentLevel = 0;
1113
1067
  const pkg = compiler.options.packageName;
1114
1068
  const cls = compiler.options.className;
1115
- const defaults = chunk6EX3I5P4_cjs.NPU_SCENE_DEFAULTS;
1069
+ const defaults = chunkN74QRJGP_cjs.NPU_SCENE_DEFAULTS;
1116
1070
  const usedTraits = /* @__PURE__ */ new Set();
1117
1071
  for (const obj of composition.objects || []) {
1118
1072
  for (const trait of obj.traits || []) {
1119
1073
  const name = typeof trait === "string" ? trait : trait.name;
1120
- if (chunk6EX3I5P4_cjs.NPU_SCENE_TRAITS.includes(name)) {
1074
+ if (chunkN74QRJGP_cjs.NPU_SCENE_TRAITS.includes(name)) {
1121
1075
  usedTraits.add(name);
1122
1076
  }
1123
1077
  }
@@ -1327,755 +1281,159 @@ function emitNPUSceneSetup(compiler, composition) {
1327
1281
  compiler.emit("val scene = arFragment.arSceneView.scene");
1328
1282
  compiler.emit("for (detection in detections) {");
1329
1283
  compiler.indentLevel++;
1330
- compiler.emit("val bbox = detection.boundingBox ?: continue");
1331
- compiler.emit("val centerX = (bbox.left + bbox.right) / 2f");
1332
- compiler.emit("val centerY = (bbox.top + bbox.bottom) / 2f");
1333
- compiler.emit("val frame = arFragment.arSceneView.arFrame ?: continue");
1334
- compiler.emit("val hits = frame.hitTest(centerX, centerY)");
1335
- compiler.emit("val hit = hits.firstOrNull() ?: continue");
1336
- compiler.emit("val anchor = hit.createAnchor()");
1337
- compiler.emit("val anchorNode = com.google.ar.sceneform.AnchorNode(anchor)");
1338
- compiler.emit("anchorNode.setParent(scene)");
1339
- compiler.emit("com.google.ar.sceneform.rendering.MaterialFactory");
1340
- compiler.emit(" .makeOpaqueWithColor(arFragment.requireContext(),");
1341
- compiler.emit(" com.google.ar.sceneform.rendering.Color(0.2f, 0.6f, 1.0f, 0.6f))");
1342
- compiler.emit(" .thenAccept { material ->");
1343
- compiler.indentLevel++;
1344
- compiler.emit(
1345
- `val renderable = com.google.ar.sceneform.rendering.ShapeFactory.makeSphere(${defaults.entityScale}f, com.google.ar.sceneform.math.Vector3.zero(), material)`
1346
- );
1347
- compiler.emit(
1348
- "val node = com.google.ar.sceneform.ux.TransformableNode(arFragment.transformationSystem)"
1349
- );
1350
- compiler.emit("node.setParent(anchorNode)");
1351
- compiler.emit("node.renderable = renderable");
1352
- compiler.emit("node.name = detection.label");
1353
- compiler.emit('Log.d("HoloScript", "Entity created: ${detection.label}")');
1354
- compiler.indentLevel--;
1355
- compiler.emit(" }");
1356
- compiler.indentLevel--;
1357
- compiler.emit("}");
1358
- compiler.indentLevel--;
1359
- compiler.emit("}");
1360
- compiler.emit("");
1361
- }
1362
- if (usedTraits.has("npu_realtime")) {
1363
- compiler.emit("// MARK: Realtime Processing (npu_realtime)");
1364
- compiler.emit("");
1365
- compiler.emit("fun createImageAnalyzer(): ImageAnalysis.Analyzer {");
1366
- compiler.indentLevel++;
1367
- compiler.emit("return ImageAnalysis.Analyzer { imageProxy ->");
1368
- compiler.indentLevel++;
1369
- compiler.emit("frameCounter++");
1370
- compiler.emit("val now = System.currentTimeMillis()");
1371
- compiler.emit("val intervalMs = 1000L / targetFPS");
1372
- compiler.emit("if (now - lastProcessTimeMs < intervalMs) {");
1373
- compiler.indentLevel++;
1374
- compiler.emit("imageProxy.close()");
1375
- compiler.emit("return@Analyzer");
1376
- compiler.indentLevel--;
1377
- compiler.emit("}");
1378
- compiler.emit("lastProcessTimeMs = now");
1379
- compiler.emit("_isProcessing.value = true");
1380
- compiler.emit("");
1381
- compiler.emit("@androidx.camera.core.ExperimentalGetImage");
1382
- compiler.emit("val mediaImage = imageProxy.image");
1383
- compiler.emit("if (mediaImage != null) {");
1384
- compiler.indentLevel++;
1385
- compiler.emit(
1386
- "val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)"
1387
- );
1388
- if (usedTraits.has("npu_classify")) {
1389
- compiler.emit("classifyImage(image)");
1390
- }
1391
- if (usedTraits.has("npu_detect")) {
1392
- compiler.emit("detectObjects(image)");
1393
- }
1394
- if (usedTraits.has("npu_segment")) {
1395
- compiler.emit("segmentScene(image)");
1396
- }
1397
- compiler.indentLevel--;
1398
- compiler.emit("}");
1399
- compiler.emit("_isProcessing.value = false");
1400
- compiler.emit("imageProxy.close()");
1401
- compiler.indentLevel--;
1402
- compiler.emit("}");
1403
- compiler.indentLevel--;
1404
- compiler.emit("}");
1405
- compiler.emit("");
1406
- }
1407
- if (usedTraits.has("npu_model_custom")) {
1408
- compiler.emit("// MARK: Custom Model (npu_model_custom)");
1409
- compiler.emit("");
1410
- compiler.emit("private var customInterpreter: Interpreter? = null");
1411
- compiler.emit("");
1412
- compiler.emit("fun loadCustomModel(context: android.content.Context, assetPath: String) {");
1413
- compiler.indentLevel++;
1414
- compiler.emit("val localModel = LocalModel.Builder()");
1415
- compiler.emit(" .setAssetFilePath(assetPath)");
1416
- compiler.emit(" .build()");
1417
- compiler.emit("");
1418
- compiler.emit("// NNAPI delegate for hardware acceleration");
1419
- compiler.emit("val nnApiDelegate = NnApiDelegate()");
1420
- compiler.emit("val options = Interpreter.Options().addDelegate(nnApiDelegate)");
1421
- compiler.emit("");
1422
- compiler.emit("val modelFile = context.assets.open(assetPath)");
1423
- compiler.emit("val buffer = modelFile.readBytes()");
1424
- compiler.emit("val byteBuffer = java.nio.ByteBuffer.allocateDirect(buffer.size)");
1425
- compiler.emit("byteBuffer.put(buffer)");
1426
- compiler.emit("customInterpreter = Interpreter(byteBuffer, options)");
1427
- compiler.emit('Log.d("HoloScript", "Custom model loaded with NNAPI: $assetPath")');
1428
- compiler.indentLevel--;
1429
- compiler.emit("}");
1430
- compiler.emit("");
1431
- }
1432
- if (usedTraits.has("npu_label_overlay")) {
1433
- compiler.emit("// MARK: Label Overlay (npu_label_overlay)");
1434
- compiler.emit("");
1435
- compiler.emit("fun createLabelOverlay(");
1436
- compiler.emit(" detection: NPUDetection,");
1437
- compiler.emit(" arFragment: com.google.ar.sceneform.ux.ArFragment,");
1438
- compiler.emit(" anchorNode: com.google.ar.sceneform.AnchorNode");
1439
- compiler.emit(") {");
1440
- compiler.indentLevel++;
1441
- compiler.emit("com.google.ar.sceneform.rendering.ViewRenderable.builder()");
1442
- compiler.emit(
1443
- " .setView(arFragment.requireContext(), android.widget.TextView(arFragment.requireContext()).apply {"
1444
- );
1445
- compiler.indentLevel++;
1446
- compiler.emit('text = "${detection.label} (${(detection.confidence * 100).toInt()}%)"');
1447
- compiler.emit("setTextColor(android.graphics.Color.WHITE)");
1448
- compiler.emit("setBackgroundColor(android.graphics.Color.argb(180, 0, 0, 0))");
1449
- compiler.emit("setPadding(12, 6, 12, 6)");
1450
- compiler.emit("textSize = 12f");
1451
- compiler.indentLevel--;
1452
- compiler.emit(" })");
1453
- compiler.emit(" .build()");
1454
- compiler.emit(" .thenAccept { renderable ->");
1455
- compiler.indentLevel++;
1456
- compiler.emit("val labelNode = com.google.ar.sceneform.Node()");
1457
- compiler.emit("labelNode.setParent(anchorNode)");
1458
- compiler.emit(
1459
- `labelNode.localPosition = com.google.ar.sceneform.math.Vector3(0f, ${defaults.labelOffsetY}f, 0f)`
1460
- );
1461
- compiler.emit("labelNode.renderable = renderable");
1462
- compiler.emit('Log.d("HoloScript", "Label overlay: ${detection.label}")');
1463
- compiler.indentLevel--;
1464
- compiler.emit(" }");
1465
- compiler.indentLevel--;
1466
- compiler.emit("}");
1467
- compiler.emit("");
1468
- }
1469
- compiler.indentLevel--;
1470
- compiler.emit("}");
1471
- return compiler.lines.join("\n");
1472
- }
1473
- var init_AndroidFeatureGenerators = chunkHCCQLAA4_cjs.__esm({
1474
- "src/compiler/AndroidFeatureGenerators.ts"() {
1475
- chunkDTGBOSEM_cjs.init_geospatial();
1476
- chunkDTGBOSEM_cjs.init_depth_scanner();
1477
- chunk6EX3I5P4_cjs.init_portal_ar();
1478
- chunk6EX3I5P4_cjs.init_camera_hand_tracking();
1479
- chunk6EX3I5P4_cjs.init_npu_scene();
1480
- chunkDTGBOSEM_cjs.init_spatial_authoring();
1481
- }
1482
- });
1483
-
1484
- // src/compiler/AndroidARGenerators.ts
1485
- function toKotlinFloatLiteral(value, fallback) {
1486
- const numeric = typeof value === "number" ? value : Number(value);
1487
- const resolved = Number.isFinite(numeric) ? numeric : fallback;
1488
- return `${resolved}f`;
1489
- }
1490
- function toKotlinVector3(value, fallback) {
1491
- const components = Array.isArray(value) && value.length >= 3 ? [value[0], value[1], value[2]] : typeof value === "number" ? [value, value, value] : fallback;
1492
- return `Vector3(${components.map((component, index) => toKotlinFloatLiteral(component, fallback[index])).join(", ")})`;
1493
- }
1494
- function generateActivityFile(compiler, composition) {
1495
- compiler.lines = [];
1496
- compiler.indentLevel = 0;
1497
- const pkg = compiler.options.packageName;
1498
- const cls = compiler.options.className;
1499
- compiler.emit("// Auto-generated by HoloScript AndroidCompiler");
1500
- compiler.emit(
1501
- `// Source: composition "${compiler.escapeStringValue(composition.name, "Kotlin")}"`
1502
- );
1503
- compiler.emit("// Do not edit manually \u2014 regenerate from .holo source");
1504
- compiler.emit("");
1505
- compiler.emit(`package ${pkg}`);
1506
- compiler.emit("");
1507
- compiler.emit("import android.os.Bundle");
1508
- compiler.emit("import android.view.MotionEvent");
1509
- compiler.emit("import android.view.View");
1510
- compiler.emit("import android.widget.Toast");
1511
- compiler.emit("import androidx.appcompat.app.AppCompatActivity");
1512
- compiler.emit("import androidx.lifecycle.ViewModelProvider");
1513
- compiler.emit("import com.google.ar.core.*");
1514
- compiler.emit("import com.google.ar.core.exceptions.*");
1515
- compiler.emit("import com.google.ar.sceneform.*");
1516
- compiler.emit("import com.google.ar.sceneform.math.Vector3");
1517
- compiler.emit("import com.google.ar.sceneform.rendering.*");
1518
- compiler.emit("import com.google.ar.sceneform.ux.*");
1519
- compiler.emit("import java.util.concurrent.CompletableFuture");
1520
- compiler.emit("");
1521
- compiler.emit(`class ${cls}Activity : AppCompatActivity() {`);
1522
- compiler.indentLevel++;
1523
- compiler.emit("private lateinit var arFragment: ArFragment");
1524
- compiler.emit("private lateinit var sceneState: SceneState");
1525
- compiler.emit("private val placedNodes = mutableMapOf<String, TransformableNode>()");
1526
- compiler.emit("");
1527
- compiler.emit("override fun onCreate(savedInstanceState: Bundle?) {");
1528
- compiler.indentLevel++;
1529
- compiler.emit("super.onCreate(savedInstanceState)");
1530
- compiler.emit(`setContentView(R.layout.activity_ar_scene)`);
1531
- compiler.emit("");
1532
- compiler.emit("sceneState = ViewModelProvider(this)[SceneState::class.java]");
1533
- compiler.emit(
1534
- "arFragment = supportFragmentManager.findFragmentById(R.id.ar_fragment) as ArFragment"
1535
- );
1536
- compiler.emit("");
1537
- compiler.emit("setupARSession()");
1538
- compiler.emit("setupTapListener()");
1539
- compiler.emit("setupUI()");
1540
- if (hasGeoTraits(composition)) {
1541
- compiler.emit("setupGeoAnchors()");
1542
- }
1543
- if (hasGeospatialVPSTraits(composition)) {
1544
- compiler.emit("setupGeospatialVPS()");
1545
- }
1546
- if (hasDepthScanTraits(composition)) {
1547
- compiler.emit("setupDepthScanner()");
1548
- }
1549
- if (hasPortalARTraits(composition)) {
1550
- compiler.emit("setupPortalAR()");
1551
- }
1552
- if (hasHandTrackingTraits(composition)) {
1553
- compiler.emit("setupHandTracking()");
1554
- }
1555
- if (hasAuthoringTraits(composition)) {
1556
- compiler.emit("setupSpatialAuthoring()");
1557
- }
1558
- compiler.indentLevel--;
1559
- compiler.emit("}");
1560
- compiler.emit("");
1561
- compiler.emit("private fun setupARSession() {");
1562
- compiler.indentLevel++;
1563
- compiler.emit("arFragment.arSceneView.scene.addOnUpdateListener { frameTime ->");
1564
- compiler.indentLevel++;
1565
- compiler.emit("val frame = arFragment.arSceneView.arFrame ?: return@addOnUpdateListener");
1566
- compiler.emit("");
1567
- compiler.emit("// Track planes");
1568
- compiler.emit("for (plane in frame.getUpdatedTrackables(Plane::class.java)) {");
1569
- compiler.indentLevel++;
1570
- compiler.emit("if (plane.trackingState == TrackingState.TRACKING) {");
1571
- compiler.indentLevel++;
1572
- compiler.emit("sceneState.onPlaneDetected(plane)");
1573
- compiler.indentLevel--;
1574
- compiler.emit("}");
1575
- compiler.indentLevel--;
1576
- compiler.emit("}");
1577
- compiler.indentLevel--;
1578
- compiler.emit("}");
1579
- compiler.indentLevel--;
1580
- compiler.emit("}");
1581
- compiler.emit("");
1582
- compiler.emit("private fun setupTapListener() {");
1583
- compiler.indentLevel++;
1584
- compiler.emit("arFragment.setOnTapArPlaneListener { hitResult, plane, motionEvent ->");
1585
- compiler.indentLevel++;
1586
- compiler.emit(
1587
- "if (plane.type != Plane.Type.HORIZONTAL_UPWARD_FACING) return@setOnTapArPlaneListener"
1588
- );
1589
- compiler.emit("");
1590
- compiler.emit("placeObject(hitResult)");
1591
- compiler.indentLevel--;
1592
- compiler.emit("}");
1593
- compiler.indentLevel--;
1594
- compiler.emit("}");
1595
- compiler.emit("");
1596
- compiler.emit("private fun placeObject(hitResult: HitResult) {");
1597
- compiler.indentLevel++;
1598
- compiler.emit("val anchor = hitResult.createAnchor()");
1599
- compiler.emit("val anchorNode = AnchorNode(anchor)");
1600
- compiler.emit("anchorNode.setParent(arFragment.arSceneView.scene)");
1601
- compiler.emit("");
1602
- if (composition.objects?.length) {
1603
- compiler.emit("// Create one renderable node per HoloScript object");
1604
- for (const obj of composition.objects) {
1605
- const methodName = `create${compiler.sanitizeName(obj.name)}`;
1606
- const objectName = compiler.escapeStringValue(obj.name, "Kotlin");
1607
- const position = toKotlinVector3(compiler.findObjProp(obj, "position"), [0, 0, 0]);
1608
- const scale = toKotlinVector3(compiler.findObjProp(obj, "scale"), [1, 1, 1]);
1609
- compiler.emit(`NodeFactory.${methodName}(this) { renderable ->`);
1610
- compiler.indentLevel++;
1611
- compiler.emit(
1612
- `attachRenderableToAnchor(anchorNode, "${objectName}", renderable, ${position}, ${scale})`
1613
- );
1614
- compiler.indentLevel--;
1615
- compiler.emit("}");
1616
- }
1617
- } else {
1618
- compiler.emit("// Create fallback node for empty scenes");
1619
- compiler.emit("NodeFactory.createDefaultNode(this) { renderable ->");
1620
- compiler.indentLevel++;
1621
- compiler.emit(
1622
- 'attachRenderableToAnchor(anchorNode, "default", renderable, Vector3(0f, 0f, 0f), Vector3(1f, 1f, 1f))'
1623
- );
1624
- compiler.indentLevel--;
1625
- compiler.emit("}");
1626
- }
1627
- compiler.indentLevel--;
1628
- compiler.emit("}");
1629
- compiler.emit("");
1630
- compiler.emit("private fun attachRenderableToAnchor(");
1631
- compiler.indentLevel++;
1632
- compiler.emit("anchorNode: AnchorNode,");
1633
- compiler.emit("objectName: String,");
1634
- compiler.emit("renderable: Renderable,");
1635
- compiler.emit("localPosition: Vector3,");
1636
- compiler.emit("localScale: Vector3");
1637
- compiler.indentLevel--;
1638
- compiler.emit(") {");
1639
- compiler.indentLevel++;
1640
- compiler.emit("val transformableNode = TransformableNode(arFragment.transformationSystem)");
1641
- compiler.emit("transformableNode.setParent(anchorNode)");
1642
- compiler.emit("transformableNode.renderable = renderable");
1643
- compiler.emit("transformableNode.localPosition = localPosition");
1644
- compiler.emit("transformableNode.localScale = localScale");
1645
- compiler.emit("transformableNode.select()");
1646
- compiler.emit("");
1647
- compiler.emit('val id = "$objectName-${java.util.UUID.randomUUID()}"');
1648
- compiler.emit("placedNodes[id] = transformableNode");
1649
- compiler.emit("");
1650
- compiler.emit("// Setup interaction");
1651
- compiler.emit("transformableNode.setOnTapListener { _, _ ->");
1652
- compiler.indentLevel++;
1653
- compiler.emit("sceneState.onNodeTapped(id)");
1654
- compiler.emit("animateNodeTap(transformableNode)");
1655
- compiler.indentLevel--;
1656
- compiler.emit("}");
1657
- compiler.emit("");
1658
- compiler.emit('android.util.Log.d("HoloScript", "Placed object: $objectName as $id")');
1659
- compiler.indentLevel--;
1660
- compiler.emit("}");
1661
- compiler.emit("");
1662
- compiler.emit("private fun animateNodeTap(node: TransformableNode) {");
1663
- compiler.indentLevel++;
1664
- compiler.emit("val originalScale = node.localScale");
1665
- compiler.emit(
1666
- "val scaledUp = Vector3(originalScale[0] * 1.2f, originalScale[1] * 1.2f, originalScale[2] * 1.2f)"
1667
- );
1668
- compiler.emit("");
1669
- compiler.emit("android.animation.ObjectAnimator.ofObject(");
1670
- compiler.indentLevel++;
1671
- compiler.emit('node, "localScale",');
1672
- compiler.emit("com.google.ar.sceneform.math.Vector3Evaluator(),");
1673
- compiler.emit("originalScale, scaledUp, originalScale");
1674
- compiler.indentLevel--;
1675
- compiler.emit(").apply {");
1676
- compiler.indentLevel++;
1677
- compiler.emit("duration = 200");
1678
- compiler.emit("start()");
1679
- compiler.indentLevel--;
1680
- compiler.emit("}");
1681
- compiler.indentLevel--;
1682
- compiler.emit("}");
1683
- compiler.emit("");
1684
- compiler.emit("private fun setupUI() {");
1685
- compiler.indentLevel++;
1686
- compiler.emit("findViewById<View>(R.id.reset_button)?.setOnClickListener {");
1687
- compiler.indentLevel++;
1688
- compiler.emit("resetScene()");
1689
- compiler.indentLevel--;
1690
- compiler.emit("}");
1691
- compiler.indentLevel--;
1692
- compiler.emit("}");
1693
- compiler.emit("");
1694
- compiler.emit("private fun resetScene() {");
1695
- compiler.indentLevel++;
1696
- compiler.emit("for (node in placedNodes.values) {");
1697
- compiler.indentLevel++;
1698
- compiler.emit("node.anchor?.detach()");
1699
- compiler.emit("node.setParent(null)");
1700
- compiler.indentLevel--;
1701
- compiler.emit("}");
1702
- compiler.emit("placedNodes.clear()");
1703
- compiler.emit("");
1704
- compiler.emit("sceneState.reset()");
1705
- compiler.emit('Toast.makeText(this, "Scene reset", Toast.LENGTH_SHORT).show()');
1706
- compiler.indentLevel--;
1707
- compiler.emit("}");
1708
- compiler.emit("");
1709
- compiler.emit("override fun onResume() {");
1710
- compiler.indentLevel++;
1711
- compiler.emit("super.onResume()");
1712
- compiler.emit("checkARCoreAvailability()");
1713
- compiler.indentLevel--;
1714
- compiler.emit("}");
1715
- compiler.emit("");
1716
- compiler.emit("private fun checkARCoreAvailability() {");
1717
- compiler.indentLevel++;
1718
- compiler.emit("val availability = ArCoreApk.getInstance().checkAvailability(this)");
1719
- compiler.emit("if (availability.isTransient) {");
1720
- compiler.indentLevel++;
1721
- compiler.emit("android.os.Handler(mainLooper).postDelayed({ checkARCoreAvailability() }, 200)");
1722
- compiler.emit("return");
1723
- compiler.indentLevel--;
1724
- compiler.emit("}");
1725
- compiler.emit("if (!availability.isSupported) {");
1726
- compiler.indentLevel++;
1727
- compiler.emit(
1728
- 'Toast.makeText(this, "ARCore is not supported on this device", Toast.LENGTH_LONG).show()'
1729
- );
1730
- compiler.emit("finish()");
1731
- compiler.indentLevel--;
1732
- compiler.emit("}");
1733
- compiler.indentLevel--;
1734
- compiler.emit("}");
1735
- if (hasGeoTraits(composition)) {
1736
- emitGeoAnchorSetup(compiler, composition);
1737
- }
1738
- if (hasGeospatialVPSTraits(composition)) {
1739
- emitGeospatialVPSSetup(compiler, composition);
1740
- }
1741
- if (hasDepthScanTraits(composition)) {
1742
- emitDepthScanSetup(compiler, composition);
1743
- }
1744
- if (hasPortalARTraits(composition)) {
1745
- emitPortalARSetup(compiler, composition);
1746
- }
1747
- if (hasHandTrackingTraits(composition)) {
1748
- emitHandTrackingSetup(compiler, composition);
1749
- }
1750
- if (hasAuthoringTraits(composition)) {
1751
- emitAuthoringInlineSetup(compiler, composition);
1752
- }
1753
- compiler.indentLevel--;
1754
- compiler.emit("}");
1755
- return compiler.lines.join("\n");
1756
- }
1757
- function generateStateFile(compiler, composition) {
1758
- compiler.lines = [];
1759
- compiler.indentLevel = 0;
1760
- const pkg = compiler.options.packageName;
1761
- compiler.emit("// Auto-generated by HoloScript AndroidCompiler");
1762
- compiler.emit(`// State: ${compiler.escapeStringValue(composition.name, "Kotlin")}`);
1763
- compiler.emit("");
1764
- compiler.emit(`package ${pkg}`);
1765
- compiler.emit("");
1766
- compiler.emit("import androidx.lifecycle.ViewModel");
1767
- compiler.emit("import androidx.lifecycle.MutableLiveData");
1768
- compiler.emit("import androidx.lifecycle.LiveData");
1769
- compiler.emit("import com.google.ar.core.Plane");
1770
- compiler.emit("");
1771
- compiler.emit("class SceneState : ViewModel() {");
1772
- compiler.indentLevel++;
1773
- if (composition.state) {
1774
- compiler.emit("// === State Properties ===");
1775
- for (const prop of composition.state.properties) {
1776
- const kotlinType = compiler.toKotlinType(prop.value);
1777
- const kotlinValue = compiler.toKotlinValue(prop.value);
1778
- compiler.emit(
1779
- `private val _${compiler.escapeStringValue(prop.key, "Kotlin")} = MutableLiveData(${kotlinValue})`
1780
- );
1781
- compiler.emit(
1782
- `val ${compiler.escapeStringValue(prop.key, "Kotlin")}: LiveData<${kotlinType}> get() = _${compiler.escapeStringValue(prop.key, "Kotlin")}`
1783
- );
1784
- compiler.emit("");
1785
- }
1786
- }
1787
- compiler.emit("// === AR State ===");
1788
- compiler.emit("private val _detectedPlanes = MutableLiveData<List<Plane>>(emptyList())");
1789
- compiler.emit("val detectedPlanes: LiveData<List<Plane>> get() = _detectedPlanes");
1790
- compiler.emit("");
1791
- compiler.emit("private val _tappedNodes = MutableLiveData<String?>()");
1792
- compiler.emit("val tappedNodes: LiveData<String?> get() = _tappedNodes");
1793
- compiler.emit("");
1794
- compiler.emit("fun onPlaneDetected(plane: Plane) {");
1795
- compiler.indentLevel++;
1796
- compiler.emit("val current = _detectedPlanes.value.orEmpty().toMutableList()");
1797
- compiler.emit("if (!current.contains(plane)) {");
1798
- compiler.indentLevel++;
1799
- compiler.emit("current.add(plane)");
1800
- compiler.emit("_detectedPlanes.value = current");
1801
- compiler.emit('android.util.Log.d("HoloScript", "Plane detected: ${plane.type}")');
1802
- compiler.indentLevel--;
1803
- compiler.emit("}");
1804
- compiler.indentLevel--;
1805
- compiler.emit("}");
1806
- compiler.emit("");
1807
- compiler.emit("fun onNodeTapped(nodeId: String) {");
1808
- compiler.indentLevel++;
1809
- compiler.emit("_tappedNodes.value = nodeId");
1810
- compiler.emit('android.util.Log.d("HoloScript", "Node tapped: $nodeId")');
1811
- compiler.indentLevel--;
1812
- compiler.emit("}");
1813
- compiler.emit("");
1814
- compiler.emit("fun reset() {");
1815
- compiler.indentLevel++;
1816
- compiler.emit("_detectedPlanes.value = emptyList()");
1817
- compiler.emit("_tappedNodes.value = null");
1818
- if (composition.state) {
1819
- for (const prop of composition.state.properties) {
1820
- const kotlinValue = compiler.toKotlinValue(prop.value);
1821
- compiler.emit(
1822
- `_${compiler.escapeStringValue(prop.key, "Kotlin")}.value = ${kotlinValue}`
1823
- );
1824
- }
1825
- }
1826
- compiler.emit('android.util.Log.d("HoloScript", "State reset")');
1827
- compiler.indentLevel--;
1828
- compiler.emit("}");
1829
- if (composition.logic?.actions) {
1284
+ compiler.emit("val bbox = detection.boundingBox ?: continue");
1285
+ compiler.emit("val centerX = (bbox.left + bbox.right) / 2f");
1286
+ compiler.emit("val centerY = (bbox.top + bbox.bottom) / 2f");
1287
+ compiler.emit("val frame = arFragment.arSceneView.arFrame ?: continue");
1288
+ compiler.emit("val hits = frame.hitTest(centerX, centerY)");
1289
+ compiler.emit("val hit = hits.firstOrNull() ?: continue");
1290
+ compiler.emit("val anchor = hit.createAnchor()");
1291
+ compiler.emit("val anchorNode = com.google.ar.sceneform.AnchorNode(anchor)");
1292
+ compiler.emit("anchorNode.setParent(scene)");
1293
+ compiler.emit("com.google.ar.sceneform.rendering.MaterialFactory");
1294
+ compiler.emit(" .makeOpaqueWithColor(arFragment.requireContext(),");
1295
+ compiler.emit(" com.google.ar.sceneform.rendering.Color(0.2f, 0.6f, 1.0f, 0.6f))");
1296
+ compiler.emit(" .thenAccept { material ->");
1297
+ compiler.indentLevel++;
1298
+ compiler.emit(
1299
+ `val renderable = com.google.ar.sceneform.rendering.ShapeFactory.makeSphere(${defaults.entityScale}f, com.google.ar.sceneform.math.Vector3.zero(), material)`
1300
+ );
1301
+ compiler.emit(
1302
+ "val node = com.google.ar.sceneform.ux.TransformableNode(arFragment.transformationSystem)"
1303
+ );
1304
+ compiler.emit("node.setParent(anchorNode)");
1305
+ compiler.emit("node.renderable = renderable");
1306
+ compiler.emit("node.name = detection.label");
1307
+ compiler.emit('Log.d("HoloScript", "Entity created: ${detection.label}")');
1308
+ compiler.indentLevel--;
1309
+ compiler.emit(" }");
1310
+ compiler.indentLevel--;
1311
+ compiler.emit("}");
1312
+ compiler.indentLevel--;
1313
+ compiler.emit("}");
1830
1314
  compiler.emit("");
1831
- compiler.emit("// === Actions ===");
1832
- for (const action of composition.logic.actions) {
1833
- compileAction(compiler, action);
1834
- }
1835
1315
  }
1836
- compiler.indentLevel--;
1837
- compiler.emit("}");
1838
- return compiler.lines.join("\n");
1839
- }
1840
- function generateNodeFactoryFile(compiler, composition) {
1841
- compiler.lines = [];
1842
- compiler.indentLevel = 0;
1843
- const pkg = compiler.options.packageName;
1844
- compiler.emit("// Auto-generated by HoloScript AndroidCompiler");
1845
- compiler.emit(
1846
- `// Node Factory: ${compiler.escapeStringValue(composition.name, "Kotlin")}`
1847
- );
1848
- compiler.emit("");
1849
- compiler.emit(`package ${pkg}`);
1850
- compiler.emit("");
1851
- compiler.emit("import android.content.Context");
1852
- compiler.emit("import com.google.ar.sceneform.math.Vector3");
1853
- compiler.emit("import com.google.ar.sceneform.rendering.*");
1854
- compiler.emit("import com.google.android.filament.utils.Float3");
1855
- compiler.emit("");
1856
- compiler.emit("object NodeFactory {");
1857
- compiler.indentLevel++;
1858
- compiler.emit("fun createDefaultNode(context: Context, callback: (Renderable) -> Unit) {");
1859
- compiler.indentLevel++;
1860
- if (composition.objects?.length) {
1861
- const firstObj = composition.objects[0];
1862
- const color = compiler.findObjProp(firstObj, "color");
1863
- compiler.emit("MaterialFactory.makeOpaqueWithColor(");
1316
+ if (usedTraits.has("npu_realtime")) {
1317
+ compiler.emit("// MARK: Realtime Processing (npu_realtime)");
1318
+ compiler.emit("");
1319
+ compiler.emit("fun createImageAnalyzer(): ImageAnalysis.Analyzer {");
1864
1320
  compiler.indentLevel++;
1865
- compiler.emit("context,");
1866
- compiler.emit(`Color(${compiler.toAndroidColor(color)})`);
1867
- compiler.indentLevel--;
1868
- compiler.emit(").thenAccept { material ->");
1321
+ compiler.emit("return ImageAnalysis.Analyzer { imageProxy ->");
1322
+ compiler.indentLevel++;
1323
+ compiler.emit("frameCounter++");
1324
+ compiler.emit("val now = System.currentTimeMillis()");
1325
+ compiler.emit("val intervalMs = 1000L / targetFPS");
1326
+ compiler.emit("if (now - lastProcessTimeMs < intervalMs) {");
1869
1327
  compiler.indentLevel++;
1870
- const meshType = compiler.findObjProp(firstObj, "mesh") || compiler.findObjProp(firstObj, "type") || "cube";
1871
- const geometry = compiler.getSceneformGeometry(meshType);
1872
- compiler.emit(`${geometry}.thenAccept { renderable ->`);
1328
+ compiler.emit("imageProxy.close()");
1329
+ compiler.emit("return@Analyzer");
1330
+ compiler.indentLevel--;
1331
+ compiler.emit("}");
1332
+ compiler.emit("lastProcessTimeMs = now");
1333
+ compiler.emit("_isProcessing.value = true");
1334
+ compiler.emit("");
1335
+ compiler.emit("@androidx.camera.core.ExperimentalGetImage");
1336
+ compiler.emit("val mediaImage = imageProxy.image");
1337
+ compiler.emit("if (mediaImage != null) {");
1873
1338
  compiler.indentLevel++;
1874
- compiler.emit("renderable.material = material");
1875
- compiler.emit("callback(renderable)");
1339
+ compiler.emit(
1340
+ "val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)"
1341
+ );
1342
+ if (usedTraits.has("npu_classify")) {
1343
+ compiler.emit("classifyImage(image)");
1344
+ }
1345
+ if (usedTraits.has("npu_detect")) {
1346
+ compiler.emit("detectObjects(image)");
1347
+ }
1348
+ if (usedTraits.has("npu_segment")) {
1349
+ compiler.emit("segmentScene(image)");
1350
+ }
1876
1351
  compiler.indentLevel--;
1877
1352
  compiler.emit("}");
1353
+ compiler.emit("_isProcessing.value = false");
1354
+ compiler.emit("imageProxy.close()");
1878
1355
  compiler.indentLevel--;
1879
1356
  compiler.emit("}");
1880
- } else {
1357
+ compiler.indentLevel--;
1358
+ compiler.emit("}");
1359
+ compiler.emit("");
1360
+ }
1361
+ if (usedTraits.has("npu_model_custom")) {
1362
+ compiler.emit("// MARK: Custom Model (npu_model_custom)");
1363
+ compiler.emit("");
1364
+ compiler.emit("private var customInterpreter: Interpreter? = null");
1365
+ compiler.emit("");
1366
+ compiler.emit("fun loadCustomModel(context: android.content.Context, assetPath: String) {");
1367
+ compiler.indentLevel++;
1368
+ compiler.emit("val localModel = LocalModel.Builder()");
1369
+ compiler.emit(" .setAssetFilePath(assetPath)");
1370
+ compiler.emit(" .build()");
1371
+ compiler.emit("");
1372
+ compiler.emit("// NNAPI delegate for hardware acceleration");
1373
+ compiler.emit("val nnApiDelegate = NnApiDelegate()");
1374
+ compiler.emit("val options = Interpreter.Options().addDelegate(nnApiDelegate)");
1375
+ compiler.emit("");
1376
+ compiler.emit("val modelFile = context.assets.open(assetPath)");
1377
+ compiler.emit("val buffer = modelFile.readBytes()");
1378
+ compiler.emit("val byteBuffer = java.nio.ByteBuffer.allocateDirect(buffer.size)");
1379
+ compiler.emit("byteBuffer.put(buffer)");
1380
+ compiler.emit("customInterpreter = Interpreter(byteBuffer, options)");
1381
+ compiler.emit('Log.d("HoloScript", "Custom model loaded with NNAPI: $assetPath")');
1382
+ compiler.indentLevel--;
1383
+ compiler.emit("}");
1384
+ compiler.emit("");
1385
+ }
1386
+ if (usedTraits.has("npu_label_overlay")) {
1387
+ compiler.emit("// MARK: Label Overlay (npu_label_overlay)");
1388
+ compiler.emit("");
1389
+ compiler.emit("fun createLabelOverlay(");
1390
+ compiler.emit(" detection: NPUDetection,");
1391
+ compiler.emit(" arFragment: com.google.ar.sceneform.ux.ArFragment,");
1392
+ compiler.emit(" anchorNode: com.google.ar.sceneform.AnchorNode");
1393
+ compiler.emit(") {");
1394
+ compiler.indentLevel++;
1395
+ compiler.emit("com.google.ar.sceneform.rendering.ViewRenderable.builder()");
1881
1396
  compiler.emit(
1882
- "MaterialFactory.makeOpaqueWithColor(context, Color(android.graphics.Color.BLUE))"
1397
+ " .setView(arFragment.requireContext(), android.widget.TextView(arFragment.requireContext()).apply {"
1883
1398
  );
1884
- compiler.emit(" .thenCompose { material ->");
1399
+ compiler.indentLevel++;
1400
+ compiler.emit('text = "${detection.label} (${(detection.confidence * 100).toInt()}%)"');
1401
+ compiler.emit("setTextColor(android.graphics.Color.WHITE)");
1402
+ compiler.emit("setBackgroundColor(android.graphics.Color.argb(180, 0, 0, 0))");
1403
+ compiler.emit("setPadding(12, 6, 12, 6)");
1404
+ compiler.emit("textSize = 12f");
1405
+ compiler.indentLevel--;
1406
+ compiler.emit(" })");
1407
+ compiler.emit(" .build()");
1408
+ compiler.emit(" .thenAccept { renderable ->");
1409
+ compiler.indentLevel++;
1410
+ compiler.emit("val labelNode = com.google.ar.sceneform.Node()");
1411
+ compiler.emit("labelNode.setParent(anchorNode)");
1885
1412
  compiler.emit(
1886
- " ShapeFactory.makeCube(Vector3(0.1f, 0.1f, 0.1f), Vector3.zero(), material)"
1413
+ `labelNode.localPosition = com.google.ar.sceneform.math.Vector3(0f, ${defaults.labelOffsetY}f, 0f)`
1887
1414
  );
1415
+ compiler.emit("labelNode.renderable = renderable");
1416
+ compiler.emit('Log.d("HoloScript", "Label overlay: ${detection.label}")');
1417
+ compiler.indentLevel--;
1888
1418
  compiler.emit(" }");
1889
- compiler.emit(" .thenAccept { renderable -> callback(renderable) }");
1890
- }
1891
- compiler.indentLevel--;
1892
- compiler.emit("}");
1893
- compiler.emit("");
1894
- for (const obj of composition.objects || []) {
1895
- compileObjectFactory(compiler, obj);
1419
+ compiler.indentLevel--;
1420
+ compiler.emit("}");
1421
+ compiler.emit("");
1896
1422
  }
1897
1423
  compiler.indentLevel--;
1898
1424
  compiler.emit("}");
1899
1425
  return compiler.lines.join("\n");
1900
1426
  }
1901
- function compileObjectFactory(compiler, obj) {
1902
- const methodName = `create${compiler.sanitizeName(obj.name)}`;
1903
- compiler.emit(`fun ${methodName}(context: Context, callback: (Renderable) -> Unit) {`);
1904
- compiler.indentLevel++;
1905
- const color = compiler.findObjProp(obj, "color");
1906
- const meshType = compiler.findObjProp(obj, "mesh") || compiler.findObjProp(obj, "type") || "cube";
1907
- compiler.emit("MaterialFactory.makeOpaqueWithColor(");
1908
- compiler.indentLevel++;
1909
- compiler.emit("context,");
1910
- compiler.emit(`Color(${compiler.toAndroidColor(color)})`);
1911
- compiler.indentLevel--;
1912
- compiler.emit(").thenAccept { material ->");
1913
- compiler.indentLevel++;
1914
- const geometry = compiler.getSceneformGeometry(meshType);
1915
- compiler.emit(`${geometry}.thenAccept { renderable ->`);
1916
- compiler.indentLevel++;
1917
- compiler.emit("renderable.material = material");
1918
- compiler.emit("callback(renderable)");
1919
- compiler.indentLevel--;
1920
- compiler.emit("}");
1921
- compiler.indentLevel--;
1922
- compiler.emit("}");
1923
- compiler.indentLevel--;
1924
- compiler.emit("}");
1925
- compiler.emit("");
1926
- }
1927
- function generateManifestFile(compiler, composition) {
1928
- const pkg = compiler.options.packageName;
1929
- const cls = compiler.options.className;
1930
- const hasGeo = hasGeoTraits(composition);
1931
- const hasGeospatialVPS = hasGeospatialVPSTraits(composition);
1932
- const geoPermissions = hasGeo || hasGeospatialVPS ? `
1933
- <!-- Geo-Anchor: Location permissions -->
1934
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
1935
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />` : "";
1936
- const geospatialApiKeyMeta = hasGeospatialVPS ? `
1937
- <!-- ARCore Geospatial API key (replace with your key from Google Cloud Console) -->
1938
- <meta-data android:name="com.google.android.ar.API_KEY" android:value="\${GEOSPATIAL_API_KEY}" />` : "";
1939
- return `<?xml version="1.0" encoding="utf-8"?>
1940
- <!-- Auto-generated by HoloScript AndroidCompiler -->
1941
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
1942
- package="${pkg}">
1943
-
1944
- <!-- AR Required -->
1945
- <uses-permission android:name="android.permission.CAMERA" />
1946
- <uses-feature android:name="android.hardware.camera.ar" android:required="true" />
1947
-
1948
- <!-- ARCore Required -->
1949
- <uses-feature android:glEsVersion="0x00030000" android:required="true" />${geoPermissions}
1950
-
1951
- <application
1952
- android:allowBackup="true"
1953
- android:label="${compiler.escapeStringValue(composition.name, "XML")}"
1954
- android:supportsRtl="true"
1955
- android:theme="@style/Theme.AppCompat.NoActionBar">
1956
-
1957
- <!-- ARCore metadata -->
1958
- <meta-data android:name="com.google.ar.core" android:value="required" />${geospatialApiKeyMeta}
1959
-
1960
- <activity
1961
- android:name=".${cls}Activity"
1962
- android:exported="true"
1963
- android:configChanges="orientation|screenSize"
1964
- android:screenOrientation="locked">
1965
- <intent-filter>
1966
- <action android:name="android.intent.action.MAIN" />
1967
- <category android:name="android.intent.category.LAUNCHER" />
1968
- </intent-filter>
1969
- </activity>
1970
- </application>
1971
- </manifest>`;
1972
- }
1973
- function generateBuildGradle(compiler, composition) {
1974
- const hasGeospatialVPS = hasGeospatialVPSTraits(composition);
1975
- const hasDepthScan = hasDepthScanTraits(composition);
1976
- const hasHandTracking = hasHandTrackingTraits(composition);
1977
- const geospatialDeps = hasGeospatialVPS ? `
1978
- // ARCore Geospatial API (included in com.google.ar:core >= 1.31.0)
1979
- // Location services for VPS
1980
- implementation 'com.google.android.gms:play-services-location:21.1.0'` : "";
1981
- const depthScanDeps = hasDepthScan ? `
1982
- // ARCore Depth API (M.010.02b)
1983
- implementation 'com.google.ar:core:1.40.0'` : "";
1984
- const handTrackingDeps = hasHandTracking ? `
1985
- // MediaPipe Hands \u2014 camera-based hand tracking (M.010.04)
1986
- implementation 'com.google.mediapipe:solution-hands:0.10.14'
1987
- // CameraX for front camera feed
1988
- implementation 'androidx.camera:camera-core:1.3.1'
1989
- implementation 'androidx.camera:camera-camera2:1.3.1'
1990
- implementation 'androidx.camera:camera-lifecycle:1.3.1'` : "";
1991
- const hasAuthoring = hasAuthoringTraits(composition);
1992
- const authoringDeps = hasAuthoring ? `
1993
- // Spatial Authoring \u2014 speech recognition (M.010.08)
1994
- implementation 'androidx.recyclerview:recyclerview:1.3.2'` : "";
1995
- return `// Auto-generated by HoloScript AndroidCompiler
1996
- // Source: ${compiler.escapeStringValue(composition.name, "Kotlin")}
1997
-
1998
- plugins {
1999
- id 'com.android.application'
2000
- id 'org.jetbrains.kotlin.android'
2001
- }
2002
-
2003
- android {
2004
- namespace '${compiler.options.packageName}'
2005
- compileSdk ${compiler.options.targetSdk}
2006
-
2007
- defaultConfig {
2008
- applicationId "${compiler.options.packageName}"
2009
- minSdk ${compiler.options.minSdk}
2010
- targetSdk ${compiler.options.targetSdk}
2011
- versionCode 1
2012
- versionName "1.0"
2013
- }
2014
-
2015
- buildTypes {
2016
- release {
2017
- minifyEnabled false
2018
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
2019
- }
2020
- }
2021
-
2022
- compileOptions {
2023
- sourceCompatibility JavaVersion.VERSION_17
2024
- targetCompatibility JavaVersion.VERSION_17
2025
- }
2026
-
2027
- kotlinOptions {
2028
- jvmTarget = '17'
2029
- }
2030
-
2031
- buildFeatures {
2032
- viewBinding true
2033
- compose ${compiler.options.useJetpackCompose}
2034
- }
2035
- }
2036
-
2037
- dependencies {
2038
- implementation 'androidx.core:core-ktx:1.12.0'
2039
- implementation 'androidx.appcompat:appcompat:1.6.1'
2040
- implementation 'com.google.android.material:material:1.11.0'
2041
- implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0'
2042
- implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.7.0'
2043
-
2044
- // ARCore (>= 1.31.0 includes Geospatial API)
2045
- implementation 'com.google.ar:core:1.41.0'
2046
-
2047
- // Sceneform (maintained fork)
2048
- implementation 'com.gorisse.thomas:sceneform:1.22.0'${geospatialDeps}${depthScanDeps}${handTrackingDeps}${authoringDeps}
2049
-
2050
- // Optional: Jetpack Compose
2051
- ${compiler.options.useJetpackCompose ? `implementation platform('androidx.compose:compose-bom:2024.01.00')
2052
- implementation 'androidx.compose.ui:ui'
2053
- implementation 'androidx.compose.material3:material3'
2054
- implementation 'androidx.activity:activity-compose:1.8.2'` : "// Compose disabled"}
2055
- }`;
2056
- }
2057
- function compileAction(compiler, action) {
2058
- const rawName = compiler.sanitizeName(action.name);
2059
- const name = rawName.charAt(0).toLowerCase() + rawName.slice(1);
2060
- compiler.emit(`fun ${name}() {`);
2061
- compiler.indentLevel++;
2062
- compiler.emit(
2063
- `android.util.Log.d("HoloScript", "Action: ${compiler.escapeStringValue(action.name, "Kotlin")}")`
2064
- );
2065
- compiler.emit("// Action implementation");
2066
- compiler.indentLevel--;
2067
- compiler.emit("}");
2068
- compiler.emit("");
2069
- }
2070
- var init_AndroidARGenerators = chunkHCCQLAA4_cjs.__esm({
2071
- "src/compiler/AndroidARGenerators.ts"() {
2072
- init_AndroidFeatureGenerators();
1427
+ var init_AndroidFeatureGenerators = chunkZHPMP447_cjs.__esm({
1428
+ "src/compiler/AndroidFeatureGenerators.ts"() {
1429
+ chunkN74QRJGP_cjs.init_npu_scene();
1430
+ chunkAWXFEAQL_cjs.init_spatial_authoring();
2073
1431
  }
2074
1432
  });
2075
1433
 
2076
1434
  // src/compiler/AndroidPeripheralGenerators.ts
2077
1435
  function hasHapticTraits(composition) {
2078
- const names = chunkDTGBOSEM_cjs.HAPTIC_FEEDBACK_TRAITS;
1436
+ const names = chunkAWXFEAQL_cjs.HAPTIC_FEEDBACK_TRAITS;
2079
1437
  for (const obj of composition.objects || []) {
2080
1438
  for (const trait of obj.traits || []) {
2081
1439
  const name = typeof trait === "string" ? trait : trait.name;
@@ -2174,7 +1532,7 @@ function emitHapticSetup(compiler, composition) {
2174
1532
  return compiler.lines.join("\n");
2175
1533
  }
2176
1534
  function hasNearbyTraits(composition) {
2177
- const names = chunkDTGBOSEM_cjs.NEARBY_CONNECTIONS_TRAITS;
1535
+ const names = chunkAWXFEAQL_cjs.NEARBY_CONNECTIONS_TRAITS;
2178
1536
  for (const obj of composition.objects || []) {
2179
1537
  for (const trait of obj.traits || []) {
2180
1538
  const name = typeof trait === "string" ? trait : trait.name;
@@ -2306,7 +1664,7 @@ function emitNearbySetup(compiler, composition) {
2306
1664
  return compiler.lines.join("\n");
2307
1665
  }
2308
1666
  function hasFoldableTraits(composition) {
2309
- const names = chunkDTGBOSEM_cjs.FOLDABLE_DISPLAY_TRAITS;
1667
+ const names = chunkAWXFEAQL_cjs.FOLDABLE_DISPLAY_TRAITS;
2310
1668
  for (const obj of composition.objects || []) {
2311
1669
  for (const trait of obj.traits || []) {
2312
1670
  const name = typeof trait === "string" ? trait : trait.name;
@@ -2399,7 +1757,7 @@ function emitFoldableSetup(compiler, composition) {
2399
1757
  return compiler.lines.join("\n");
2400
1758
  }
2401
1759
  function hasDexTraits(composition) {
2402
- const names = chunkDTGBOSEM_cjs.SAMSUNG_DEX_TRAITS;
1760
+ const names = chunkAWXFEAQL_cjs.SAMSUNG_DEX_TRAITS;
2403
1761
  for (const obj of composition.objects || []) {
2404
1762
  for (const trait of obj.traits || []) {
2405
1763
  const name = typeof trait === "string" ? trait : trait.name;
@@ -2494,7 +1852,7 @@ function emitDexSetup(compiler, composition) {
2494
1852
  return compiler.lines.join("\n");
2495
1853
  }
2496
1854
  function hasLensTraits(composition) {
2497
- const names = chunkDTGBOSEM_cjs.GOOGLE_LENS_TRAITS;
1855
+ const names = chunkAWXFEAQL_cjs.GOOGLE_LENS_TRAITS;
2498
1856
  for (const obj of composition.objects || []) {
2499
1857
  for (const trait of obj.traits || []) {
2500
1858
  const name = typeof trait === "string" ? trait : trait.name;
@@ -2512,7 +1870,7 @@ function emitLensSetup(compiler, composition) {
2512
1870
  for (const obj of composition.objects || []) {
2513
1871
  for (const trait of obj.traits || []) {
2514
1872
  const name = typeof trait === "string" ? trait : trait.name;
2515
- if (chunkDTGBOSEM_cjs.GOOGLE_LENS_TRAITS.includes(name)) {
1873
+ if (chunkAWXFEAQL_cjs.GOOGLE_LENS_TRAITS.includes(name)) {
2516
1874
  usedTraits.add(name);
2517
1875
  }
2518
1876
  }
@@ -2621,7 +1979,7 @@ function emitLensSetup(compiler, composition) {
2621
1979
  return compiler.lines.join("\n");
2622
1980
  }
2623
1981
  function hasWebXRTraits(composition) {
2624
- const names = chunkDTGBOSEM_cjs.WEBXR_TRAITS;
1982
+ const names = chunkAWXFEAQL_cjs.WEBXR_TRAITS;
2625
1983
  for (const obj of composition.objects || []) {
2626
1984
  for (const trait of obj.traits || []) {
2627
1985
  const name = typeof trait === "string" ? trait : trait.name;
@@ -2635,7 +1993,7 @@ function collectWebXRTraits(composition) {
2635
1993
  for (const obj of composition.objects || []) {
2636
1994
  for (const trait of obj.traits || []) {
2637
1995
  const name = typeof trait === "string" ? trait : trait.name;
2638
- if (chunkDTGBOSEM_cjs.WEBXR_TRAITS.includes(name)) {
1996
+ if (chunkAWXFEAQL_cjs.WEBXR_TRAITS.includes(name)) {
2639
1997
  usedTraits.add(name);
2640
1998
  }
2641
1999
  }
@@ -2923,20 +2281,20 @@ function emitWebXRSetup(compiler, composition) {
2923
2281
  compiler.emit("</html>");
2924
2282
  return compiler.lines.join("\n");
2925
2283
  }
2926
- var init_AndroidPeripheralGenerators = chunkHCCQLAA4_cjs.__esm({
2284
+ var init_AndroidPeripheralGenerators = chunkZHPMP447_cjs.__esm({
2927
2285
  "src/compiler/AndroidPeripheralGenerators.ts"() {
2928
- chunkDTGBOSEM_cjs.init_haptic_feedback();
2929
- chunkDTGBOSEM_cjs.init_nearby_connections();
2930
- chunkDTGBOSEM_cjs.init_foldable_display();
2931
- chunkDTGBOSEM_cjs.init_samsung_dex();
2932
- chunkDTGBOSEM_cjs.init_google_lens();
2933
- chunkDTGBOSEM_cjs.init_webxr();
2286
+ chunkAWXFEAQL_cjs.init_haptic_feedback();
2287
+ chunkAWXFEAQL_cjs.init_nearby_connections();
2288
+ chunkAWXFEAQL_cjs.init_foldable_display();
2289
+ chunkAWXFEAQL_cjs.init_samsung_dex();
2290
+ chunkAWXFEAQL_cjs.init_google_lens();
2291
+ chunkAWXFEAQL_cjs.init_webxr();
2934
2292
  }
2935
2293
  });
2936
2294
 
2937
2295
  // src/compiler/AndroidCompiler.ts
2938
2296
  var AndroidCompiler_exports = {};
2939
- chunkHCCQLAA4_cjs.__export(AndroidCompiler_exports, {
2297
+ chunkZHPMP447_cjs.__export(AndroidCompiler_exports, {
2940
2298
  AndroidCompiler: () => exports.AndroidCompiler,
2941
2299
  compileToAndroid: () => compileToAndroid
2942
2300
  });
@@ -2945,14 +2303,15 @@ function compileToAndroid(composition, options) {
2945
2303
  return Promise.resolve(compiler.compile(composition, "test-token", void 0));
2946
2304
  }
2947
2305
  exports.AndroidCompiler = void 0;
2948
- var init_AndroidCompiler = chunkHCCQLAA4_cjs.__esm({
2306
+ var init_AndroidCompiler = chunkZHPMP447_cjs.__esm({
2949
2307
  "src/compiler/AndroidCompiler.ts"() {
2950
- chunkLODTHGST_cjs.init_CompilerBase();
2308
+ chunkZK7KX5CD_cjs.init_CompilerBase();
2951
2309
  init_AndroidARGenerators();
2952
2310
  init_AndroidFeatureGenerators();
2311
+ init_AndroidSceneViewFeatureGenerators();
2953
2312
  init_AndroidPeripheralGenerators();
2954
- chunkFEWUHQNM_cjs.init_AndroidKotlinHelpers();
2955
- exports.AndroidCompiler = class extends chunkLODTHGST_cjs.CompilerBase {
2313
+ chunkCFVK26P4_cjs.init_AndroidKotlinHelpers();
2314
+ exports.AndroidCompiler = class extends chunkZK7KX5CD_cjs.CompilerBase {
2956
2315
  constructor(options = {}) {
2957
2316
  super();
2958
2317
  this.compilerName = "AndroidCompiler";
@@ -2976,11 +2335,26 @@ var init_AndroidCompiler = chunkHCCQLAA4_cjs.__esm({
2976
2335
  this.validateCompilerAccess(agentToken, outputPath);
2977
2336
  const result = {
2978
2337
  activityFile: generateActivityFile(this, composition),
2979
- stateFile: generateStateFile(this, composition),
2980
- nodeFactoryFile: generateNodeFactoryFile(this, composition),
2338
+ stateFile: generateStateFile(),
2339
+ nodeFactoryFile: generateNodeFactoryFile(),
2981
2340
  manifestFile: generateManifestFile(this, composition),
2982
2341
  buildGradle: generateBuildGradle(this, composition)
2983
2342
  };
2343
+ if (hasGeoAnchorTraits(composition)) {
2344
+ result.geoAnchorSetup = emitGeoAnchorSetup(this, composition);
2345
+ }
2346
+ if (hasGeospatialVPSTraits(composition)) {
2347
+ result.geospatialVPSSetup = emitGeospatialVPSSetup(this, composition);
2348
+ }
2349
+ if (hasDepthScanTraits(composition)) {
2350
+ result.depthScanSetup = emitDepthScanSetup(this, composition);
2351
+ }
2352
+ if (hasPortalARTraits(composition)) {
2353
+ result.portalARSetup = emitPortalARSetup(this, composition);
2354
+ }
2355
+ if (hasHandTrackingTraits(composition)) {
2356
+ result.handTrackingSetup = emitHandTrackingSetup(this, composition);
2357
+ }
2984
2358
  if (hasNPUSceneTraits(composition)) {
2985
2359
  result.npuSceneSetup = emitNPUSceneSetup(this, composition);
2986
2360
  }
@@ -3007,37 +2381,82 @@ var init_AndroidCompiler = chunkHCCQLAA4_cjs.__esm({
3007
2381
  }
3008
2382
  return result;
3009
2383
  }
2384
+ /**
2385
+ * Compile to a path-keyed map of reference-relative files (Android project layout).
2386
+ *
2387
+ * Mirrors AndroidXRCompiler.compileToFiles(): the native return is named fields
2388
+ * (AndroidCompileResult), so this adapter maps those fields onto the on-disk Android
2389
+ * project layout, letting the SAME byte-diff golden gate + committed-reference-app pattern
2390
+ * (QuestCompiler / AndroidXRCompiler) apply to the legacy plain-Android (ARCore) target.
2391
+ * Keys are POSIX-relative to the app project root (the dir holding settings.gradle.kts).
2392
+ *
2393
+ * Optional feature-setup fields (npuSceneSetup, hapticSetup, …) are emitted as extra
2394
+ * Kotlin files under the same package dir, keyed off the field name, so the gate covers
2395
+ * them when a trait pulls them in. The field→filename map is fixed so output is stable.
2396
+ */
2397
+ compileToFiles(composition, agentToken = "") {
2398
+ const r = this.compile(composition, agentToken);
2399
+ const pkgPath = this.options.packageName.replace(/\./g, "/");
2400
+ const javaRel = `app/src/main/java/${pkgPath}`;
2401
+ const files = {
2402
+ [`${javaRel}/${this.options.className}Activity.kt`]: r.activityFile,
2403
+ "app/src/main/AndroidManifest.xml": r.manifestFile,
2404
+ "app/build.gradle.kts": r.buildGradle
2405
+ };
2406
+ const featureFiles = {
2407
+ geoAnchorSetup: "GeoAnchorSetup.kt",
2408
+ geospatialVPSSetup: "GeospatialVPSSetup.kt",
2409
+ depthScanSetup: "DepthScanSetup.kt",
2410
+ portalARSetup: "PortalARSetup.kt",
2411
+ handTrackingSetup: "HandTrackingSetup.kt",
2412
+ npuSceneSetup: "NPUSceneSetup.kt",
2413
+ authoringSetup: "AuthoringSetup.kt",
2414
+ hapticSetup: "HapticSetup.kt",
2415
+ nearbySetup: "NearbySetup.kt",
2416
+ foldableSetup: "FoldableSetup.kt",
2417
+ dexSetup: "DexSetup.kt",
2418
+ lensSetup: "LensSetup.kt",
2419
+ webxrSetup: "WebXRSetup.kt"
2420
+ };
2421
+ for (const [field, fileName] of Object.entries(featureFiles)) {
2422
+ const content = r[field];
2423
+ if (typeof content === "string" && content.length > 0) {
2424
+ files[`${javaRel}/${fileName}`] = content;
2425
+ }
2426
+ }
2427
+ return files;
2428
+ }
3010
2429
  emit(line) {
3011
2430
  const indent = this.options.indent.repeat(this.indentLevel);
3012
2431
  this.lines.push(indent + line);
3013
2432
  }
3014
2433
  /** @deprecated Use sanitizeNameCapitalized from AndroidKotlinHelpers */
3015
2434
  sanitizeName(name) {
3016
- return chunkFEWUHQNM_cjs.sanitizeNameCapitalized(name);
2435
+ return chunkCFVK26P4_cjs.sanitizeNameCapitalized(name);
3017
2436
  }
3018
2437
  /** @deprecated Use getSceneformGeometry from AndroidKotlinHelpers */
3019
2438
  getSceneformGeometry(meshType) {
3020
- return chunkFEWUHQNM_cjs.getSceneformGeometry(meshType);
2439
+ return chunkCFVK26P4_cjs.getSceneformGeometry(meshType);
3021
2440
  }
3022
2441
  /** @deprecated Use findObjProp from AndroidKotlinHelpers */
3023
2442
  findObjProp(obj, key) {
3024
- return chunkFEWUHQNM_cjs.findObjProp(obj, key);
2443
+ return chunkCFVK26P4_cjs.findObjProp(obj, key);
3025
2444
  }
3026
2445
  /** @deprecated Use toKotlinType from AndroidKotlinHelpers */
3027
2446
  toKotlinType(value) {
3028
- return chunkFEWUHQNM_cjs.toKotlinType(value);
2447
+ return chunkCFVK26P4_cjs.toKotlinType(value);
3029
2448
  }
3030
2449
  /** @deprecated Use toKotlinValue from AndroidKotlinHelpers */
3031
2450
  toKotlinValue(value) {
3032
- return chunkFEWUHQNM_cjs.toKotlinValue(value, (s, t) => this.escapeStringValue(s, t));
2451
+ return chunkCFVK26P4_cjs.toKotlinValue(value, (s, t) => this.escapeStringValue(s, t));
3033
2452
  }
3034
2453
  /** @deprecated Use toAndroidColor from AndroidKotlinHelpers */
3035
2454
  toAndroidColor(value) {
3036
- return chunkFEWUHQNM_cjs.toAndroidColor(value);
2455
+ return chunkCFVK26P4_cjs.toAndroidColor(value);
3037
2456
  }
3038
2457
  /** @deprecated Use compositionHasTrait from AndroidKotlinHelpers */
3039
- compositionHasTrait(composition, traitName) {
3040
- return chunkFEWUHQNM_cjs.compositionHasTrait(composition, traitName);
2458
+ compositionHasTrait(composition, traitName2) {
2459
+ return chunkCFVK26P4_cjs.compositionHasTrait(composition, traitName2);
3041
2460
  }
3042
2461
  };
3043
2462
  }
@@ -3046,5 +2465,5 @@ var init_AndroidCompiler = chunkHCCQLAA4_cjs.__esm({
3046
2465
  exports.AndroidCompiler_exports = AndroidCompiler_exports;
3047
2466
  exports.compileToAndroid = compileToAndroid;
3048
2467
  exports.init_AndroidCompiler = init_AndroidCompiler;
3049
- //# sourceMappingURL=chunk-OS533P33.cjs.map
3050
- //# sourceMappingURL=chunk-OS533P33.cjs.map
2468
+ //# sourceMappingURL=chunk-2KKOYZYI.cjs.map
2469
+ //# sourceMappingURL=chunk-2KKOYZYI.cjs.map