@holoscript/core 6.0.4 → 6.1.2
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.
- package/LICENSE +21 -0
- package/README.md +3 -3
- package/bin/holoscript.cjs +3 -0
- package/dist/GLTFPipeline-SFIORFJU.js +16 -0
- package/dist/GLTFPipeline-VNNDPONV.cjs +37 -0
- package/dist/{HoloScriptPlusParser-BN6KVRCM.js → HoloScriptPlusParser-7FBIFUFC.js} +6 -5
- package/dist/{HoloScriptPlusParser-NC5FE6AL.cjs → HoloScriptPlusParser-A2W7OCN2.cjs} +17 -16
- package/dist/HoloScriptPlusParser-F2Z56FJR.js +10 -0
- package/dist/HoloScriptPlusParser-WKHRIH6T.cjs +27 -0
- package/dist/{USDZExporter-UWGWNMMD.cjs → USDZExporter-3FWJ25JI.cjs} +344 -16
- package/dist/{USDZExporter-NTMBNTDB.js → USDZExporter-D2HQLQYK.js} +344 -16
- package/dist/agents/index.cjs +19 -0
- package/dist/agents/index.d.ts +100 -0
- package/dist/agents/index.js +17 -0
- package/dist/chunk-22W6NGYN.js +725 -0
- package/dist/{chunk-5OEOHAAW.cjs → chunk-27MPVJVZ.cjs} +64 -28
- package/dist/{chunk-RVYPEYPX.js → chunk-2A7FURVO.js} +44 -8
- package/dist/{chunk-XCWFGZAA.js → chunk-2B7WVIDZ.js} +11 -8
- package/dist/{chunk-NDQNIJEH.js → chunk-2BSMSUCE.js} +250 -24
- package/dist/chunk-2HLIGOKU.cjs +5546 -0
- package/dist/{chunk-EONILVMF.js → chunk-2M2DPHKB.js} +4 -4
- package/dist/{chunk-G7CT3EMP.cjs → chunk-2YSNA2F2.cjs} +319 -47
- package/dist/{chunk-IWI6J7FX.js → chunk-33XCOVE3.js} +5 -5
- package/dist/chunk-3FOKASKO.cjs +348 -0
- package/dist/{chunk-DXJQDCFL.js → chunk-4C57PR42.js} +3 -3
- package/dist/{chunk-MPXBVFHQ.js → chunk-4N4SXXWF.js} +4 -3
- package/dist/chunk-4PDEPEQW.cjs +41 -0
- package/dist/chunk-4R6HPSHJ.js +2176 -0
- package/dist/chunk-4R6SBXDB.js +45 -0
- package/dist/chunk-4SY77NA4.cjs +413 -0
- package/dist/{chunk-YCXFCXDS.js → chunk-4UUKPCY4.js} +668 -110
- package/dist/{chunk-LGGRPKTV.cjs → chunk-52ULD552.cjs} +114 -35
- package/dist/{chunk-L4G4RLXX.js → chunk-5CKA5SXU.js} +438 -22
- package/dist/chunk-5FSKKMR7.cjs +2092 -0
- package/dist/{chunk-FF3Q7ADR.js → chunk-5JEU52DW.js} +5 -3
- package/dist/chunk-5N54COB6.cjs +327 -0
- package/dist/chunk-5S7RKFGR.cjs +446 -0
- package/dist/{chunk-KED34ILP.js → chunk-6ASWLXXN.js} +21 -9
- package/dist/chunk-6CTRH7HT.cjs +1985 -0
- package/dist/{chunk-CAUCGUEA.cjs → chunk-6EX3I5P4.cjs} +6 -6
- package/dist/chunk-6FGQNDR4.js +5731 -0
- package/dist/{chunk-72EQECGT.cjs → chunk-6KMK2UXT.cjs} +122 -46
- package/dist/{chunk-G4VZTCIB.js → chunk-6L4VE27M.js} +33 -23
- package/dist/{chunk-ATSKSYVE.cjs → chunk-6S6TKNEA.cjs} +6478 -1738
- package/dist/chunk-77V4GTCA.js +596 -0
- package/dist/{chunk-ZP4D3CSX.cjs → chunk-7AD52FRS.cjs} +16 -16
- package/dist/chunk-A6KINLZJ.js +236 -0
- package/dist/chunk-AIA52I7T.cjs +543 -0
- package/dist/chunk-AIX25INK.cjs +602 -0
- package/dist/{chunk-B5TCIAPQ.cjs → chunk-AO4I2Z7M.cjs} +17 -18
- package/dist/{chunk-Q5SJOGHQ.cjs → chunk-BPICAGBV.cjs} +324 -199
- package/dist/chunk-BRQJKJGT.cjs +20 -0
- package/dist/{chunk-3FXV5S25.cjs → chunk-C37BHB7N.cjs} +6 -3
- package/dist/{chunk-XUTX5CBW.js → chunk-CBJY23VL.js} +3 -3
- package/dist/chunk-CIWWXYHZ.cjs +50 -0
- package/dist/{chunk-XXINBTZK.cjs → chunk-DIL6DDDN.cjs} +101 -45
- package/dist/chunk-DMXC24WV.js +404 -0
- package/dist/{chunk-PMGODDJA.cjs → chunk-DTGBOSEM.cjs} +12 -12
- package/dist/chunk-E7JP3BS3.cjs +61 -0
- package/dist/{chunk-HJJLD366.js → chunk-EKBKLK7P.js} +3 -3
- package/dist/chunk-EKYL4PE3.cjs +404 -0
- package/dist/{chunk-UPJBDCVF.js → chunk-EMMC5CSQ.js} +12 -8
- package/dist/{chunk-GGHSW2NN.js → chunk-EOBB6A4B.js} +6389 -1718
- package/dist/chunk-EOFNVCM6.js +325 -0
- package/dist/{chunk-FHQVYCH2.js → chunk-ER4GATIU.js} +7 -7
- package/dist/{chunk-N5FTS757.cjs → chunk-EXKSFGSX.cjs} +7 -148
- package/dist/{chunk-LK5IAVH6.cjs → chunk-EXUP2BUM.cjs} +27 -27
- package/dist/chunk-FDSGHPAK.js +130 -0
- package/dist/chunk-FEWUHQNM.cjs +144 -0
- package/dist/{chunk-5TOFIR6L.js → chunk-FGGJQRLZ.js} +5 -142
- package/dist/chunk-FHP6LXJS.js +415 -0
- package/dist/{chunk-7LCYLPW2.cjs → chunk-FJPADH77.cjs} +7 -4
- package/dist/{chunk-T36DDXSF.js → chunk-FXKTYFYA.js} +150 -25
- package/dist/chunk-G2LS3RFO.js +623 -0
- package/dist/chunk-GCMWDSBZ.cjs +729 -0
- package/dist/chunk-GJNCFRJU.cjs +125 -0
- package/dist/{chunk-Q4QX3AET.cjs → chunk-GMP623FG.cjs} +16 -13
- package/dist/{chunk-XD6IYDUX.js → chunk-GN3KDX4W.js} +119 -43
- package/dist/{chunk-QLEAOI3Q.cjs → chunk-GQYKQSTC.cjs} +10 -10
- package/dist/chunk-GTU2Z2WW.cjs +262 -0
- package/dist/chunk-GZG4KA4E.js +529 -0
- package/dist/{chunk-BND3ST2K.cjs → chunk-H3MGK7TX.cjs} +42 -32
- package/dist/{chunk-XRKWN5PL.cjs → chunk-H5DZIHJP.cjs} +14 -18
- package/dist/{chunk-Z34RLXRA.cjs → chunk-HANL7K2Q.cjs} +65 -50
- package/dist/{chunk-3SAK5KFL.cjs → chunk-HCCQLAA4.cjs} +2 -11
- package/dist/{chunk-LXJ4667L.cjs → chunk-HGVXZDSK.cjs} +108 -20
- package/dist/{chunk-3FJCK5XA.js → chunk-HRODTEEO.js} +30 -10
- package/dist/{chunk-HQUEA5R6.cjs → chunk-HZCQO4JM.cjs} +6 -6
- package/dist/{chunk-S565K7NK.js → chunk-I2O7TW6B.js} +12 -8
- package/dist/chunk-IHESJZSW.js +4490 -0
- package/dist/{chunk-FSF7EQVA.cjs → chunk-IRWWS72C.cjs} +63 -22
- package/dist/{chunk-5O6TQC6M.cjs → chunk-IVIA7K75.cjs} +689 -127
- package/dist/chunk-IVY74O6C.js +247 -0
- package/dist/chunk-J32ZJZJH.js +554 -0
- package/dist/chunk-J56PTA46.cjs +639 -0
- package/dist/chunk-JD7CIZ33.js +1949 -0
- package/dist/{chunk-T7LEXZUZ.cjs → chunk-JIYN45TV.cjs} +14 -15
- package/dist/{chunk-FFKU7BTK.cjs → chunk-KHPCJRI3.cjs} +24 -21
- package/dist/chunk-KKFZ3B6J.cjs +557 -0
- package/dist/chunk-KPJL34Y7.cjs +186 -0
- package/dist/{chunk-HE7ULERA.cjs → chunk-KQTPCYTG.cjs} +128 -44
- package/dist/{chunk-OFKWH2IP.js → chunk-KX76JUQY.js} +3 -3
- package/dist/{chunk-33LSUQDD.cjs → chunk-L63H3SQ4.cjs} +43 -31
- package/dist/{chunk-K6EKD26I.js → chunk-LAOCQJ2M.js} +64 -8
- package/dist/chunk-LM2VU56C.cjs +37 -0
- package/dist/chunk-M56JSP4A.js +400 -0
- package/dist/chunk-MBOOR7X4.js +18 -0
- package/dist/{chunk-XWPNTWDN.cjs → chunk-MJVIRCUV.cjs} +31 -27
- package/dist/{chunk-SDAMZIRE.js → chunk-MSMIFMBL.js} +135 -18
- package/dist/{chunk-56IF4NTA.js → chunk-MXFUTKCO.js} +18 -18
- package/dist/{chunk-6UEHYZ7V.cjs → chunk-MXJ5SS53.cjs} +447 -31
- package/dist/chunk-MYY4PMWX.cjs +264 -0
- package/dist/chunk-N75IH2HY.js +258 -0
- package/dist/{chunk-GVUR45UF.cjs → chunk-NG77ATEW.cjs} +7 -6
- package/dist/chunk-NW5G5FBQ.js +215 -0
- package/dist/{chunk-E3FWRT3Z.js → chunk-OEFY723R.js} +28 -13
- package/dist/chunk-OEV5RMZO.cjs +3042 -0
- package/dist/{chunk-X4ZF6CNE.cjs → chunk-OIQYIIO3.cjs} +7 -7
- package/dist/{chunk-2CWOLHTE.js → chunk-OL46QLBJ.js} +3 -11
- package/dist/chunk-OPZ7XDDI.js +487 -0
- package/dist/chunk-OSYNRVOV.cjs +243 -0
- package/dist/{chunk-TEWCN33Y.js → chunk-P7YIA5LN.js} +91 -7
- package/dist/chunk-PGANYCAG.cjs +220 -0
- package/dist/{chunk-CS2EMTGF.js → chunk-QAVXL2IH.js} +62 -21
- package/dist/{chunk-T4NKMBDL.js → chunk-QCCBXSCE.js} +1666 -756
- package/dist/{chunk-F4IULT7N.js → chunk-QPOQ7VPI.js} +16 -13
- package/dist/{chunk-6XSERL6L.js → chunk-QTPMJRGS.js} +3108 -2827
- package/dist/{chunk-F3HH56EB.cjs → chunk-QWNQ523V.cjs} +1730 -823
- package/dist/{chunk-R7MA7QWV.js → chunk-R3IVNY6P.js} +102 -23
- package/dist/chunk-R75BSDH7.cjs +50 -0
- package/dist/chunk-RAXUF5DF.cjs +2196 -0
- package/dist/{chunk-BF2235SI.cjs → chunk-RMHC2VG7.cjs} +2876 -2592
- package/dist/chunk-RUXGBKPS.cjs +4517 -0
- package/dist/{chunk-UERJ3YJV.js → chunk-S5IFXW6E.js} +113 -9
- package/dist/{chunk-27LWW5FU.cjs → chunk-S6YWHCKV.cjs} +5 -5
- package/dist/{chunk-WB4Z63GG.js → chunk-SIEXCILW.js} +3 -3
- package/dist/{chunk-CLYEIWA5.cjs → chunk-SLU6UPJI.cjs} +5 -3
- package/dist/{chunk-LZ266PCM.cjs → chunk-T5J7ZKP3.cjs} +446 -60
- package/dist/chunk-TDCNJHWO.js +341 -0
- package/dist/{chunk-IHOUYQIA.js → chunk-TG7O4WBC.js} +5 -5
- package/dist/chunk-THCK6ECW.js +2085 -0
- package/dist/chunk-TJHVSBP2.js +439 -0
- package/dist/chunk-TK74TR4H.js +5541 -0
- package/dist/{chunk-CDPGV4DN.js → chunk-U4NBQJBY.js} +14 -15
- package/dist/{chunk-NOZZ46QU.js → chunk-UD3DSHZM.js} +10 -14
- package/dist/chunk-UDMYRFDZ.js +3038 -0
- package/dist/{chunk-WDW67DZB.cjs → chunk-UOIGFQXC.cjs} +90 -68
- package/dist/{chunk-BU7VWW2K.js → chunk-URG2SJLK.js} +14 -15
- package/dist/{chunk-EQV4R3EV.cjs → chunk-V73NPPTM.cjs} +152 -35
- package/dist/chunk-VECQYRXL.js +474 -0
- package/dist/chunk-VEXPG4WN.js +1989 -0
- package/dist/{chunk-LDP5OK6G.js → chunk-VMLKSV26.js} +5 -5
- package/dist/{chunk-5BGSECRJ.cjs → chunk-VSK7W3O5.cjs} +47 -27
- package/dist/chunk-VVKVQZI6.js +55 -0
- package/dist/{chunk-YQK5JNFK.js → chunk-W55Z7QIX.js} +103 -15
- package/dist/{chunk-KSGXLT74.cjs → chunk-W6P2GBHH.cjs} +3 -3
- package/dist/{chunk-IBDG74G2.cjs → chunk-W6RW64BB.cjs} +7 -7
- package/dist/chunk-WDT3JTGM.cjs +483 -0
- package/dist/{chunk-HPS76H7Q.js → chunk-WKX5AMOY.js} +3 -3
- package/dist/chunk-WNNE3PO3.js +34 -0
- package/dist/{chunk-XG23EUQX.cjs → chunk-WRLUBRKS.cjs} +538 -312
- package/dist/{chunk-IFNQFCTM.js → chunk-WRNEH5MO.js} +79 -8
- package/dist/{chunk-54FHG2MX.js → chunk-WRWEX5ZF.js} +7 -4
- package/dist/{chunk-KCQ5NDYC.cjs → chunk-X3GJPRVK.cjs} +154 -80
- package/dist/{chunk-7AGYRWKW.cjs → chunk-XFXGA5IW.cjs} +126 -22
- package/dist/{chunk-TQSZUOW5.cjs → chunk-XHIV6326.cjs} +4 -4
- package/dist/chunk-XJAN7CZG.cjs +432 -0
- package/dist/chunk-XL6INWKT.js +121 -0
- package/dist/{chunk-E3UALNFA.js → chunk-XMWZG36H.js} +4 -4
- package/dist/{chunk-BKIGPPVM.js → chunk-XSFNHP2E.js} +6 -3
- package/dist/{chunk-H5Z7NASB.js → chunk-XT6JY5W5.js} +25 -3
- package/dist/chunk-XXZJEFKW.cjs +490 -0
- package/dist/chunk-Y3MWXQSB.cjs +5737 -0
- package/dist/chunk-YF2I3MV3.js +46 -0
- package/dist/{chunk-V3NN3HPP.js → chunk-YIMN575O.js} +437 -52
- package/dist/chunk-YIVFJNYV.js +176 -0
- package/dist/{chunk-MD6KDHVE.cjs → chunk-YKGPCZEE.cjs} +10 -10
- package/dist/chunk-YQELFNJV.js +39 -0
- package/dist/chunk-Z5XMPRNC.cjs +5390 -0
- package/dist/{chunk-3FYZOR7S.cjs → chunk-ZDSYWBIE.cjs} +18 -18
- package/dist/{chunk-6TZPZCOJ.cjs → chunk-ZKSS47EV.cjs} +24 -19
- package/dist/chunk-ZUL5AVTX.cjs +1993 -0
- package/dist/chunk-ZXBZVXDW.js +5386 -0
- package/dist/{chunk-DMG7C4H2.js → chunk-ZZ7RO2UQ.js} +312 -44
- package/dist/cli/holoscript-runner.cjs +200 -204
- package/dist/cli/holoscript-runner.js +144 -148
- package/dist/codebase/index.cjs +1 -1
- package/dist/codebase/index.js +1 -1
- package/dist/compiler/agent-inference.cjs +10 -7
- package/dist/compiler/agent-inference.js +6 -3
- package/dist/compiler/android-xr.cjs +12 -7
- package/dist/compiler/android-xr.js +10 -5
- package/dist/compiler/android.cjs +12 -8
- package/dist/compiler/android.js +10 -6
- package/dist/compiler/ar.cjs +9 -6
- package/dist/compiler/ar.js +7 -4
- package/dist/compiler/babylon.cjs +12 -8
- package/dist/compiler/babylon.js +11 -7
- package/dist/compiler/business-quest.cjs +43 -0
- package/dist/compiler/business-quest.js +4 -0
- package/dist/compiler/coco.cjs +1 -1
- package/dist/compiler/coco.js +1 -1
- package/dist/compiler/context.cjs +25 -0
- package/dist/compiler/context.d.ts +28 -0
- package/dist/compiler/context.js +8 -0
- package/dist/compiler/domain-block-utils.cjs +155 -152
- package/dist/compiler/domain-block-utils.js +7 -4
- package/dist/compiler/dtdl.cjs +10 -7
- package/dist/compiler/dtdl.js +7 -4
- package/dist/compiler/gltf-pipeline.cjs +9 -9
- package/dist/compiler/gltf-pipeline.js +2 -2
- package/dist/compiler/godot.cjs +9 -6
- package/dist/compiler/godot.js +8 -5
- package/dist/compiler/incremental.cjs +12 -7
- package/dist/compiler/incremental.js +7 -2
- package/dist/compiler/index.cjs +3550 -268
- package/dist/compiler/index.d.ts +404 -21
- package/dist/compiler/index.js +3280 -138
- package/dist/compiler/ios.cjs +11 -8
- package/dist/compiler/ios.js +9 -6
- package/dist/compiler/llm-provider-capabilities.cjs +25 -0
- package/dist/compiler/llm-provider-capabilities.d.ts +43 -0
- package/dist/compiler/llm-provider-capabilities.js +8 -0
- package/dist/compiler/multi-layer.cjs +14 -10
- package/dist/compiler/multi-layer.js +13 -9
- package/dist/compiler/nodetoy.cjs +5 -5
- package/dist/compiler/nodetoy.js +2 -2
- package/dist/compiler/openxr.cjs +10 -6
- package/dist/compiler/openxr.js +9 -5
- package/dist/compiler/playcanvas.cjs +10 -7
- package/dist/compiler/playcanvas.js +9 -6
- package/dist/compiler/r3f.cjs +17 -13
- package/dist/compiler/r3f.d.ts +22 -0
- package/dist/compiler/r3f.js +12 -8
- package/dist/compiler/remotion.cjs +1 -1
- package/dist/compiler/remotion.js +1 -1
- package/dist/compiler/reproducibility.cjs +1 -1
- package/dist/compiler/reproducibility.js +1 -1
- package/dist/compiler/sdf.cjs +10 -7
- package/dist/compiler/sdf.js +8 -5
- package/dist/compiler/semantic-scene.cjs +1 -1
- package/dist/compiler/semantic-scene.js +1 -1
- package/dist/compiler/state.cjs +9 -5
- package/dist/compiler/state.js +7 -3
- package/dist/compiler/trait-composition.cjs +11 -7
- package/dist/compiler/trait-composition.js +7 -3
- package/dist/compiler/unity.cjs +10 -6
- package/dist/compiler/unity.js +9 -5
- package/dist/compiler/unreal.cjs +11 -7
- package/dist/compiler/unreal.js +9 -5
- package/dist/compiler/urdf.cjs +20 -13
- package/dist/compiler/urdf.js +8 -5
- package/dist/compiler/usd-physics.cjs +10 -7
- package/dist/compiler/usd-physics.js +7 -4
- package/dist/compiler/visionos.cjs +10 -6
- package/dist/compiler/visionos.js +9 -5
- package/dist/compiler/vrchat.cjs +10 -7
- package/dist/compiler/vrchat.js +8 -5
- package/dist/compiler/vrr.cjs +10 -7
- package/dist/compiler/vrr.js +8 -5
- package/dist/compiler/wasm.cjs +13 -10
- package/dist/compiler/wasm.js +8 -5
- package/dist/compiler/webgpu.cjs +9 -6
- package/dist/compiler/webgpu.js +8 -5
- package/dist/constants.d.ts +3 -2
- package/dist/coordinators/index.cjs +1266 -0
- package/dist/coordinators/index.d.ts +260 -0
- package/dist/coordinators/index.js +1259 -0
- package/dist/debugger.cjs +9 -7
- package/dist/debugger.js +7 -5
- package/dist/entries/interop.cjs +23 -21
- package/dist/entries/interop.js +5 -3
- package/dist/entries/scripting.cjs +18 -18
- package/dist/entries/scripting.js +8 -8
- package/dist/hololand/index.cjs +146 -0
- package/dist/hololand/index.d.ts +70 -0
- package/dist/hololand/index.js +5 -0
- package/dist/index.cjs +20332 -18121
- package/dist/index.d.ts +1477 -40
- package/dist/index.js +19451 -17638
- package/dist/math/tropical-spmv.cjs +45 -0
- package/dist/math/tropical-spmv.js +4 -0
- package/dist/math/vec3.cjs +14 -14
- package/dist/math/vec3.js +2 -2
- package/dist/{ml-dsa-PHCWUBPX.cjs → ml-dsa-FSKBTE3W.cjs} +177 -90
- package/dist/{ml-dsa-WYLJHJO6.js → ml-dsa-Z7JDKW4L.js} +158 -71
- package/dist/paper-0c-spike/index.cjs +150 -0
- package/dist/paper-0c-spike/index.d.ts +29 -0
- package/dist/paper-0c-spike/index.js +141 -0
- package/dist/parser.cjs +45 -11
- package/dist/parser.d.ts +11 -0
- package/dist/parser.js +10 -8
- package/dist/{playwright-RL6GY4F7.cjs → playwright-3AT3AKTV.cjs} +1985 -1985
- package/dist/{playwright-5OSAPTNH.js → playwright-VZPDVUEQ.js} +3 -3
- package/dist/reconstruction/index.cjs +153 -0
- package/dist/reconstruction/index.d.ts +105 -0
- package/dist/reconstruction/index.js +8 -0
- package/dist/runtime.cjs +7 -5
- package/dist/runtime.js +6 -4
- package/dist/self-improvement/index.cjs +563 -0
- package/dist/self-improvement/index.js +545 -0
- package/dist/storage/index.cjs +10 -9
- package/dist/storage/index.js +3 -2
- package/dist/testing.cjs +25 -0
- package/dist/testing.d.ts +70 -0
- package/dist/testing.js +4 -0
- package/dist/tools/index.d.ts +22 -1
- package/dist/traitDocs/traitDocs.cjs +33 -0
- package/dist/traitDocs/traitDocs.d.ts +69 -0
- package/dist/traitDocs/traitDocs.js +7 -0
- package/dist/traits/botanical-lotus.cjs +41 -0
- package/dist/traits/botanical-lotus.d.ts +172 -0
- package/dist/traits/botanical-lotus.js +4 -0
- package/dist/traits/engines/index.cjs +520 -0
- package/dist/traits/engines/index.js +380 -0
- package/dist/traits/index.cjs +17630 -7881
- package/dist/traits/index.d.ts +197 -0
- package/dist/traits/index.js +16573 -7193
- package/dist/traits/simulation-solver-factory.cjs +13 -0
- package/dist/traits/simulation-solver-factory.d.ts +23 -0
- package/dist/traits/simulation-solver-factory.js +4 -0
- package/dist/traits/webcam-gaze.cjs +35 -0
- package/dist/traits/webcam-gaze.d.ts +17 -0
- package/dist/traits/webcam-gaze.js +4 -0
- package/dist/type-checker.cjs +6 -5
- package/dist/type-checker.js +4 -3
- package/dist/world/index.cjs +947 -0
- package/dist/world/index.d.ts +147 -0
- package/dist/world/index.js +939 -0
- package/dist/world-model/index.cjs +1446 -0
- package/dist/world-model/index.d.ts +119 -0
- package/dist/world-model/index.js +1414 -0
- package/dist/wot/index.cjs +29 -0
- package/dist/wot/index.js +4 -0
- package/package.json +153 -61
- package/dist/GLTFPipeline-DEN36VNK.js +0 -12
- package/dist/GLTFPipeline-YPCAK236.cjs +0 -33
- package/dist/chunk-4XSNJCLC.cjs +0 -1859
- package/dist/chunk-A7PIMZGU.js +0 -263
- package/dist/chunk-BWFJEM5A.js +0 -5419
- package/dist/chunk-CBJSLA2E.cjs +0 -5423
- package/dist/chunk-K3JDKWGI.cjs +0 -270
- package/dist/chunk-LSW7P7ML.js +0 -3675
- package/dist/chunk-MEASWI2Y.js +0 -126
- package/dist/chunk-NCUKG4SK.cjs +0 -3075
- package/dist/chunk-Q5JT3YML.cjs +0 -129
- package/dist/chunk-QGKNANZ3.js +0 -3071
- package/dist/chunk-S2N5TNMA.js +0 -1855
- package/dist/chunk-TSH3MSQU.cjs +0 -129
- package/dist/chunk-WGMEAYBG.js +0 -126
- package/dist/chunk-X6SEAXAX.cjs +0 -3681
|
@@ -1,8 +1,646 @@
|
|
|
1
|
-
import { init_R3FCompiler, MATERIAL_PRESETS } from './chunk-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { init_R3FCompiler, MATERIAL_PRESETS } from './chunk-FXKTYFYA.js';
|
|
2
|
+
import { init_ProvenanceSemiring, ProvenanceSemiring } from './chunk-TJHVSBP2.js';
|
|
3
|
+
import { init_TraitCompositor, TraitCompositor } from './chunk-4C57PR42.js';
|
|
4
|
+
import { init_PlatformConditional, platformCategory, PLATFORM_CAPABILITIES, PLATFORM_CATEGORIES } from './chunk-GZG4KA4E.js';
|
|
5
|
+
import { init_DomainBlockCompilerMixin, compileDomainBlocks, inputToUSDA, compileInputBlock, navigationToUSDA, compileNavigationBlock, renderingToUSDA, compileRenderingBlock, proceduralToUSDA, compileProceduralBlock, web3ToUSDA, compileWeb3Block, architectureToUSDA, compileArchitectureBlock, musicToUSDA, compileMusicBlock, educationToUSDA, compileEducationBlock, datavizToUSDA, compileDataVizBlock, iotToUSDA, compileIoTBlock, compileRoboticsBlock, roboticsToUSDA, compileHealthcareBlock, healthcareToUSDA, compilePaymentBlock, paymentToUSDA, compileNarrativeBlock, narrativeToUSDA, compileWeatherBlock, weatherToUSD, compileAudioSourceBlock, audioSourceToUSD, compilePostProcessingBlock, postProcessingToUSD, compileParticleBlock, particlesToUSD, compilePhysicsBlock, compileMaterialBlock, materialToUSD } from './chunk-W55Z7QIX.js';
|
|
6
|
+
import { init_CompilerBase, CompilerBase } from './chunk-QTPMJRGS.js';
|
|
7
|
+
import { parsePipeline } from './chunk-J32ZJZJH.js';
|
|
8
|
+
import { __export, __esm } from './chunk-OL46QLBJ.js';
|
|
9
|
+
import { ANSCapabilityPath } from '@holoscript/core-types/ans';
|
|
10
|
+
|
|
11
|
+
// src/compiler/ThreeJSCompiler.ts
|
|
12
|
+
var ThreeJSCompiler_exports = {};
|
|
13
|
+
__export(ThreeJSCompiler_exports, {
|
|
14
|
+
ThreeJSCompiler: () => ThreeJSCompiler
|
|
15
|
+
});
|
|
16
|
+
var SHAPE_TO_THREE_GEOMETRY, ThreeJSCompiler;
|
|
17
|
+
var init_ThreeJSCompiler = __esm({
|
|
18
|
+
"src/compiler/ThreeJSCompiler.ts"() {
|
|
19
|
+
init_TraitCompositor();
|
|
20
|
+
init_ProvenanceSemiring();
|
|
21
|
+
init_CompilerBase();
|
|
22
|
+
SHAPE_TO_THREE_GEOMETRY = {
|
|
23
|
+
sphere: "SphereGeometry",
|
|
24
|
+
orb: "SphereGeometry",
|
|
25
|
+
cube: "BoxGeometry",
|
|
26
|
+
box: "BoxGeometry",
|
|
27
|
+
cylinder: "CylinderGeometry",
|
|
28
|
+
cone: "ConeGeometry",
|
|
29
|
+
pyramid: "ConeGeometry",
|
|
30
|
+
plane: "PlaneGeometry",
|
|
31
|
+
ground: "PlaneGeometry",
|
|
32
|
+
torus: "TorusGeometry",
|
|
33
|
+
ring: "TorusGeometry",
|
|
34
|
+
capsule: "CapsuleGeometry"
|
|
35
|
+
};
|
|
36
|
+
ThreeJSCompiler = class extends CompilerBase {
|
|
37
|
+
constructor(options = {}) {
|
|
38
|
+
super();
|
|
39
|
+
this.compilerName = "ThreeJSCompiler";
|
|
40
|
+
this.lines = [];
|
|
41
|
+
this.indentLevel = 0;
|
|
42
|
+
this.options = {
|
|
43
|
+
className: options.className ?? "GeneratedScene",
|
|
44
|
+
enableShadows: options.enableShadows ?? true,
|
|
45
|
+
enablePostProcessing: options.enablePostProcessing ?? false,
|
|
46
|
+
indent: options.indent ?? " ",
|
|
47
|
+
provenanceHash: options.provenanceHash ?? ""
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
getRequiredCapability() {
|
|
51
|
+
return ANSCapabilityPath.R3F;
|
|
52
|
+
}
|
|
53
|
+
compile(composition, agentToken, outputPath) {
|
|
54
|
+
this.validateCompilerAccess(agentToken, outputPath);
|
|
55
|
+
this.lines = [];
|
|
56
|
+
this.indentLevel = 0;
|
|
57
|
+
this.emit("// Auto-generated by HoloScript ThreeJSCompiler");
|
|
58
|
+
this.emit(
|
|
59
|
+
`// Source: composition "${this.escapeStringValue(composition.name, "TypeScript")}"`
|
|
60
|
+
);
|
|
61
|
+
if (this.options.provenanceHash) {
|
|
62
|
+
this.emit(`// Provenance Hash: ${this.options.provenanceHash}`);
|
|
63
|
+
}
|
|
64
|
+
this.emit("");
|
|
65
|
+
this.emitImports(composition);
|
|
66
|
+
this.emit("");
|
|
67
|
+
this.emit(`export class ${this.options.className} {`);
|
|
68
|
+
this.indent();
|
|
69
|
+
this.emit("private scene: THREE.Scene;");
|
|
70
|
+
this.emit("private renderer: THREE.WebGLRenderer;");
|
|
71
|
+
this.emit("private camera: THREE.PerspectiveCamera;");
|
|
72
|
+
this.emit("private canvas: HTMLCanvasElement;");
|
|
73
|
+
this.emit("private frameId: number = 0;");
|
|
74
|
+
this.emit("");
|
|
75
|
+
this.emit("constructor(canvas: HTMLCanvasElement) {");
|
|
76
|
+
this.indent();
|
|
77
|
+
this.emit("this.canvas = canvas;");
|
|
78
|
+
this.emit("this.scene = new THREE.Scene();");
|
|
79
|
+
this.emit(
|
|
80
|
+
"this.renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: false });"
|
|
81
|
+
);
|
|
82
|
+
this.emit("this.renderer.setPixelRatio(window.devicePixelRatio);");
|
|
83
|
+
this.emit("this.renderer.setSize(canvas.clientWidth, canvas.clientHeight);");
|
|
84
|
+
if (this.options.enableShadows) {
|
|
85
|
+
this.emit("this.renderer.shadowMap.enabled = true;");
|
|
86
|
+
this.emit("this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;");
|
|
87
|
+
}
|
|
88
|
+
this.emit(
|
|
89
|
+
"this.camera = new THREE.PerspectiveCamera(75, canvas.clientWidth / canvas.clientHeight, 0.1, 1000);"
|
|
90
|
+
);
|
|
91
|
+
this.emit("this.camera.position.set(0, 2, 10);");
|
|
92
|
+
this.dedent();
|
|
93
|
+
this.emit("}");
|
|
94
|
+
this.emit("");
|
|
95
|
+
this.emit("async build(): Promise<void> {");
|
|
96
|
+
this.indent();
|
|
97
|
+
if (composition.environment) this.emitEnvironment(composition.environment);
|
|
98
|
+
if (composition.lights?.length) {
|
|
99
|
+
for (const light of composition.lights) this.emitLight(light);
|
|
100
|
+
} else {
|
|
101
|
+
this.emit("// Default lighting");
|
|
102
|
+
this.emit("const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);");
|
|
103
|
+
this.emit("this.scene.add(ambientLight);");
|
|
104
|
+
this.emit("const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);");
|
|
105
|
+
this.emit("dirLight.position.set(5, 10, 5);");
|
|
106
|
+
if (this.options.enableShadows) {
|
|
107
|
+
this.emit("dirLight.castShadow = true;");
|
|
108
|
+
this.emit("dirLight.shadow.mapSize.set(2048, 2048);");
|
|
109
|
+
}
|
|
110
|
+
this.emit("this.scene.add(dirLight);");
|
|
111
|
+
this.emit("");
|
|
112
|
+
}
|
|
113
|
+
if (composition.camera) this.emitCamera(composition.camera);
|
|
114
|
+
if (composition.objects?.length) {
|
|
115
|
+
for (const obj of composition.objects) this.emitObject(obj);
|
|
116
|
+
}
|
|
117
|
+
if (composition.spatialGroups?.length) {
|
|
118
|
+
for (const g of composition.spatialGroups) this.emitGroup(g);
|
|
119
|
+
}
|
|
120
|
+
if (composition.zones?.length) {
|
|
121
|
+
for (const z of composition.zones) this.emitZone(z);
|
|
122
|
+
}
|
|
123
|
+
if (composition.audio?.length) {
|
|
124
|
+
for (const a of composition.audio) this.emitAudio(a);
|
|
125
|
+
}
|
|
126
|
+
this.emitRenderLoop();
|
|
127
|
+
this.dedent();
|
|
128
|
+
this.emit("}");
|
|
129
|
+
this.emit("");
|
|
130
|
+
this.emit("dispose(): void {");
|
|
131
|
+
this.indent();
|
|
132
|
+
this.emit("cancelAnimationFrame(this.frameId);");
|
|
133
|
+
this.emit("this.renderer.dispose();");
|
|
134
|
+
this.emit("this.scene.clear();");
|
|
135
|
+
this.dedent();
|
|
136
|
+
this.emit("}");
|
|
137
|
+
this.dedent();
|
|
138
|
+
this.emit("}");
|
|
139
|
+
return this.lines.join("\n");
|
|
140
|
+
}
|
|
141
|
+
// --- Imports ---
|
|
142
|
+
emitImports(_composition) {
|
|
143
|
+
this.emit('import * as THREE from "three";');
|
|
144
|
+
if (this.options.enablePostProcessing) {
|
|
145
|
+
this.emit('import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";');
|
|
146
|
+
this.emit(
|
|
147
|
+
'import { RenderPass } from "three/addons/postprocessing/RenderPass.js";'
|
|
148
|
+
);
|
|
149
|
+
this.emit(
|
|
150
|
+
'import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";'
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// --- Environment ---
|
|
155
|
+
emitEnvironment(env) {
|
|
156
|
+
for (const prop of env.properties) {
|
|
157
|
+
if (prop.key === "background" || prop.key === "skybox" || prop.key === "preset") {
|
|
158
|
+
if (typeof prop.value === "string" && prop.value.startsWith("#")) {
|
|
159
|
+
this.emit(`this.scene.background = new THREE.Color(${this.toThreeColorHex(prop.value)});`);
|
|
160
|
+
} else {
|
|
161
|
+
this.emit(`// skybox: "${prop.value}" \u2014 load via THREE.CubeTextureLoader`);
|
|
162
|
+
}
|
|
163
|
+
} else if (prop.key === "fog" && typeof prop.value === "object") {
|
|
164
|
+
const fog = prop.value;
|
|
165
|
+
const near = fog.near ?? 10;
|
|
166
|
+
const far = fog.far ?? 100;
|
|
167
|
+
const color = this.toThreeColorHex(fog.color ?? "#cccccc");
|
|
168
|
+
this.emit(`this.scene.fog = new THREE.Fog(${color}, ${near}, ${far});`);
|
|
169
|
+
} else if (prop.key === "ambient_light") {
|
|
170
|
+
this.emit(
|
|
171
|
+
`this.scene.add(new THREE.AmbientLight(0xffffff, ${prop.value ?? 0.5}));`
|
|
172
|
+
);
|
|
173
|
+
} else if (prop.key === "ground") {
|
|
174
|
+
this.emit(
|
|
175
|
+
`const groundGeom = new THREE.PlaneGeometry(100, 100);`
|
|
176
|
+
);
|
|
177
|
+
this.emit(
|
|
178
|
+
`const groundMat = new THREE.MeshStandardMaterial({ color: 0x888888, roughness: 0.8 });`
|
|
179
|
+
);
|
|
180
|
+
this.emit(`const ground = new THREE.Mesh(groundGeom, groundMat);`);
|
|
181
|
+
this.emit(`ground.rotation.x = -Math.PI / 2;`);
|
|
182
|
+
if (this.options.enableShadows) {
|
|
183
|
+
this.emit(`ground.receiveShadow = true;`);
|
|
184
|
+
}
|
|
185
|
+
this.emit(`this.scene.add(ground);`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
this.emit("");
|
|
189
|
+
}
|
|
190
|
+
// --- Objects ---
|
|
191
|
+
emitObject(obj, parentVar) {
|
|
192
|
+
const v = this.sanitizeName(obj.name);
|
|
193
|
+
let geom = "cube";
|
|
194
|
+
let modelSrc;
|
|
195
|
+
let textContent;
|
|
196
|
+
let position;
|
|
197
|
+
let rotation;
|
|
198
|
+
let scale;
|
|
199
|
+
let size;
|
|
200
|
+
const mat = {};
|
|
201
|
+
for (const p of obj.properties) {
|
|
202
|
+
switch (p.key) {
|
|
203
|
+
case "geometry":
|
|
204
|
+
case "mesh":
|
|
205
|
+
case "type":
|
|
206
|
+
if (typeof p.value === "string") geom = p.value;
|
|
207
|
+
break;
|
|
208
|
+
case "position":
|
|
209
|
+
if (Array.isArray(p.value)) position = p.value;
|
|
210
|
+
break;
|
|
211
|
+
case "rotation":
|
|
212
|
+
if (Array.isArray(p.value)) rotation = p.value;
|
|
213
|
+
break;
|
|
214
|
+
case "scale":
|
|
215
|
+
scale = p.value;
|
|
216
|
+
break;
|
|
217
|
+
case "size":
|
|
218
|
+
size = p.value;
|
|
219
|
+
break;
|
|
220
|
+
case "color":
|
|
221
|
+
mat.color = p.value;
|
|
222
|
+
break;
|
|
223
|
+
case "roughness":
|
|
224
|
+
mat.roughness = p.value;
|
|
225
|
+
break;
|
|
226
|
+
case "metalness":
|
|
227
|
+
case "metallic":
|
|
228
|
+
mat.metalness = p.value;
|
|
229
|
+
break;
|
|
230
|
+
case "opacity":
|
|
231
|
+
mat.opacity = p.value;
|
|
232
|
+
break;
|
|
233
|
+
case "emissive":
|
|
234
|
+
mat.emissive = p.value;
|
|
235
|
+
break;
|
|
236
|
+
case "emissive_intensity":
|
|
237
|
+
case "emissiveIntensity":
|
|
238
|
+
mat.emissiveIntensity = p.value;
|
|
239
|
+
break;
|
|
240
|
+
case "material":
|
|
241
|
+
if (typeof p.value === "object" && p.value !== null)
|
|
242
|
+
Object.assign(mat, p.value);
|
|
243
|
+
break;
|
|
244
|
+
case "model":
|
|
245
|
+
case "src":
|
|
246
|
+
case "source":
|
|
247
|
+
if (typeof p.value === "string") modelSrc = p.value;
|
|
248
|
+
break;
|
|
249
|
+
case "text":
|
|
250
|
+
if (typeof p.value === "string") textContent = p.value;
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
this.emit(`// Object: ${this.escapeStringValue(obj.name, "TypeScript")}`);
|
|
255
|
+
if (modelSrc) {
|
|
256
|
+
this.emit(`// GLTFLoader required for model: "${modelSrc}"`);
|
|
257
|
+
this.emit(`// import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";`);
|
|
258
|
+
this.emit(`const ${v}Loader = new GLTFLoader();`);
|
|
259
|
+
this.emit(
|
|
260
|
+
`const ${v}Gltf = await new Promise<THREE.Group>((resolve, reject) => { ${v}Loader.load("${modelSrc}", (g) => resolve(g.scene), undefined, reject); });`
|
|
261
|
+
);
|
|
262
|
+
this.emit(`const ${v} = ${v}Gltf;`);
|
|
263
|
+
this.emit(`this.scene.add(${v});`);
|
|
264
|
+
} else if (geom === "text" || textContent) {
|
|
265
|
+
this.emit(`// Text geometry requires THREE.FontLoader / troika-three-text`);
|
|
266
|
+
this.emit(`const ${v}Geom = new THREE.PlaneGeometry(2, 0.5);`);
|
|
267
|
+
this.emit(
|
|
268
|
+
`const ${v}Mat = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true });`
|
|
269
|
+
);
|
|
270
|
+
this.emit(`const ${v} = new THREE.Mesh(${v}Geom, ${v}Mat);`);
|
|
271
|
+
this.emit(`// Text content: "${textContent || ""}"`);
|
|
272
|
+
this.emit(`this.scene.add(${v});`);
|
|
273
|
+
} else {
|
|
274
|
+
const geomArgs = this.geometryArgs(geom, size);
|
|
275
|
+
const geomClass = SHAPE_TO_THREE_GEOMETRY[geom] ?? "BoxGeometry";
|
|
276
|
+
this.emit(`const ${v}Geom = new THREE.${geomClass}(${geomArgs});`);
|
|
277
|
+
const matProps = this.buildMaterialProps(mat);
|
|
278
|
+
this.emit(`const ${v}Mat = new THREE.MeshStandardMaterial({ ${matProps} });`);
|
|
279
|
+
this.emit(`const ${v} = new THREE.Mesh(${v}Geom, ${v}Mat);`);
|
|
280
|
+
this.emit(`this.scene.add(${v});`);
|
|
281
|
+
}
|
|
282
|
+
if (position)
|
|
283
|
+
this.emit(`${v}.position.set(${position[0]}, ${position[1]}, ${position[2]});`);
|
|
284
|
+
if (rotation)
|
|
285
|
+
this.emit(`${v}.rotation.set(${rotation[0]}, ${rotation[1]}, ${rotation[2]});`);
|
|
286
|
+
if (scale) {
|
|
287
|
+
if (Array.isArray(scale)) {
|
|
288
|
+
this.emit(`${v}.scale.set(${scale[0]}, ${scale[1]}, ${scale[2]});`);
|
|
289
|
+
} else {
|
|
290
|
+
this.emit(`${v}.scale.setScalar(${scale});`);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (parentVar) this.emit(`${parentVar}.add(${v});`);
|
|
294
|
+
const physicsTraits = (obj.traits || []).filter(
|
|
295
|
+
(t) => t.name === "physics" || t.name === "collidable"
|
|
296
|
+
);
|
|
297
|
+
if (physicsTraits.length > 0) {
|
|
298
|
+
const semiring = new ProvenanceSemiring();
|
|
299
|
+
const applications = physicsTraits.map((t) => ({
|
|
300
|
+
name: t.name,
|
|
301
|
+
config: t.config || {},
|
|
302
|
+
context: obj.provenance?.context
|
|
303
|
+
}));
|
|
304
|
+
const { config: physicsConfig } = semiring.add(applications);
|
|
305
|
+
const isStatic = (physicsConfig.type || "dynamic") === "static";
|
|
306
|
+
this.emit(
|
|
307
|
+
`// @physics \u2014 mass: ${physicsConfig.mass ?? 1}, type: ${isStatic ? "static" : "dynamic"}`
|
|
308
|
+
);
|
|
309
|
+
this.emit(
|
|
310
|
+
`// Use a physics library (cannon-es, rapier, ammo.js) to attach a rigid body to ${v}`
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
for (const trait of obj.traits || []) {
|
|
314
|
+
if (trait.name === "physics" || trait.name === "collidable") {
|
|
315
|
+
continue;
|
|
316
|
+
} else if (trait.name === "shadow") {
|
|
317
|
+
if (this.options.enableShadows) {
|
|
318
|
+
this.emit(`${v}.castShadow = true;`);
|
|
319
|
+
this.emit(`${v}.receiveShadow = true;`);
|
|
320
|
+
}
|
|
321
|
+
} else if (trait.name === "grabbable") {
|
|
322
|
+
this.emit(`// @grabbable \u2014 attach raycaster pointer-down handler to ${v}`);
|
|
323
|
+
} else if (trait.name === "hoverable") {
|
|
324
|
+
this.emit(`// @hoverable \u2014 attach raycaster pointer-move handler to ${v}`);
|
|
325
|
+
} else if (trait.name === "gaussian_splat") {
|
|
326
|
+
this.emit(
|
|
327
|
+
`// @gaussian_splat \u2014 use @mkkellogg/gaussian-splats-3d or three-splat for ${v}`
|
|
328
|
+
);
|
|
329
|
+
} else if (trait.name === "object_tracking") {
|
|
330
|
+
this.emit(`// @object_tracking \u2014 WebXR hit-test for ${v}`);
|
|
331
|
+
} else if (trait.name === "eye_tracked") {
|
|
332
|
+
this.emit(`// @eye_tracked \u2014 WebXR eye tracking for ${v}`);
|
|
333
|
+
} else if (trait.name === "controlnet") {
|
|
334
|
+
this.emit(
|
|
335
|
+
`// @controlnet(model: "${trait.config?.model || "canny"}") \u2014 route to inference API for ${v}`
|
|
336
|
+
);
|
|
337
|
+
} else {
|
|
338
|
+
this.emit(
|
|
339
|
+
`// @${this.escapeStringValue(trait.name, "TypeScript")}: ${JSON.stringify(trait.config || {})}`
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
if (obj.traits && obj.traits.length > 0) {
|
|
344
|
+
const traitNames = obj.traits.map((t) => t.name);
|
|
345
|
+
const compositor = new TraitCompositor();
|
|
346
|
+
const composed = compositor.compose(traitNames);
|
|
347
|
+
if (Object.keys(composed).length > 0) {
|
|
348
|
+
this.emit(`// TraitCompositor: composed ${traitNames.join(" + ")}`);
|
|
349
|
+
const composedProps = this.buildMaterialProps(composed);
|
|
350
|
+
if (composedProps) {
|
|
351
|
+
this.emit(
|
|
352
|
+
`Object.assign((${v}.material as THREE.MeshStandardMaterial), { ${composedProps} });`
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (obj.children?.length) {
|
|
358
|
+
for (const child of obj.children) this.emitObject(child, v);
|
|
359
|
+
}
|
|
360
|
+
this.emit("");
|
|
361
|
+
}
|
|
362
|
+
// --- Groups ---
|
|
363
|
+
emitGroup(group, parentVar) {
|
|
364
|
+
const v = this.sanitizeName(group.name);
|
|
365
|
+
this.emit(
|
|
366
|
+
`const ${v} = new THREE.Group(); // "${this.escapeStringValue(group.name, "TypeScript")}"`
|
|
367
|
+
);
|
|
368
|
+
for (const p of group.properties) {
|
|
369
|
+
if (p.key === "position" && Array.isArray(p.value))
|
|
370
|
+
this.emit(`${v}.position.set(${p.value[0]}, ${p.value[1]}, ${p.value[2]});`);
|
|
371
|
+
else if (p.key === "rotation" && Array.isArray(p.value))
|
|
372
|
+
this.emit(`${v}.rotation.set(${p.value[0]}, ${p.value[1]}, ${p.value[2]});`);
|
|
373
|
+
else if (p.key === "scale") {
|
|
374
|
+
if (Array.isArray(p.value)) {
|
|
375
|
+
this.emit(`${v}.scale.set(${p.value[0]}, ${p.value[1]}, ${p.value[2]});`);
|
|
376
|
+
} else {
|
|
377
|
+
this.emit(`${v}.scale.setScalar(${p.value});`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
const addTarget = parentVar ? parentVar : "this.scene";
|
|
382
|
+
this.emit(`${addTarget}.add(${v});`);
|
|
383
|
+
for (const obj of group.objects) this.emitObject(obj, v);
|
|
384
|
+
if (group.groups) {
|
|
385
|
+
for (const sub of group.groups) this.emitGroup(sub, v);
|
|
386
|
+
}
|
|
387
|
+
this.emit("");
|
|
388
|
+
}
|
|
389
|
+
// --- Lights ---
|
|
390
|
+
emitLight(light) {
|
|
391
|
+
const v = this.sanitizeName(light.name);
|
|
392
|
+
let position;
|
|
393
|
+
let color;
|
|
394
|
+
let intensity;
|
|
395
|
+
let direction;
|
|
396
|
+
let castShadow = false;
|
|
397
|
+
let angle;
|
|
398
|
+
let distance;
|
|
399
|
+
let penumbra;
|
|
400
|
+
for (const p of light.properties) {
|
|
401
|
+
if (p.key === "position" && Array.isArray(p.value)) position = p.value;
|
|
402
|
+
else if (p.key === "color") color = p.value;
|
|
403
|
+
else if (p.key === "intensity") intensity = p.value;
|
|
404
|
+
else if (p.key === "direction" && Array.isArray(p.value)) direction = p.value;
|
|
405
|
+
else if (p.key === "cast_shadow" || p.key === "castShadow") castShadow = !!p.value;
|
|
406
|
+
else if (p.key === "angle") angle = p.value;
|
|
407
|
+
else if (p.key === "distance") distance = p.value;
|
|
408
|
+
else if (p.key === "penumbra") penumbra = p.value;
|
|
409
|
+
}
|
|
410
|
+
const colorHex = this.toThreeColorHex(color ?? "#ffffff");
|
|
411
|
+
const intStr = intensity !== void 0 ? String(intensity) : "1.0";
|
|
412
|
+
switch (light.lightType) {
|
|
413
|
+
case "hemisphere":
|
|
414
|
+
case "ambient":
|
|
415
|
+
this.emit(`const ${v} = new THREE.AmbientLight(${colorHex}, ${intStr});`);
|
|
416
|
+
this.emit(`this.scene.add(${v});`);
|
|
417
|
+
break;
|
|
418
|
+
case "directional": {
|
|
419
|
+
this.emit(`const ${v} = new THREE.DirectionalLight(${colorHex}, ${intStr});`);
|
|
420
|
+
const pos = position ?? direction ?? [5, 10, 5];
|
|
421
|
+
this.emit(`${v}.position.set(${pos[0]}, ${pos[1]}, ${pos[2]});`);
|
|
422
|
+
if (castShadow && this.options.enableShadows) {
|
|
423
|
+
this.emit(`${v}.castShadow = true;`);
|
|
424
|
+
this.emit(`${v}.shadow.mapSize.set(2048, 2048);`);
|
|
425
|
+
this.emit(`${v}.shadow.camera.near = 0.1;`);
|
|
426
|
+
this.emit(`${v}.shadow.camera.far = 500;`);
|
|
427
|
+
}
|
|
428
|
+
this.emit(`this.scene.add(${v});`);
|
|
429
|
+
break;
|
|
430
|
+
}
|
|
431
|
+
case "point": {
|
|
432
|
+
const distStr = distance !== void 0 ? String(distance) : "0";
|
|
433
|
+
this.emit(
|
|
434
|
+
`const ${v} = new THREE.PointLight(${colorHex}, ${intStr}, ${distStr});`
|
|
435
|
+
);
|
|
436
|
+
if (position) this.emit(`${v}.position.set(${position[0]}, ${position[1]}, ${position[2]});`);
|
|
437
|
+
if (castShadow && this.options.enableShadows) this.emit(`${v}.castShadow = true;`);
|
|
438
|
+
this.emit(`this.scene.add(${v});`);
|
|
439
|
+
break;
|
|
440
|
+
}
|
|
441
|
+
case "spot": {
|
|
442
|
+
const angleRad = angle !== void 0 ? `${angle} * Math.PI / 180` : "Math.PI / 6";
|
|
443
|
+
const pen = penumbra ?? 0.1;
|
|
444
|
+
this.emit(
|
|
445
|
+
`const ${v} = new THREE.SpotLight(${colorHex}, ${intStr}, ${distance ?? 0}, ${angleRad}, ${pen});`
|
|
446
|
+
);
|
|
447
|
+
if (position) this.emit(`${v}.position.set(${position[0]}, ${position[1]}, ${position[2]});`);
|
|
448
|
+
if (castShadow && this.options.enableShadows) this.emit(`${v}.castShadow = true;`);
|
|
449
|
+
this.emit(`this.scene.add(${v});`);
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
default:
|
|
453
|
+
this.emit(`// Light "${light.lightType}" not mapped \u2014 using AmbientLight fallback`);
|
|
454
|
+
this.emit(`const ${v} = new THREE.AmbientLight(${colorHex}, ${intStr});`);
|
|
455
|
+
this.emit(`this.scene.add(${v});`);
|
|
456
|
+
}
|
|
457
|
+
this.emit("");
|
|
458
|
+
}
|
|
459
|
+
// --- Camera ---
|
|
460
|
+
emitCamera(camera) {
|
|
461
|
+
let position;
|
|
462
|
+
let target;
|
|
463
|
+
let fov;
|
|
464
|
+
let near;
|
|
465
|
+
let far;
|
|
466
|
+
for (const p of camera.properties) {
|
|
467
|
+
if (p.key === "position" && Array.isArray(p.value)) position = p.value;
|
|
468
|
+
else if (p.key === "target" && Array.isArray(p.value)) target = p.value;
|
|
469
|
+
else if (p.key === "fov") fov = p.value;
|
|
470
|
+
else if (p.key === "near") near = p.value;
|
|
471
|
+
else if (p.key === "far") far = p.value;
|
|
472
|
+
}
|
|
473
|
+
if (fov !== void 0) this.emit(`this.camera.fov = ${fov};`);
|
|
474
|
+
if (near !== void 0) this.emit(`this.camera.near = ${near};`);
|
|
475
|
+
if (far !== void 0) this.emit(`this.camera.far = ${far};`);
|
|
476
|
+
if (position)
|
|
477
|
+
this.emit(
|
|
478
|
+
`this.camera.position.set(${position[0]}, ${position[1]}, ${position[2]});`
|
|
479
|
+
);
|
|
480
|
+
if (target) {
|
|
481
|
+
this.emit(
|
|
482
|
+
`this.camera.lookAt(new THREE.Vector3(${target[0]}, ${target[1]}, ${target[2]}));`
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
this.emit(`this.camera.updateProjectionMatrix();`);
|
|
486
|
+
this.emit("");
|
|
487
|
+
}
|
|
488
|
+
// --- Audio ---
|
|
489
|
+
emitAudio(audio) {
|
|
490
|
+
const v = this.sanitizeName(audio.name);
|
|
491
|
+
let src = "";
|
|
492
|
+
let loop = false;
|
|
493
|
+
let volume = 1;
|
|
494
|
+
let spatial = false;
|
|
495
|
+
for (const p of audio.properties) {
|
|
496
|
+
if (p.key === "src" || p.key === "source") src = String(p.value);
|
|
497
|
+
else if (p.key === "loop") loop = !!p.value;
|
|
498
|
+
else if (p.key === "volume") volume = p.value;
|
|
499
|
+
else if (p.key === "spatial") spatial = !!p.value;
|
|
500
|
+
}
|
|
501
|
+
if (spatial) {
|
|
502
|
+
this.emit(`const ${v}Listener = new THREE.AudioListener();`);
|
|
503
|
+
this.emit(`this.camera.add(${v}Listener);`);
|
|
504
|
+
this.emit(`const ${v} = new THREE.PositionalAudio(${v}Listener);`);
|
|
505
|
+
} else {
|
|
506
|
+
this.emit(`const ${v}Listener = new THREE.AudioListener();`);
|
|
507
|
+
this.emit(`this.camera.add(${v}Listener);`);
|
|
508
|
+
this.emit(`const ${v} = new THREE.Audio(${v}Listener);`);
|
|
509
|
+
}
|
|
510
|
+
this.emit(`const ${v}Loader = new THREE.AudioLoader();`);
|
|
511
|
+
this.emit(
|
|
512
|
+
`${v}Loader.load("${src}", (buffer) => { ${v}.setBuffer(buffer); ${v}.setLoop(${loop}); ${v}.setVolume(${volume}); ${v}.play(); });`
|
|
513
|
+
);
|
|
514
|
+
this.emit("");
|
|
515
|
+
}
|
|
516
|
+
// --- Zones ---
|
|
517
|
+
emitZone(zone) {
|
|
518
|
+
const v = this.sanitizeName(zone.name);
|
|
519
|
+
let shape = "box";
|
|
520
|
+
let position;
|
|
521
|
+
let size;
|
|
522
|
+
let radius;
|
|
523
|
+
for (const p of zone.properties) {
|
|
524
|
+
if (p.key === "shape") shape = String(p.value);
|
|
525
|
+
else if (p.key === "position" && Array.isArray(p.value)) position = p.value;
|
|
526
|
+
else if (p.key === "size") size = p.value;
|
|
527
|
+
else if (p.key === "radius") radius = p.value;
|
|
528
|
+
}
|
|
529
|
+
if (shape === "sphere") {
|
|
530
|
+
this.emit(
|
|
531
|
+
`const ${v}Geom = new THREE.SphereGeometry(${radius ?? 5}, 16, 16);`
|
|
532
|
+
);
|
|
533
|
+
} else {
|
|
534
|
+
const s = Array.isArray(size) ? size : [size ?? 5, size ?? 5, size ?? 5];
|
|
535
|
+
this.emit(`const ${v}Geom = new THREE.BoxGeometry(${s[0]}, ${s[1]}, ${s[2]});`);
|
|
536
|
+
}
|
|
537
|
+
this.emit(
|
|
538
|
+
`const ${v}Mat = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true, visible: false });`
|
|
539
|
+
);
|
|
540
|
+
this.emit(`const ${v} = new THREE.Mesh(${v}Geom, ${v}Mat);`);
|
|
541
|
+
if (position) this.emit(`${v}.position.set(${position[0]}, ${position[1]}, ${position[2]});`);
|
|
542
|
+
this.emit(`this.scene.add(${v}); // trigger zone (invisible)`);
|
|
543
|
+
if (zone.handlers?.length) {
|
|
544
|
+
this.emit(
|
|
545
|
+
`// Zone handlers: attach raycaster intersection checks for ${v}`
|
|
546
|
+
);
|
|
547
|
+
for (const h of zone.handlers) {
|
|
548
|
+
this.emit(
|
|
549
|
+
`// on ${this.escapeStringValue(h.event, "TypeScript")}: implement via raycaster.intersectObject(${v})`
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
this.emit("");
|
|
554
|
+
}
|
|
555
|
+
// --- Render Loop ---
|
|
556
|
+
emitRenderLoop() {
|
|
557
|
+
this.emit("// Render loop");
|
|
558
|
+
this.emit("const animate = (): void => {");
|
|
559
|
+
this.indent();
|
|
560
|
+
this.emit("this.frameId = requestAnimationFrame(animate);");
|
|
561
|
+
this.emit("this.renderer.render(this.scene, this.camera);");
|
|
562
|
+
this.dedent();
|
|
563
|
+
this.emit("};");
|
|
564
|
+
this.emit("animate();");
|
|
565
|
+
this.emit("");
|
|
566
|
+
this.emit("// Resize handler");
|
|
567
|
+
this.emit('window.addEventListener("resize", () => {');
|
|
568
|
+
this.indent();
|
|
569
|
+
this.emit("const w = this.canvas.clientWidth, h = this.canvas.clientHeight;");
|
|
570
|
+
this.emit("this.renderer.setSize(w, h);");
|
|
571
|
+
this.emit("this.camera.aspect = w / h;");
|
|
572
|
+
this.emit("this.camera.updateProjectionMatrix();");
|
|
573
|
+
this.dedent();
|
|
574
|
+
this.emit("});");
|
|
575
|
+
}
|
|
576
|
+
// --- Value Helpers ---
|
|
577
|
+
toThreeColorHex(value) {
|
|
578
|
+
if (typeof value === "string" && value.startsWith("#")) {
|
|
579
|
+
return `0x${value.slice(1)}`;
|
|
580
|
+
}
|
|
581
|
+
if (typeof value === "number") return `0x${value.toString(16).padStart(6, "0")}`;
|
|
582
|
+
return "0xffffff";
|
|
583
|
+
}
|
|
584
|
+
buildMaterialProps(mat) {
|
|
585
|
+
const parts = [];
|
|
586
|
+
if (mat.color !== void 0) {
|
|
587
|
+
parts.push(`color: ${this.toThreeColorHex(mat.color)}`);
|
|
588
|
+
}
|
|
589
|
+
if (mat.roughness !== void 0) parts.push(`roughness: ${mat.roughness}`);
|
|
590
|
+
if (mat.metalness !== void 0) parts.push(`metalness: ${mat.metalness}`);
|
|
591
|
+
if (mat.opacity !== void 0 && mat.opacity < 1) {
|
|
592
|
+
parts.push(`opacity: ${mat.opacity}`, "transparent: true");
|
|
593
|
+
}
|
|
594
|
+
if (mat.emissive !== void 0) {
|
|
595
|
+
parts.push(`emissive: ${this.toThreeColorHex(mat.emissive)}`);
|
|
596
|
+
}
|
|
597
|
+
if (mat.emissiveIntensity !== void 0) {
|
|
598
|
+
parts.push(`emissiveIntensity: ${mat.emissiveIntensity}`);
|
|
599
|
+
}
|
|
600
|
+
return parts.join(", ");
|
|
601
|
+
}
|
|
602
|
+
geometryArgs(type, size) {
|
|
603
|
+
const s = typeof size === "number" ? size : 1;
|
|
604
|
+
switch (type) {
|
|
605
|
+
case "sphere":
|
|
606
|
+
case "orb":
|
|
607
|
+
return `${s * 0.5}, 32, 32`;
|
|
608
|
+
case "cube":
|
|
609
|
+
case "box":
|
|
610
|
+
return `${s}, ${s}, ${s}`;
|
|
611
|
+
case "cylinder":
|
|
612
|
+
return `${s * 0.5}, ${s * 0.5}, ${s * 2}, 32`;
|
|
613
|
+
case "cone":
|
|
614
|
+
case "pyramid":
|
|
615
|
+
return `${s * 0.5}, ${s * 2}, ${type === "pyramid" ? 4 : 32}`;
|
|
616
|
+
case "plane":
|
|
617
|
+
case "ground":
|
|
618
|
+
return `${s}, ${s}`;
|
|
619
|
+
case "torus":
|
|
620
|
+
case "ring":
|
|
621
|
+
return `${s * 0.5}, ${s * 0.15}, 16, 64`;
|
|
622
|
+
case "capsule":
|
|
623
|
+
return `${s * 0.3}, ${s * 0.6}, 4, 16`;
|
|
624
|
+
default:
|
|
625
|
+
return `${s}, ${s}, ${s}`;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
// --- Emit Helpers ---
|
|
629
|
+
emit(line) {
|
|
630
|
+
this.lines.push(this.options.indent.repeat(this.indentLevel) + line);
|
|
631
|
+
}
|
|
632
|
+
indent() {
|
|
633
|
+
this.indentLevel++;
|
|
634
|
+
}
|
|
635
|
+
dedent() {
|
|
636
|
+
this.indentLevel = Math.max(0, this.indentLevel - 1);
|
|
637
|
+
}
|
|
638
|
+
sanitizeName(name) {
|
|
639
|
+
return name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
});
|
|
6
644
|
|
|
7
645
|
// src/compiler/A2AAgentCardCompiler.ts
|
|
8
646
|
var A2AAgentCardCompiler_exports = {};
|
|
@@ -286,26 +924,10 @@ var init_A2AAgentCardCompiler = __esm({
|
|
|
286
924
|
* Compile a domain-specific block into a specialized skill.
|
|
287
925
|
*/
|
|
288
926
|
compileDomainBlockSkill(block) {
|
|
289
|
-
const domainTags = {
|
|
290
|
-
iot: ["iot", "sensor", "telemetry", "digital-twin"],
|
|
291
|
-
robotics: ["robotics", "control", "actuator", "simulation"],
|
|
292
|
-
dataviz: ["data-visualization", "analytics", "dashboard"],
|
|
293
|
-
education: ["education", "learning", "curriculum"],
|
|
294
|
-
healthcare: ["healthcare", "medical", "monitoring"],
|
|
295
|
-
music: ["music", "audio", "composition"],
|
|
296
|
-
architecture: ["architecture", "building", "design"],
|
|
297
|
-
web3: ["web3", "blockchain", "smart-contract"],
|
|
298
|
-
physics: ["physics", "simulation", "collision"],
|
|
299
|
-
material: ["material", "rendering", "pbr"],
|
|
300
|
-
vfx: ["vfx", "particles", "visual-effects"],
|
|
301
|
-
weather: ["weather", "atmosphere", "environmental"],
|
|
302
|
-
navigation: ["navigation", "pathfinding", "ai"],
|
|
303
|
-
procedural: ["procedural", "generation", "algorithms"]
|
|
304
|
-
};
|
|
305
927
|
const tags = [
|
|
306
928
|
block.domain,
|
|
307
929
|
block.keyword,
|
|
308
|
-
...domainTags
|
|
930
|
+
...block.domainTags?.length ? block.domainTags : [],
|
|
309
931
|
...block.traits
|
|
310
932
|
];
|
|
311
933
|
return {
|
|
@@ -1438,695 +2060,21 @@ var init_NIRCompiler = __esm({
|
|
|
1438
2060
|
}
|
|
1439
2061
|
});
|
|
1440
2062
|
|
|
1441
|
-
// src/parser/PipelineParser.ts
|
|
1442
|
-
function stripComments(source) {
|
|
1443
|
-
const lines = source.split("\n");
|
|
1444
|
-
return lines.map((line) => {
|
|
1445
|
-
let inString = null;
|
|
1446
|
-
for (let i = 0; i < line.length; i++) {
|
|
1447
|
-
const ch = line[i];
|
|
1448
|
-
if (inString) {
|
|
1449
|
-
if (ch === inString && line[i - 1] !== "\\") inString = null;
|
|
1450
|
-
} else if (ch === '"' || ch === "'") {
|
|
1451
|
-
inString = ch;
|
|
1452
|
-
} else if (ch === "/" && line[i + 1] === "/") {
|
|
1453
|
-
return line.substring(0, i);
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
return line;
|
|
1457
|
-
}).join("\n");
|
|
1458
|
-
}
|
|
1459
|
-
function parseDuration(value) {
|
|
1460
|
-
const match = value.match(/^(\d+)(s|m|h|d)$/);
|
|
1461
|
-
if (!match) return void 0;
|
|
1462
|
-
return { value: parseInt(match[1], 10), unit: match[2] };
|
|
1463
|
-
}
|
|
1464
|
-
function extractBlock(source, keyword, name) {
|
|
1465
|
-
const results = [];
|
|
1466
|
-
const namePattern = "(\\w+)";
|
|
1467
|
-
const regex = new RegExp(`${keyword}\\s+${namePattern}\\s*\\{`, "g");
|
|
1468
|
-
let match;
|
|
1469
|
-
while ((match = regex.exec(source)) !== null) {
|
|
1470
|
-
const blockName = match[1];
|
|
1471
|
-
const startLine = source.substring(0, match.index).split("\n").length;
|
|
1472
|
-
const startIdx = source.indexOf("{", match.index);
|
|
1473
|
-
let depth = 1;
|
|
1474
|
-
let i = startIdx + 1;
|
|
1475
|
-
while (i < source.length && depth > 0) {
|
|
1476
|
-
if (source[i] === "{") depth++;
|
|
1477
|
-
if (source[i] === "}") depth--;
|
|
1478
|
-
i++;
|
|
1479
|
-
}
|
|
1480
|
-
results.push({
|
|
1481
|
-
content: source.substring(startIdx + 1, i - 1),
|
|
1482
|
-
name: blockName,
|
|
1483
|
-
startLine
|
|
1484
|
-
});
|
|
1485
|
-
}
|
|
1486
|
-
return results;
|
|
1487
|
-
}
|
|
1488
|
-
function parseProperties(content) {
|
|
1489
|
-
const props = {};
|
|
1490
|
-
const lines = content.split("\n");
|
|
1491
|
-
for (const line of lines) {
|
|
1492
|
-
const trimmed = line.trim();
|
|
1493
|
-
if (!trimmed || trimmed.startsWith("//")) continue;
|
|
1494
|
-
const kvMatch = trimmed.match(/^(\w+)\s*:\s+(.+)$/);
|
|
1495
|
-
if (kvMatch) {
|
|
1496
|
-
const key = kvMatch[1];
|
|
1497
|
-
let val = kvMatch[2].trim();
|
|
1498
|
-
if (typeof val === "string" && val.endsWith(",")) {
|
|
1499
|
-
val = val.slice(0, -1).trim();
|
|
1500
|
-
}
|
|
1501
|
-
if (typeof val === "string") {
|
|
1502
|
-
const strVal = val;
|
|
1503
|
-
if (strVal.startsWith('"') && strVal.endsWith('"')) {
|
|
1504
|
-
val = strVal.slice(1, -1);
|
|
1505
|
-
} else if (strVal.startsWith("'") && strVal.endsWith("'")) {
|
|
1506
|
-
val = strVal.slice(1, -1);
|
|
1507
|
-
} else if (strVal === "true") {
|
|
1508
|
-
val = true;
|
|
1509
|
-
} else if (strVal === "false") {
|
|
1510
|
-
val = false;
|
|
1511
|
-
} else if (/^\d+$/.test(strVal)) {
|
|
1512
|
-
val = parseInt(strVal, 10);
|
|
1513
|
-
} else if (/^\d+\.\d+$/.test(strVal)) {
|
|
1514
|
-
val = parseFloat(strVal);
|
|
1515
|
-
}
|
|
1516
|
-
}
|
|
1517
|
-
props[key] = val;
|
|
1518
|
-
}
|
|
1519
|
-
}
|
|
1520
|
-
return props;
|
|
1521
|
-
}
|
|
1522
|
-
function parseNestedBlock(content, keyword) {
|
|
1523
|
-
const blocks = extractBlock(content, keyword);
|
|
1524
|
-
if (blocks.length === 0) return void 0;
|
|
1525
|
-
return parseProperties(blocks[0].content);
|
|
1526
|
-
}
|
|
1527
|
-
function parseFieldMappings(content) {
|
|
1528
|
-
const mappings = [];
|
|
1529
|
-
const lines = content.split("\n");
|
|
1530
|
-
for (const line of lines) {
|
|
1531
|
-
const trimmed = line.trim();
|
|
1532
|
-
if (!trimmed || trimmed.startsWith("//")) continue;
|
|
1533
|
-
const mapMatch = trimmed.match(/^(\w+)\s*->\s*(\w+)(?:\s*:\s*(.+))?$/);
|
|
1534
|
-
if (mapMatch) {
|
|
1535
|
-
const transforms = mapMatch[3] ? mapMatch[3].split(":").map((t) => t.trim()).filter(Boolean) : [];
|
|
1536
|
-
mappings.push({
|
|
1537
|
-
from: mapMatch[1],
|
|
1538
|
-
to: mapMatch[2],
|
|
1539
|
-
transforms
|
|
1540
|
-
});
|
|
1541
|
-
}
|
|
1542
|
-
}
|
|
1543
|
-
return mappings;
|
|
1544
|
-
}
|
|
1545
|
-
function parseValidateFields(content) {
|
|
1546
|
-
const fields = [];
|
|
1547
|
-
const lines = content.split("\n");
|
|
1548
|
-
for (const line of lines) {
|
|
1549
|
-
const trimmed = line.trim();
|
|
1550
|
-
if (!trimmed || trimmed.startsWith("//")) continue;
|
|
1551
|
-
const vMatch = trimmed.match(/^(\w+)\s*:\s*(.+)$/);
|
|
1552
|
-
if (vMatch) {
|
|
1553
|
-
const rules = vMatch[2].split(",").map((r) => r.trim()).filter(Boolean);
|
|
1554
|
-
fields.push({ field: vMatch[1], rules });
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
return fields;
|
|
1558
|
-
}
|
|
1559
|
-
function parseBranchRoutes(content) {
|
|
1560
|
-
const routes = [];
|
|
1561
|
-
const lines = content.split("\n");
|
|
1562
|
-
for (const line of lines) {
|
|
1563
|
-
const trimmed = line.trim();
|
|
1564
|
-
if (!trimmed || trimmed.startsWith("//")) continue;
|
|
1565
|
-
const whenMatch = trimmed.match(/^when\s+(.+?)\s*->\s*sink\s+(\w+)$/);
|
|
1566
|
-
if (whenMatch) {
|
|
1567
|
-
routes.push({ condition: whenMatch[1], sinkName: whenMatch[2] });
|
|
1568
|
-
continue;
|
|
1569
|
-
}
|
|
1570
|
-
const defaultMatch = trimmed.match(/^default\s*->\s*sink\s+(\w+)$/);
|
|
1571
|
-
if (defaultMatch) {
|
|
1572
|
-
routes.push({ condition: "default", sinkName: defaultMatch[1] });
|
|
1573
|
-
}
|
|
1574
|
-
}
|
|
1575
|
-
return routes;
|
|
1576
|
-
}
|
|
1577
|
-
function parseStringArray(content) {
|
|
1578
|
-
const match = content.match(/\[([\s\S]*?)\]/);
|
|
1579
|
-
if (!match) return [];
|
|
1580
|
-
return match[1].split(",").map((s) => s.trim().replace(/^["']|["']$/g, "")).filter(Boolean);
|
|
1581
|
-
}
|
|
1582
|
-
function parsePipeline(source) {
|
|
1583
|
-
const errors = [];
|
|
1584
|
-
const clean = stripComments(source);
|
|
1585
|
-
const pipelineBlocks = extractBlock(clean, "pipeline");
|
|
1586
|
-
if (pipelineBlocks.length === 0) {
|
|
1587
|
-
const quotedMatch = clean.match(/pipeline\s+["']([^"']+)["']\s*\{/);
|
|
1588
|
-
if (!quotedMatch) {
|
|
1589
|
-
return { success: false, errors: [{ message: "No pipeline block found" }] };
|
|
1590
|
-
}
|
|
1591
|
-
const startIdx = clean.indexOf("{", quotedMatch.index);
|
|
1592
|
-
let depth = 1;
|
|
1593
|
-
let i = startIdx + 1;
|
|
1594
|
-
while (i < clean.length && depth > 0) {
|
|
1595
|
-
if (clean[i] === "{") depth++;
|
|
1596
|
-
if (clean[i] === "}") depth--;
|
|
1597
|
-
i++;
|
|
1598
|
-
}
|
|
1599
|
-
const pipelineContent = clean.substring(startIdx + 1, i - 1);
|
|
1600
|
-
return parsePipelineContent(quotedMatch[1], pipelineContent, errors);
|
|
1601
|
-
}
|
|
1602
|
-
return parsePipelineContent(pipelineBlocks[0].name, pipelineBlocks[0].content, errors);
|
|
1603
|
-
}
|
|
1604
|
-
function parsePipelineContent(name, content, errors) {
|
|
1605
|
-
const invalidKeywords = [
|
|
1606
|
-
"environment",
|
|
1607
|
-
"spatial_group",
|
|
1608
|
-
"template",
|
|
1609
|
-
"object",
|
|
1610
|
-
"orb",
|
|
1611
|
-
"theme",
|
|
1612
|
-
"light",
|
|
1613
|
-
"camera",
|
|
1614
|
-
"audio",
|
|
1615
|
-
"zone",
|
|
1616
|
-
"timeline",
|
|
1617
|
-
"particle_system",
|
|
1618
|
-
"effects",
|
|
1619
|
-
"ui",
|
|
1620
|
-
"npc",
|
|
1621
|
-
"quest",
|
|
1622
|
-
"dialogue",
|
|
1623
|
-
"ability",
|
|
1624
|
-
"achievement",
|
|
1625
|
-
"talent_tree",
|
|
1626
|
-
"behavior",
|
|
1627
|
-
"state_machine",
|
|
1628
|
-
"shape",
|
|
1629
|
-
"terrain",
|
|
1630
|
-
"waypoints",
|
|
1631
|
-
"spawn_group",
|
|
1632
|
-
"composition",
|
|
1633
|
-
"constraint",
|
|
1634
|
-
"sub_orb",
|
|
1635
|
-
"norm",
|
|
1636
|
-
"metanorm"
|
|
1637
|
-
];
|
|
1638
|
-
for (const keyword of invalidKeywords) {
|
|
1639
|
-
if (new RegExp(`\\b${keyword}\\b`).test(content)) {
|
|
1640
|
-
errors.push({
|
|
1641
|
-
message: `SyntaxError: '${keyword}' is not valid in a pipeline context. Use .holo for spatial compositions or .hsplus for behaviors.`
|
|
1642
|
-
});
|
|
1643
|
-
}
|
|
1644
|
-
}
|
|
1645
|
-
const props = parseProperties(content);
|
|
1646
|
-
const schedule = typeof props.schedule === "string" ? props.schedule : void 0;
|
|
1647
|
-
const timeout = typeof props.timeout === "string" ? parseDuration(props.timeout) : void 0;
|
|
1648
|
-
let retry;
|
|
1649
|
-
const retryBlock = parseNestedBlock(content, "retry");
|
|
1650
|
-
if (retryBlock) {
|
|
1651
|
-
retry = {
|
|
1652
|
-
max: typeof retryBlock.max === "number" ? retryBlock.max : 3,
|
|
1653
|
-
backoff: retryBlock.backoff || "exponential"
|
|
1654
|
-
};
|
|
1655
|
-
}
|
|
1656
|
-
const sources = [];
|
|
1657
|
-
for (const block of extractBlock(content, "source")) {
|
|
1658
|
-
const p = parseProperties(block.content);
|
|
1659
|
-
sources.push({
|
|
1660
|
-
kind: "source",
|
|
1661
|
-
name: block.name,
|
|
1662
|
-
type: p.type || "rest",
|
|
1663
|
-
endpoint: p.endpoint,
|
|
1664
|
-
path: p.path,
|
|
1665
|
-
pattern: p.pattern,
|
|
1666
|
-
since: p.since,
|
|
1667
|
-
method: p.method,
|
|
1668
|
-
auth: parseNestedBlock(block.content, "auth"),
|
|
1669
|
-
pagination: parseNestedBlock(block.content, "pagination"),
|
|
1670
|
-
properties: p
|
|
1671
|
-
});
|
|
1672
|
-
}
|
|
1673
|
-
const transforms = [];
|
|
1674
|
-
for (const block of extractBlock(content, "transform")) {
|
|
1675
|
-
const p = parseProperties(block.content);
|
|
1676
|
-
const mappings = parseFieldMappings(block.content);
|
|
1677
|
-
const hasType = p.type !== void 0;
|
|
1678
|
-
transforms.push({
|
|
1679
|
-
kind: "transform",
|
|
1680
|
-
name: block.name,
|
|
1681
|
-
type: hasType ? p.type : mappings.length > 0 ? "field_mapping" : void 0,
|
|
1682
|
-
mappings: mappings.length > 0 ? mappings : void 0,
|
|
1683
|
-
model: p.model,
|
|
1684
|
-
prompt: p.prompt,
|
|
1685
|
-
input: p.input,
|
|
1686
|
-
output: p.output,
|
|
1687
|
-
server: p.server,
|
|
1688
|
-
tool: p.tool,
|
|
1689
|
-
method: p.method,
|
|
1690
|
-
url: p.url,
|
|
1691
|
-
timeout: typeof p.timeout === "string" ? parseDuration(p.timeout) : void 0,
|
|
1692
|
-
where: p.where,
|
|
1693
|
-
properties: p
|
|
1694
|
-
});
|
|
1695
|
-
}
|
|
1696
|
-
const filters = [];
|
|
1697
|
-
for (const block of extractBlock(content, "filter")) {
|
|
1698
|
-
const p = parseProperties(block.content);
|
|
1699
|
-
if (!p.where) {
|
|
1700
|
-
errors.push({
|
|
1701
|
-
message: `Filter "${block.name}" missing 'where' clause`,
|
|
1702
|
-
line: block.startLine,
|
|
1703
|
-
block: block.name
|
|
1704
|
-
});
|
|
1705
|
-
}
|
|
1706
|
-
filters.push({
|
|
1707
|
-
kind: "filter",
|
|
1708
|
-
name: block.name,
|
|
1709
|
-
where: p.where || ""
|
|
1710
|
-
});
|
|
1711
|
-
}
|
|
1712
|
-
const validates = [];
|
|
1713
|
-
for (const block of extractBlock(content, "validate")) {
|
|
1714
|
-
validates.push({
|
|
1715
|
-
kind: "validate",
|
|
1716
|
-
name: block.name,
|
|
1717
|
-
fields: parseValidateFields(block.content)
|
|
1718
|
-
});
|
|
1719
|
-
}
|
|
1720
|
-
const merges = [];
|
|
1721
|
-
for (const block of extractBlock(content, "merge")) {
|
|
1722
|
-
const p = parseProperties(block.content);
|
|
1723
|
-
const fromArr = typeof p.from === "string" ? parseStringArray(p.from) : [];
|
|
1724
|
-
merges.push({
|
|
1725
|
-
kind: "merge",
|
|
1726
|
-
name: block.name,
|
|
1727
|
-
from: fromArr,
|
|
1728
|
-
dedup: parseNestedBlock(block.content, "dedup"),
|
|
1729
|
-
strategy: p.strategy
|
|
1730
|
-
});
|
|
1731
|
-
}
|
|
1732
|
-
const branches = [];
|
|
1733
|
-
for (const block of extractBlock(content, "branch")) {
|
|
1734
|
-
branches.push({
|
|
1735
|
-
kind: "branch",
|
|
1736
|
-
name: block.name,
|
|
1737
|
-
routes: parseBranchRoutes(block.content)
|
|
1738
|
-
});
|
|
1739
|
-
}
|
|
1740
|
-
const sinks = [];
|
|
1741
|
-
for (const block of extractBlock(content, "sink")) {
|
|
1742
|
-
const p = parseProperties(block.content);
|
|
1743
|
-
sinks.push({
|
|
1744
|
-
kind: "sink",
|
|
1745
|
-
name: block.name,
|
|
1746
|
-
type: p.type || "rest",
|
|
1747
|
-
endpoint: p.endpoint,
|
|
1748
|
-
path: p.path,
|
|
1749
|
-
method: p.method,
|
|
1750
|
-
auth: parseNestedBlock(block.content, "auth"),
|
|
1751
|
-
batch: parseNestedBlock(block.content, "batch"),
|
|
1752
|
-
onError: parseNestedBlock(block.content, "on_error"),
|
|
1753
|
-
format: p.format,
|
|
1754
|
-
append: p.append,
|
|
1755
|
-
server: p.server,
|
|
1756
|
-
tool: p.tool,
|
|
1757
|
-
properties: p
|
|
1758
|
-
});
|
|
1759
|
-
}
|
|
1760
|
-
const steps = [
|
|
1761
|
-
...sources,
|
|
1762
|
-
...merges,
|
|
1763
|
-
...transforms,
|
|
1764
|
-
...filters,
|
|
1765
|
-
...validates,
|
|
1766
|
-
...branches,
|
|
1767
|
-
...sinks
|
|
1768
|
-
];
|
|
1769
|
-
if (sources.length === 0) {
|
|
1770
|
-
errors.push({ message: "Pipeline has no sources" });
|
|
1771
|
-
}
|
|
1772
|
-
if (sinks.length === 0) {
|
|
1773
|
-
errors.push({ message: "Pipeline has no sinks" });
|
|
1774
|
-
}
|
|
1775
|
-
const pipeline = {
|
|
1776
|
-
name,
|
|
1777
|
-
schedule,
|
|
1778
|
-
timeout,
|
|
1779
|
-
retry,
|
|
1780
|
-
steps,
|
|
1781
|
-
sources,
|
|
1782
|
-
transforms,
|
|
1783
|
-
filters,
|
|
1784
|
-
validates,
|
|
1785
|
-
merges,
|
|
1786
|
-
branches,
|
|
1787
|
-
sinks
|
|
1788
|
-
};
|
|
1789
|
-
return { success: errors.length === 0, pipeline, errors };
|
|
1790
|
-
}
|
|
1791
|
-
function isPipelineSource(source) {
|
|
1792
|
-
return /pipeline\s+["']?\w/.test(source);
|
|
1793
|
-
}
|
|
1794
|
-
|
|
1795
|
-
// src/compiler/platform/PlatformConditional.ts
|
|
1796
|
-
var PLATFORM_CATEGORIES = {
|
|
1797
|
-
vr: ["quest3", "pcvr", "visionos", "android-xr"],
|
|
1798
|
-
ar: ["visionos-ar", "android-xr-ar", "webxr"],
|
|
1799
|
-
mobile: ["ios", "android"],
|
|
1800
|
-
desktop: ["windows", "macos", "linux", "web"],
|
|
1801
|
-
automotive: ["android-auto", "carplay"],
|
|
1802
|
-
wearable: ["watchos", "wearos"]
|
|
1803
|
-
};
|
|
1804
|
-
var ALL_PLATFORMS = Object.values(
|
|
1805
|
-
PLATFORM_CATEGORIES
|
|
1806
|
-
).flat();
|
|
1807
|
-
function platformCategory(target) {
|
|
1808
|
-
for (const [cat, platforms] of Object.entries(PLATFORM_CATEGORIES)) {
|
|
1809
|
-
if (platforms.includes(target)) return cat;
|
|
1810
|
-
}
|
|
1811
|
-
return "desktop";
|
|
1812
|
-
}
|
|
1813
|
-
var PLATFORM_CAPABILITIES = {
|
|
1814
|
-
quest3: {
|
|
1815
|
-
spatialTracking: true,
|
|
1816
|
-
handTracking: true,
|
|
1817
|
-
eyeTracking: true,
|
|
1818
|
-
haptics: true,
|
|
1819
|
-
spatialAudio: true,
|
|
1820
|
-
gpu3D: true,
|
|
1821
|
-
arCamera: true,
|
|
1822
|
-
gps: false,
|
|
1823
|
-
npu: true,
|
|
1824
|
-
webxrSupport: true,
|
|
1825
|
-
frameBudgetMs: 11.1,
|
|
1826
|
-
agentBudgetMs: 5,
|
|
1827
|
-
computeModel: "edge-first"
|
|
1828
|
-
},
|
|
1829
|
-
pcvr: {
|
|
1830
|
-
spatialTracking: true,
|
|
1831
|
-
handTracking: true,
|
|
1832
|
-
eyeTracking: true,
|
|
1833
|
-
haptics: true,
|
|
1834
|
-
spatialAudio: true,
|
|
1835
|
-
gpu3D: true,
|
|
1836
|
-
arCamera: false,
|
|
1837
|
-
gps: false,
|
|
1838
|
-
npu: false,
|
|
1839
|
-
webxrSupport: true,
|
|
1840
|
-
frameBudgetMs: 11.1,
|
|
1841
|
-
agentBudgetMs: 5,
|
|
1842
|
-
computeModel: "edge-first"
|
|
1843
|
-
},
|
|
1844
|
-
visionos: {
|
|
1845
|
-
spatialTracking: true,
|
|
1846
|
-
handTracking: true,
|
|
1847
|
-
eyeTracking: true,
|
|
1848
|
-
haptics: false,
|
|
1849
|
-
spatialAudio: true,
|
|
1850
|
-
gpu3D: true,
|
|
1851
|
-
arCamera: true,
|
|
1852
|
-
gps: false,
|
|
1853
|
-
npu: true,
|
|
1854
|
-
webxrSupport: false,
|
|
1855
|
-
frameBudgetMs: 11.1,
|
|
1856
|
-
agentBudgetMs: 5,
|
|
1857
|
-
computeModel: "edge-first"
|
|
1858
|
-
},
|
|
1859
|
-
"android-xr": {
|
|
1860
|
-
spatialTracking: true,
|
|
1861
|
-
handTracking: true,
|
|
1862
|
-
eyeTracking: true,
|
|
1863
|
-
haptics: true,
|
|
1864
|
-
spatialAudio: true,
|
|
1865
|
-
gpu3D: true,
|
|
1866
|
-
arCamera: true,
|
|
1867
|
-
gps: true,
|
|
1868
|
-
npu: true,
|
|
1869
|
-
webxrSupport: true,
|
|
1870
|
-
frameBudgetMs: 11.1,
|
|
1871
|
-
agentBudgetMs: 5,
|
|
1872
|
-
computeModel: "edge-first"
|
|
1873
|
-
},
|
|
1874
|
-
"visionos-ar": {
|
|
1875
|
-
spatialTracking: true,
|
|
1876
|
-
handTracking: true,
|
|
1877
|
-
eyeTracking: true,
|
|
1878
|
-
haptics: false,
|
|
1879
|
-
spatialAudio: true,
|
|
1880
|
-
gpu3D: true,
|
|
1881
|
-
arCamera: true,
|
|
1882
|
-
gps: true,
|
|
1883
|
-
npu: true,
|
|
1884
|
-
webxrSupport: false,
|
|
1885
|
-
frameBudgetMs: 16.6,
|
|
1886
|
-
agentBudgetMs: 10,
|
|
1887
|
-
computeModel: "edge-first"
|
|
1888
|
-
},
|
|
1889
|
-
"android-xr-ar": {
|
|
1890
|
-
spatialTracking: true,
|
|
1891
|
-
handTracking: true,
|
|
1892
|
-
eyeTracking: false,
|
|
1893
|
-
haptics: true,
|
|
1894
|
-
spatialAudio: true,
|
|
1895
|
-
gpu3D: true,
|
|
1896
|
-
arCamera: true,
|
|
1897
|
-
gps: true,
|
|
1898
|
-
npu: true,
|
|
1899
|
-
webxrSupport: true,
|
|
1900
|
-
frameBudgetMs: 16.6,
|
|
1901
|
-
agentBudgetMs: 10,
|
|
1902
|
-
computeModel: "edge-first"
|
|
1903
|
-
},
|
|
1904
|
-
webxr: {
|
|
1905
|
-
spatialTracking: true,
|
|
1906
|
-
handTracking: false,
|
|
1907
|
-
eyeTracking: false,
|
|
1908
|
-
haptics: false,
|
|
1909
|
-
spatialAudio: false,
|
|
1910
|
-
gpu3D: true,
|
|
1911
|
-
arCamera: true,
|
|
1912
|
-
gps: false,
|
|
1913
|
-
npu: false,
|
|
1914
|
-
webxrSupport: true,
|
|
1915
|
-
frameBudgetMs: 16.6,
|
|
1916
|
-
agentBudgetMs: 15,
|
|
1917
|
-
computeModel: "cloud-first"
|
|
1918
|
-
},
|
|
1919
|
-
ios: {
|
|
1920
|
-
spatialTracking: false,
|
|
1921
|
-
handTracking: false,
|
|
1922
|
-
eyeTracking: false,
|
|
1923
|
-
haptics: true,
|
|
1924
|
-
spatialAudio: false,
|
|
1925
|
-
gpu3D: true,
|
|
1926
|
-
arCamera: true,
|
|
1927
|
-
gps: true,
|
|
1928
|
-
npu: true,
|
|
1929
|
-
webxrSupport: false,
|
|
1930
|
-
frameBudgetMs: 16.6,
|
|
1931
|
-
agentBudgetMs: 100,
|
|
1932
|
-
computeModel: "cloud-first"
|
|
1933
|
-
},
|
|
1934
|
-
android: {
|
|
1935
|
-
spatialTracking: false,
|
|
1936
|
-
handTracking: false,
|
|
1937
|
-
eyeTracking: false,
|
|
1938
|
-
haptics: true,
|
|
1939
|
-
spatialAudio: false,
|
|
1940
|
-
gpu3D: true,
|
|
1941
|
-
arCamera: true,
|
|
1942
|
-
gps: true,
|
|
1943
|
-
npu: true,
|
|
1944
|
-
webxrSupport: true,
|
|
1945
|
-
frameBudgetMs: 16.6,
|
|
1946
|
-
agentBudgetMs: 100,
|
|
1947
|
-
computeModel: "cloud-first"
|
|
1948
|
-
},
|
|
1949
|
-
windows: {
|
|
1950
|
-
spatialTracking: false,
|
|
1951
|
-
handTracking: false,
|
|
1952
|
-
eyeTracking: false,
|
|
1953
|
-
haptics: false,
|
|
1954
|
-
spatialAudio: false,
|
|
1955
|
-
gpu3D: true,
|
|
1956
|
-
arCamera: false,
|
|
1957
|
-
gps: false,
|
|
1958
|
-
npu: false,
|
|
1959
|
-
webxrSupport: true,
|
|
1960
|
-
frameBudgetMs: 16.6,
|
|
1961
|
-
agentBudgetMs: 200,
|
|
1962
|
-
computeModel: "cloud-first"
|
|
1963
|
-
},
|
|
1964
|
-
macos: {
|
|
1965
|
-
spatialTracking: false,
|
|
1966
|
-
handTracking: false,
|
|
1967
|
-
eyeTracking: false,
|
|
1968
|
-
haptics: false,
|
|
1969
|
-
spatialAudio: false,
|
|
1970
|
-
gpu3D: true,
|
|
1971
|
-
arCamera: false,
|
|
1972
|
-
gps: false,
|
|
1973
|
-
npu: true,
|
|
1974
|
-
webxrSupport: true,
|
|
1975
|
-
frameBudgetMs: 16.6,
|
|
1976
|
-
agentBudgetMs: 200,
|
|
1977
|
-
computeModel: "cloud-first"
|
|
1978
|
-
},
|
|
1979
|
-
linux: {
|
|
1980
|
-
spatialTracking: false,
|
|
1981
|
-
handTracking: false,
|
|
1982
|
-
eyeTracking: false,
|
|
1983
|
-
haptics: false,
|
|
1984
|
-
spatialAudio: false,
|
|
1985
|
-
gpu3D: true,
|
|
1986
|
-
arCamera: false,
|
|
1987
|
-
gps: false,
|
|
1988
|
-
npu: false,
|
|
1989
|
-
webxrSupport: true,
|
|
1990
|
-
frameBudgetMs: 16.6,
|
|
1991
|
-
agentBudgetMs: 200,
|
|
1992
|
-
computeModel: "cloud-first"
|
|
1993
|
-
},
|
|
1994
|
-
web: {
|
|
1995
|
-
spatialTracking: false,
|
|
1996
|
-
handTracking: false,
|
|
1997
|
-
eyeTracking: false,
|
|
1998
|
-
haptics: false,
|
|
1999
|
-
spatialAudio: false,
|
|
2000
|
-
gpu3D: true,
|
|
2001
|
-
arCamera: false,
|
|
2002
|
-
gps: false,
|
|
2003
|
-
npu: false,
|
|
2004
|
-
webxrSupport: true,
|
|
2005
|
-
frameBudgetMs: 16.6,
|
|
2006
|
-
agentBudgetMs: 200,
|
|
2007
|
-
computeModel: "cloud-first"
|
|
2008
|
-
},
|
|
2009
|
-
"android-auto": {
|
|
2010
|
-
spatialTracking: false,
|
|
2011
|
-
handTracking: false,
|
|
2012
|
-
eyeTracking: false,
|
|
2013
|
-
haptics: false,
|
|
2014
|
-
spatialAudio: true,
|
|
2015
|
-
gpu3D: false,
|
|
2016
|
-
arCamera: false,
|
|
2017
|
-
gps: true,
|
|
2018
|
-
npu: false,
|
|
2019
|
-
webxrSupport: false,
|
|
2020
|
-
frameBudgetMs: 30,
|
|
2021
|
-
agentBudgetMs: 15,
|
|
2022
|
-
computeModel: "safety-critical"
|
|
2023
|
-
},
|
|
2024
|
-
carplay: {
|
|
2025
|
-
spatialTracking: false,
|
|
2026
|
-
handTracking: false,
|
|
2027
|
-
eyeTracking: false,
|
|
2028
|
-
haptics: false,
|
|
2029
|
-
spatialAudio: true,
|
|
2030
|
-
gpu3D: false,
|
|
2031
|
-
arCamera: false,
|
|
2032
|
-
gps: true,
|
|
2033
|
-
npu: false,
|
|
2034
|
-
webxrSupport: false,
|
|
2035
|
-
frameBudgetMs: 30,
|
|
2036
|
-
agentBudgetMs: 15,
|
|
2037
|
-
computeModel: "safety-critical"
|
|
2038
|
-
},
|
|
2039
|
-
watchos: {
|
|
2040
|
-
spatialTracking: false,
|
|
2041
|
-
handTracking: false,
|
|
2042
|
-
eyeTracking: false,
|
|
2043
|
-
haptics: true,
|
|
2044
|
-
spatialAudio: false,
|
|
2045
|
-
gpu3D: false,
|
|
2046
|
-
arCamera: false,
|
|
2047
|
-
gps: true,
|
|
2048
|
-
npu: true,
|
|
2049
|
-
webxrSupport: false,
|
|
2050
|
-
frameBudgetMs: 33.3,
|
|
2051
|
-
agentBudgetMs: 50,
|
|
2052
|
-
computeModel: "cloud-first"
|
|
2053
|
-
},
|
|
2054
|
-
wearos: {
|
|
2055
|
-
spatialTracking: false,
|
|
2056
|
-
handTracking: false,
|
|
2057
|
-
eyeTracking: false,
|
|
2058
|
-
haptics: true,
|
|
2059
|
-
spatialAudio: false,
|
|
2060
|
-
gpu3D: false,
|
|
2061
|
-
arCamera: false,
|
|
2062
|
-
gps: true,
|
|
2063
|
-
npu: false,
|
|
2064
|
-
webxrSupport: false,
|
|
2065
|
-
frameBudgetMs: 33.3,
|
|
2066
|
-
agentBudgetMs: 50,
|
|
2067
|
-
computeModel: "cloud-first"
|
|
2068
|
-
}
|
|
2069
|
-
};
|
|
2070
|
-
var DEFAULT_EMBODIMENT = {
|
|
2071
|
-
vr: "Avatar3D",
|
|
2072
|
-
ar: "SpatialPersona",
|
|
2073
|
-
mobile: "UI2D",
|
|
2074
|
-
desktop: "FullGUI",
|
|
2075
|
-
automotive: "VoiceHUD",
|
|
2076
|
-
wearable: "UI2D"
|
|
2077
|
-
};
|
|
2078
|
-
function resolvePlatforms(condition) {
|
|
2079
|
-
let platforms = /* @__PURE__ */ new Set();
|
|
2080
|
-
if (condition.include) {
|
|
2081
|
-
for (const p of condition.include) platforms.add(p);
|
|
2082
|
-
}
|
|
2083
|
-
if (condition.includeCategories) {
|
|
2084
|
-
for (const cat of condition.includeCategories) {
|
|
2085
|
-
for (const p of PLATFORM_CATEGORIES[cat]) platforms.add(p);
|
|
2086
|
-
}
|
|
2087
|
-
}
|
|
2088
|
-
if (!condition.include && !condition.includeCategories) {
|
|
2089
|
-
for (const p of ALL_PLATFORMS) platforms.add(p);
|
|
2090
|
-
}
|
|
2091
|
-
if (condition.exclude) {
|
|
2092
|
-
for (const p of condition.exclude) platforms.delete(p);
|
|
2093
|
-
}
|
|
2094
|
-
if (condition.requireCapabilities) {
|
|
2095
|
-
platforms = new Set(
|
|
2096
|
-
[...platforms].filter((p) => {
|
|
2097
|
-
const caps = PLATFORM_CAPABILITIES[p];
|
|
2098
|
-
return condition.requireCapabilities.every((cap) => {
|
|
2099
|
-
const val = caps[cap];
|
|
2100
|
-
return typeof val === "boolean" ? val : Number(val) > 0;
|
|
2101
|
-
});
|
|
2102
|
-
})
|
|
2103
|
-
);
|
|
2104
|
-
}
|
|
2105
|
-
return [...platforms];
|
|
2106
|
-
}
|
|
2107
|
-
function matchesPlatform(target, condition) {
|
|
2108
|
-
return resolvePlatforms(condition).includes(target);
|
|
2109
|
-
}
|
|
2110
|
-
function selectBlock(target, blocks) {
|
|
2111
|
-
for (const block of blocks) {
|
|
2112
|
-
if (matchesPlatform(target, block.condition)) return block.body;
|
|
2113
|
-
}
|
|
2114
|
-
return void 0;
|
|
2115
|
-
}
|
|
2116
|
-
function embodimentFor(target) {
|
|
2117
|
-
return DEFAULT_EMBODIMENT[platformCategory(target)];
|
|
2118
|
-
}
|
|
2119
|
-
function agentBudgetFor(target) {
|
|
2120
|
-
return PLATFORM_CAPABILITIES[target].agentBudgetMs;
|
|
2121
|
-
}
|
|
2122
|
-
function hasCapability(target, cap) {
|
|
2123
|
-
const val = PLATFORM_CAPABILITIES[target][cap];
|
|
2124
|
-
return typeof val === "boolean" ? val : Number(val) > 0;
|
|
2125
|
-
}
|
|
2126
|
-
|
|
2127
2063
|
// src/compiler/USDZPipeline.ts
|
|
2128
2064
|
init_DomainBlockCompilerMixin();
|
|
2129
2065
|
init_R3FCompiler();
|
|
2066
|
+
function presetString(p, k) {
|
|
2067
|
+
const v = p[k];
|
|
2068
|
+
return typeof v === "string" ? v : void 0;
|
|
2069
|
+
}
|
|
2070
|
+
function presetNumber(p, k) {
|
|
2071
|
+
const v = p[k];
|
|
2072
|
+
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
2073
|
+
}
|
|
2074
|
+
function presetBoolean(p, k) {
|
|
2075
|
+
const v = p[k];
|
|
2076
|
+
return typeof v === "boolean" ? v : void 0;
|
|
2077
|
+
}
|
|
2130
2078
|
var _USDZPipeline = class _USDZPipeline {
|
|
2131
2079
|
constructor(options = {}) {
|
|
2132
2080
|
this.materials = /* @__PURE__ */ new Map();
|
|
@@ -2347,31 +2295,47 @@ ${domainBlocksOutput}` : materials,
|
|
|
2347
2295
|
const presetName = typeof material === "string" ? material : typeof materialPreset === "string" ? materialPreset : void 0;
|
|
2348
2296
|
if (presetName && MATERIAL_PRESETS[presetName]) {
|
|
2349
2297
|
const preset = MATERIAL_PRESETS[presetName];
|
|
2350
|
-
|
|
2351
|
-
if (
|
|
2352
|
-
|
|
2353
|
-
if (
|
|
2354
|
-
|
|
2355
|
-
if (
|
|
2356
|
-
|
|
2357
|
-
if (
|
|
2358
|
-
|
|
2359
|
-
if (
|
|
2360
|
-
|
|
2361
|
-
if (
|
|
2362
|
-
|
|
2363
|
-
if (
|
|
2364
|
-
|
|
2365
|
-
if (
|
|
2366
|
-
|
|
2367
|
-
if (
|
|
2368
|
-
|
|
2369
|
-
if (
|
|
2370
|
-
|
|
2371
|
-
if (
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2298
|
+
const colorStr = presetString(preset, "color");
|
|
2299
|
+
if (colorStr) mat.baseColor = this.hexToRGB(colorStr);
|
|
2300
|
+
const metal = presetNumber(preset, "metalness");
|
|
2301
|
+
if (metal !== void 0) mat.metallic = metal;
|
|
2302
|
+
const rough = presetNumber(preset, "roughness");
|
|
2303
|
+
if (rough !== void 0) mat.roughness = rough;
|
|
2304
|
+
const op = presetNumber(preset, "opacity");
|
|
2305
|
+
if (op !== void 0) mat.opacity = op;
|
|
2306
|
+
const emissiveStr = presetString(preset, "emissive");
|
|
2307
|
+
if (emissiveStr) mat.emissiveColor = this.hexToRGB(emissiveStr);
|
|
2308
|
+
const emissiveInt = presetNumber(preset, "emissiveIntensity");
|
|
2309
|
+
if (emissiveInt !== void 0) mat.emissiveIntensity = emissiveInt;
|
|
2310
|
+
const trans = presetNumber(preset, "transmission");
|
|
2311
|
+
if (trans !== void 0) mat.transmission = trans;
|
|
2312
|
+
const ior = presetNumber(preset, "ior");
|
|
2313
|
+
if (ior !== void 0) mat.ior = ior;
|
|
2314
|
+
const thick = presetNumber(preset, "thickness");
|
|
2315
|
+
if (thick !== void 0) mat.thickness = thick;
|
|
2316
|
+
const cc = presetNumber(preset, "clearcoat");
|
|
2317
|
+
if (cc !== void 0) mat.clearcoat = cc;
|
|
2318
|
+
const ccr = presetNumber(preset, "clearcoatRoughness");
|
|
2319
|
+
if (ccr !== void 0) mat.clearcoatRoughness = ccr;
|
|
2320
|
+
const sheen = presetNumber(preset, "sheen");
|
|
2321
|
+
if (sheen !== void 0) mat.sheen = sheen;
|
|
2322
|
+
const sheenR = presetNumber(preset, "sheenRoughness");
|
|
2323
|
+
if (sheenR !== void 0) mat.sheenRoughness = sheenR;
|
|
2324
|
+
const sheenColorStr = presetString(preset, "sheenColor");
|
|
2325
|
+
if (sheenColorStr) mat.sheenColor = this.hexToRGB(sheenColorStr);
|
|
2326
|
+
const irid = presetNumber(preset, "iridescence");
|
|
2327
|
+
if (irid !== void 0) mat.iridescence = irid;
|
|
2328
|
+
const iridIor = presetNumber(preset, "iridescenceIOR");
|
|
2329
|
+
if (iridIor !== void 0) mat.iridescenceIOR = iridIor;
|
|
2330
|
+
const aniso = presetNumber(preset, "anisotropy");
|
|
2331
|
+
if (aniso !== void 0) mat.anisotropy = aniso;
|
|
2332
|
+
const anisoRot = presetNumber(preset, "anisotropyRotation");
|
|
2333
|
+
if (anisoRot !== void 0) mat.anisotropyRotation = anisoRot;
|
|
2334
|
+
const attColorStr = presetString(preset, "attenuationColor");
|
|
2335
|
+
if (attColorStr) mat.attenuationColor = this.hexToRGB(attColorStr);
|
|
2336
|
+
const attDist = presetNumber(preset, "attenuationDistance");
|
|
2337
|
+
if (attDist !== void 0) mat.attenuationDistance = attDist;
|
|
2338
|
+
if (presetBoolean(preset, "transparent") && mat.opacity === void 0) mat.opacity = 0.99;
|
|
2375
2339
|
}
|
|
2376
2340
|
if (typeof color === "string") {
|
|
2377
2341
|
mat.baseColor = this.hexToRGB(color);
|
|
@@ -2913,6 +2877,864 @@ _USDZPipeline.TEXTURE_CHANNEL_MAP = {
|
|
|
2913
2877
|
};
|
|
2914
2878
|
var USDZPipeline = _USDZPipeline;
|
|
2915
2879
|
|
|
2880
|
+
// src/compiler/GaussianSplattingCompiler.ts
|
|
2881
|
+
init_CompilerBase();
|
|
2882
|
+
var GAUSSIAN_SPLAT_TRAIT_NAME = "gaussian_splat";
|
|
2883
|
+
var MULTIPLAYER_TRAIT_NAME = "multiplayer";
|
|
2884
|
+
function detectMultiUserSharedSort(composition) {
|
|
2885
|
+
const objects = composition.objects ?? [];
|
|
2886
|
+
for (const obj of objects) {
|
|
2887
|
+
if (objectHasBothTraits(obj)) return true;
|
|
2888
|
+
}
|
|
2889
|
+
return false;
|
|
2890
|
+
}
|
|
2891
|
+
function objectHasBothTraits(obj) {
|
|
2892
|
+
const traits = obj.traits ?? [];
|
|
2893
|
+
let hasSplat = false;
|
|
2894
|
+
let hasMultiplayer = false;
|
|
2895
|
+
for (const t of traits) {
|
|
2896
|
+
if (t.name === GAUSSIAN_SPLAT_TRAIT_NAME) hasSplat = true;
|
|
2897
|
+
else if (t.name === MULTIPLAYER_TRAIT_NAME) hasMultiplayer = true;
|
|
2898
|
+
if (hasSplat && hasMultiplayer) return true;
|
|
2899
|
+
}
|
|
2900
|
+
const childrenLike = obj.children ?? obj.objects ?? [];
|
|
2901
|
+
for (const child of childrenLike) {
|
|
2902
|
+
if (objectHasBothTraits(child)) return true;
|
|
2903
|
+
}
|
|
2904
|
+
return false;
|
|
2905
|
+
}
|
|
2906
|
+
var SHARED_SORT_SHADER_PATH = "packages/engine/src/gpu/shaders/splat-shared-sort.wgsl";
|
|
2907
|
+
var GaussianSplattingCompiler = class extends CompilerBase {
|
|
2908
|
+
constructor(options = {}) {
|
|
2909
|
+
super();
|
|
2910
|
+
this.compilerName = "GaussianSplattingCompiler";
|
|
2911
|
+
this.options = {
|
|
2912
|
+
format: options.format ?? "glb",
|
|
2913
|
+
colorSpace: options.colorSpace ?? "srgb_rec709_display",
|
|
2914
|
+
generator: options.generator ?? "HoloScript GaussianSplattingCompiler v1.0.0",
|
|
2915
|
+
copyright: options.copyright ?? "",
|
|
2916
|
+
shDegree: options.shDegree ?? 0
|
|
2917
|
+
};
|
|
2918
|
+
}
|
|
2919
|
+
getRequiredCapability() {
|
|
2920
|
+
return ANSCapabilityPath.GLTF;
|
|
2921
|
+
}
|
|
2922
|
+
compile(composition, agentToken, outputPath) {
|
|
2923
|
+
this.validateCompilerAccess(agentToken, outputPath);
|
|
2924
|
+
const { data, warnings } = this.extractGaussianData(composition);
|
|
2925
|
+
const result = this.buildGLTF(data);
|
|
2926
|
+
if (warnings && warnings.length > 0) {
|
|
2927
|
+
result.warnings = warnings;
|
|
2928
|
+
}
|
|
2929
|
+
return result;
|
|
2930
|
+
}
|
|
2931
|
+
/**
|
|
2932
|
+
* Extended compile that runs the standard glTF export AND reports
|
|
2933
|
+
* compile-time WebGPU emit flags derived from trait co-occurrence.
|
|
2934
|
+
*
|
|
2935
|
+
* The standard `compile()` API is left unchanged so existing call sites
|
|
2936
|
+
* (MCP `compile_to_3dgs`, ExportManager) keep their contract. Callers that
|
|
2937
|
+
* need the shared-sort flag opt in via this method.
|
|
2938
|
+
*
|
|
2939
|
+
* @see detectMultiUserSharedSort (the detection rule)
|
|
2940
|
+
* @see SHARED_SORT_SHADER_PATH (the kernel artifact path)
|
|
2941
|
+
*/
|
|
2942
|
+
compileExtended(composition, agentToken, outputPath) {
|
|
2943
|
+
const gltf = this.compile(composition, agentToken, outputPath);
|
|
2944
|
+
const multiUserSharedSort = detectMultiUserSharedSort(composition);
|
|
2945
|
+
return {
|
|
2946
|
+
gltf,
|
|
2947
|
+
multiUserSharedSort,
|
|
2948
|
+
sharedSortShaderPath: multiUserSharedSort ? SHARED_SORT_SHADER_PATH : void 0
|
|
2949
|
+
};
|
|
2950
|
+
}
|
|
2951
|
+
/**
|
|
2952
|
+
* Instance accessor for the multi-user shared-sort detector. Mirrors the
|
|
2953
|
+
* standalone `detectMultiUserSharedSort()` export — provided so callers
|
|
2954
|
+
* holding a compiler instance can run the check without a second import.
|
|
2955
|
+
*/
|
|
2956
|
+
detectMultiUserSharedSort(composition) {
|
|
2957
|
+
return detectMultiUserSharedSort(composition);
|
|
2958
|
+
}
|
|
2959
|
+
// ─── Data extraction ────────────────────────────────────────────────────────
|
|
2960
|
+
extractGaussianData(composition) {
|
|
2961
|
+
for (const obj of composition.objects ?? []) {
|
|
2962
|
+
const trait = obj.traits?.find((t) => t.name === "gaussian_splat");
|
|
2963
|
+
if (trait && trait.config) {
|
|
2964
|
+
const p = trait.config;
|
|
2965
|
+
const positions = this.parseFloatArray(p.positions);
|
|
2966
|
+
const scales = this.parseFloatArray(p.scales);
|
|
2967
|
+
const rotations = this.parseFloatArray(p.rotations);
|
|
2968
|
+
let colors = this.parseFloatArray(p.colors);
|
|
2969
|
+
const opacities = this.parseFloatArray(p.opacities);
|
|
2970
|
+
if (positions && scales && rotations && colors && opacities) {
|
|
2971
|
+
const count = positions.length / 3;
|
|
2972
|
+
if (scales.length === count * 3 && rotations.length === count * 4 && (colors.length === count * 4 || colors.length === count * 3) && opacities.length === count) {
|
|
2973
|
+
if (colors.length === count * 3) {
|
|
2974
|
+
colors = this.expandRgbToRgba(colors, count);
|
|
2975
|
+
}
|
|
2976
|
+
return {
|
|
2977
|
+
data: {
|
|
2978
|
+
positions,
|
|
2979
|
+
scales,
|
|
2980
|
+
rotations,
|
|
2981
|
+
colors,
|
|
2982
|
+
opacities,
|
|
2983
|
+
shCoefficients: this.parseFloatArray(p.shCoefficients),
|
|
2984
|
+
count
|
|
2985
|
+
}
|
|
2986
|
+
};
|
|
2987
|
+
}
|
|
2988
|
+
}
|
|
2989
|
+
if (positions && colors) {
|
|
2990
|
+
const count = positions.length / 3;
|
|
2991
|
+
if (colors.length === count * 3 || colors.length === count * 4) {
|
|
2992
|
+
return { data: this.computeCovarianceFromPointCloud(positions, colors) };
|
|
2993
|
+
}
|
|
2994
|
+
}
|
|
2995
|
+
}
|
|
2996
|
+
}
|
|
2997
|
+
return {
|
|
2998
|
+
data: this.generateDemoGrid(),
|
|
2999
|
+
warnings: ["No valid @gaussian_splat trait data found; falling back to demo grid"]
|
|
3000
|
+
};
|
|
3001
|
+
}
|
|
3002
|
+
expandRgbToRgba(rgb, count) {
|
|
3003
|
+
const rgba = new Float32Array(count * 4);
|
|
3004
|
+
for (let i = 0; i < count; i++) {
|
|
3005
|
+
rgba[i * 4] = rgb[i * 3];
|
|
3006
|
+
rgba[i * 4 + 1] = rgb[i * 3 + 1];
|
|
3007
|
+
rgba[i * 4 + 2] = rgb[i * 3 + 2];
|
|
3008
|
+
rgba[i * 4 + 3] = 1;
|
|
3009
|
+
}
|
|
3010
|
+
return rgba;
|
|
3011
|
+
}
|
|
3012
|
+
parseFloatArray(value) {
|
|
3013
|
+
if (value instanceof Float32Array) return value;
|
|
3014
|
+
if (Array.isArray(value)) {
|
|
3015
|
+
const nums = value.map((v) => typeof v === "number" ? v : Number(v));
|
|
3016
|
+
return new Float32Array(nums);
|
|
3017
|
+
}
|
|
3018
|
+
return void 0;
|
|
3019
|
+
}
|
|
3020
|
+
// ─── Covariance from point cloud (HoloMap raw output) ───────────────────────
|
|
3021
|
+
/**
|
|
3022
|
+
* Compute per-point Gaussian parameters from a raw point cloud.
|
|
3023
|
+
*
|
|
3024
|
+
* For each point we find k nearest neighbours, compute the 3x3 covariance
|
|
3025
|
+
* matrix of that neighbourhood, eigen-decompose it via Jacobi rotations,
|
|
3026
|
+
* and derive:
|
|
3027
|
+
* - scales = sqrt(eigenvalues) (isotropic minimum clamp)
|
|
3028
|
+
* - rotation = quaternion from eigenvector basis
|
|
3029
|
+
* - opacity = 1.0 (uniform)
|
|
3030
|
+
* - colors = passed through (RGB expanded to RGBA if needed)
|
|
3031
|
+
*/
|
|
3032
|
+
computeCovarianceFromPointCloud(positions, colors) {
|
|
3033
|
+
const n = Math.floor(positions.length / 3);
|
|
3034
|
+
const k = Math.min(12, Math.max(4, n - 1));
|
|
3035
|
+
const scales = new Float32Array(n * 3);
|
|
3036
|
+
const rotations = new Float32Array(n * 4);
|
|
3037
|
+
const opacities = new Float32Array(n);
|
|
3038
|
+
let rgbaColors;
|
|
3039
|
+
if (colors.length === n * 3) {
|
|
3040
|
+
rgbaColors = this.expandRgbToRgba(colors, n);
|
|
3041
|
+
} else {
|
|
3042
|
+
rgbaColors = colors;
|
|
3043
|
+
}
|
|
3044
|
+
const grid = this.buildSpatialGrid(positions, n);
|
|
3045
|
+
for (let i = 0; i < n; i++) {
|
|
3046
|
+
const px = positions[i * 3];
|
|
3047
|
+
const py = positions[i * 3 + 1];
|
|
3048
|
+
const pz = positions[i * 3 + 2];
|
|
3049
|
+
const neighbours = this.findKNearestNeighbours(grid, positions, n, px, py, pz, k, i);
|
|
3050
|
+
let meanX = 0, meanY = 0, meanZ = 0;
|
|
3051
|
+
for (const idx of neighbours) {
|
|
3052
|
+
meanX += positions[idx * 3];
|
|
3053
|
+
meanY += positions[idx * 3 + 1];
|
|
3054
|
+
meanZ += positions[idx * 3 + 2];
|
|
3055
|
+
}
|
|
3056
|
+
const invM = 1 / neighbours.length;
|
|
3057
|
+
meanX *= invM;
|
|
3058
|
+
meanY *= invM;
|
|
3059
|
+
meanZ *= invM;
|
|
3060
|
+
let c00 = 0, c01 = 0, c02 = 0, c11 = 0, c12 = 0, c22 = 0;
|
|
3061
|
+
for (const idx of neighbours) {
|
|
3062
|
+
const dx = positions[idx * 3] - meanX;
|
|
3063
|
+
const dy = positions[idx * 3 + 1] - meanY;
|
|
3064
|
+
const dz = positions[idx * 3 + 2] - meanZ;
|
|
3065
|
+
c00 += dx * dx;
|
|
3066
|
+
c01 += dx * dy;
|
|
3067
|
+
c02 += dx * dz;
|
|
3068
|
+
c11 += dy * dy;
|
|
3069
|
+
c12 += dy * dz;
|
|
3070
|
+
c22 += dz * dz;
|
|
3071
|
+
}
|
|
3072
|
+
const invLen = 1 / (neighbours.length - 1 || 1);
|
|
3073
|
+
c00 *= invLen;
|
|
3074
|
+
c01 *= invLen;
|
|
3075
|
+
c02 *= invLen;
|
|
3076
|
+
c11 *= invLen;
|
|
3077
|
+
c12 *= invLen;
|
|
3078
|
+
c22 *= invLen;
|
|
3079
|
+
const ev = this.jacobiEigenvalues3([
|
|
3080
|
+
c00,
|
|
3081
|
+
c01,
|
|
3082
|
+
c02,
|
|
3083
|
+
c01,
|
|
3084
|
+
c11,
|
|
3085
|
+
c12,
|
|
3086
|
+
c02,
|
|
3087
|
+
c12,
|
|
3088
|
+
c22
|
|
3089
|
+
]);
|
|
3090
|
+
const minScale = 1e-3;
|
|
3091
|
+
scales[i * 3] = Math.max(minScale, Math.sqrt(Math.abs(ev.values[0])));
|
|
3092
|
+
scales[i * 3 + 1] = Math.max(minScale, Math.sqrt(Math.abs(ev.values[1])));
|
|
3093
|
+
scales[i * 3 + 2] = Math.max(minScale, Math.sqrt(Math.abs(ev.values[2])));
|
|
3094
|
+
const q = this.rotationMatrixToQuaternion(ev.vectors);
|
|
3095
|
+
rotations[i * 4] = q[0];
|
|
3096
|
+
rotations[i * 4 + 1] = q[1];
|
|
3097
|
+
rotations[i * 4 + 2] = q[2];
|
|
3098
|
+
rotations[i * 4 + 3] = q[3];
|
|
3099
|
+
opacities[i] = 1;
|
|
3100
|
+
}
|
|
3101
|
+
return {
|
|
3102
|
+
positions,
|
|
3103
|
+
scales,
|
|
3104
|
+
rotations,
|
|
3105
|
+
colors: rgbaColors,
|
|
3106
|
+
opacities,
|
|
3107
|
+
count: n
|
|
3108
|
+
};
|
|
3109
|
+
}
|
|
3110
|
+
/** Simple uniform-grid spatial hash for k-NN acceleration. */
|
|
3111
|
+
buildSpatialGrid(positions, n) {
|
|
3112
|
+
let minX = Infinity, minY = Infinity, minZ = Infinity;
|
|
3113
|
+
let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
|
|
3114
|
+
for (let i = 0; i < n; i++) {
|
|
3115
|
+
const x = positions[i * 3];
|
|
3116
|
+
const y = positions[i * 3 + 1];
|
|
3117
|
+
const z = positions[i * 3 + 2];
|
|
3118
|
+
if (x < minX) minX = x;
|
|
3119
|
+
if (y < minY) minY = y;
|
|
3120
|
+
if (z < minZ) minZ = z;
|
|
3121
|
+
if (x > maxX) maxX = x;
|
|
3122
|
+
if (y > maxY) maxY = y;
|
|
3123
|
+
if (z > maxZ) maxZ = z;
|
|
3124
|
+
}
|
|
3125
|
+
const extent = Math.max(maxX - minX, maxY - minY, maxZ - minZ, 1e-6);
|
|
3126
|
+
const cellsPerAxis = Math.max(1, Math.round(Math.pow(n / 8, 1 / 3)));
|
|
3127
|
+
const cellSize = extent / cellsPerAxis;
|
|
3128
|
+
const grid = /* @__PURE__ */ new Map();
|
|
3129
|
+
for (let i = 0; i < n; i++) {
|
|
3130
|
+
const cx = Math.floor((positions[i * 3] - minX) / cellSize);
|
|
3131
|
+
const cy = Math.floor((positions[i * 3 + 1] - minY) / cellSize);
|
|
3132
|
+
const cz = Math.floor((positions[i * 3 + 2] - minZ) / cellSize);
|
|
3133
|
+
const key = `${cx},${cy},${cz}`;
|
|
3134
|
+
const arr = grid.get(key);
|
|
3135
|
+
if (arr) {
|
|
3136
|
+
arr.push(i);
|
|
3137
|
+
} else {
|
|
3138
|
+
grid.set(key, [i]);
|
|
3139
|
+
}
|
|
3140
|
+
}
|
|
3141
|
+
return grid;
|
|
3142
|
+
}
|
|
3143
|
+
findKNearestNeighbours(grid, positions, n, px, py, pz, k, selfIdx) {
|
|
3144
|
+
if (n <= 2048) {
|
|
3145
|
+
const dists = [];
|
|
3146
|
+
for (let i = 0; i < n; i++) {
|
|
3147
|
+
const dx = positions[i * 3] - px;
|
|
3148
|
+
const dy = positions[i * 3 + 1] - py;
|
|
3149
|
+
const dz = positions[i * 3 + 2] - pz;
|
|
3150
|
+
dists.push({ idx: i, d2: dx * dx + dy * dy + dz * dz });
|
|
3151
|
+
}
|
|
3152
|
+
dists.sort((a, b) => a.d2 - b.d2);
|
|
3153
|
+
return dists.slice(0, k + 1).map((d) => d.idx);
|
|
3154
|
+
}
|
|
3155
|
+
const radius = this.estimateSearchRadius(positions, n);
|
|
3156
|
+
const radius2 = radius * radius;
|
|
3157
|
+
const candidates = [];
|
|
3158
|
+
for (let i = 0; i < n; i++) {
|
|
3159
|
+
const dx = positions[i * 3] - px;
|
|
3160
|
+
const dy = positions[i * 3 + 1] - py;
|
|
3161
|
+
const dz = positions[i * 3 + 2] - pz;
|
|
3162
|
+
const d2 = dx * dx + dy * dy + dz * dz;
|
|
3163
|
+
if (d2 <= radius2) {
|
|
3164
|
+
candidates.push({ idx: i, d2 });
|
|
3165
|
+
}
|
|
3166
|
+
}
|
|
3167
|
+
candidates.sort((a, b) => a.d2 - b.d2);
|
|
3168
|
+
return candidates.slice(0, k + 1).map((c) => c.idx);
|
|
3169
|
+
}
|
|
3170
|
+
estimateSearchRadius(positions, n) {
|
|
3171
|
+
const sampleCount = Math.min(256, n);
|
|
3172
|
+
let totalDist = 0;
|
|
3173
|
+
let counted = 0;
|
|
3174
|
+
const step = Math.max(1, Math.floor(n / sampleCount));
|
|
3175
|
+
for (let i = 0; i < n; i += step) {
|
|
3176
|
+
let minD2 = Infinity;
|
|
3177
|
+
const px = positions[i * 3];
|
|
3178
|
+
const py = positions[i * 3 + 1];
|
|
3179
|
+
const pz = positions[i * 3 + 2];
|
|
3180
|
+
for (let j = 0; j < n; j++) {
|
|
3181
|
+
if (i === j) continue;
|
|
3182
|
+
const dx = positions[j * 3] - px;
|
|
3183
|
+
const dy = positions[j * 3 + 1] - py;
|
|
3184
|
+
const dz = positions[j * 3 + 2] - pz;
|
|
3185
|
+
const d2 = dx * dx + dy * dy + dz * dz;
|
|
3186
|
+
if (d2 < minD2) minD2 = d2;
|
|
3187
|
+
}
|
|
3188
|
+
if (minD2 < Infinity) {
|
|
3189
|
+
totalDist += Math.sqrt(minD2);
|
|
3190
|
+
counted++;
|
|
3191
|
+
}
|
|
3192
|
+
}
|
|
3193
|
+
const avg = counted > 0 ? totalDist / counted : 0.1;
|
|
3194
|
+
return avg * 3;
|
|
3195
|
+
}
|
|
3196
|
+
/** Jacobi eigenvalue decomposition for a 3x3 symmetric matrix.
|
|
3197
|
+
* Returns eigenvalues (descending) and eigenvectors as column-major 3x3.
|
|
3198
|
+
*/
|
|
3199
|
+
jacobiEigenvalues3(a) {
|
|
3200
|
+
let m = [
|
|
3201
|
+
[a[0], a[1], a[2]],
|
|
3202
|
+
[a[3], a[4], a[5]],
|
|
3203
|
+
[a[6], a[7], a[8]]
|
|
3204
|
+
];
|
|
3205
|
+
let v = [
|
|
3206
|
+
[1, 0, 0],
|
|
3207
|
+
[0, 1, 0],
|
|
3208
|
+
[0, 0, 1]
|
|
3209
|
+
];
|
|
3210
|
+
const eps = 1e-10;
|
|
3211
|
+
const maxSweeps = 50;
|
|
3212
|
+
for (let sweep = 0; sweep < maxSweeps; sweep++) {
|
|
3213
|
+
let offDiagSum = 0;
|
|
3214
|
+
for (let p = 0; p < 3; p++) {
|
|
3215
|
+
for (let q = p + 1; q < 3; q++) {
|
|
3216
|
+
offDiagSum += Math.abs(m[p][q]);
|
|
3217
|
+
if (Math.abs(m[p][q]) < eps) continue;
|
|
3218
|
+
const tau = (m[q][q] - m[p][p]) / (2 * m[p][q]);
|
|
3219
|
+
let t;
|
|
3220
|
+
if (tau >= 0) {
|
|
3221
|
+
t = 1 / (tau + Math.sqrt(1 + tau * tau));
|
|
3222
|
+
} else {
|
|
3223
|
+
t = 1 / (tau - Math.sqrt(1 + tau * tau));
|
|
3224
|
+
}
|
|
3225
|
+
const c = 1 / Math.sqrt(1 + t * t);
|
|
3226
|
+
const s = t * c;
|
|
3227
|
+
const mpp = m[p][p];
|
|
3228
|
+
const mqq = m[q][q];
|
|
3229
|
+
const mpq = m[p][q];
|
|
3230
|
+
m[p][p] = c * c * mpp - 2 * s * c * mpq + s * s * mqq;
|
|
3231
|
+
m[q][q] = s * s * mpp + 2 * s * c * mpq + c * c * mqq;
|
|
3232
|
+
m[p][q] = 0;
|
|
3233
|
+
m[q][p] = 0;
|
|
3234
|
+
for (let r = 0; r < 3; r++) {
|
|
3235
|
+
if (r !== p && r !== q) {
|
|
3236
|
+
const mr_p = m[r][p];
|
|
3237
|
+
const mr_q = m[r][q];
|
|
3238
|
+
m[r][p] = c * mr_p - s * mr_q;
|
|
3239
|
+
m[p][r] = m[r][p];
|
|
3240
|
+
m[r][q] = s * mr_p + c * mr_q;
|
|
3241
|
+
m[q][r] = m[r][q];
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3244
|
+
for (let r = 0; r < 3; r++) {
|
|
3245
|
+
const vr_p = v[r][p];
|
|
3246
|
+
const vr_q = v[r][q];
|
|
3247
|
+
v[r][p] = c * vr_p - s * vr_q;
|
|
3248
|
+
v[r][q] = s * vr_p + c * vr_q;
|
|
3249
|
+
}
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
if (offDiagSum < eps) break;
|
|
3253
|
+
}
|
|
3254
|
+
const vals = [m[0][0], m[1][1], m[2][2]];
|
|
3255
|
+
const cols = [
|
|
3256
|
+
[v[0][0], v[1][0], v[2][0]],
|
|
3257
|
+
[v[0][1], v[1][1], v[2][1]],
|
|
3258
|
+
[v[0][2], v[1][2], v[2][2]]
|
|
3259
|
+
];
|
|
3260
|
+
const order = [0, 1, 2].sort((i, j) => vals[j] - vals[i]);
|
|
3261
|
+
return {
|
|
3262
|
+
values: [vals[order[0]], vals[order[1]], vals[order[2]]],
|
|
3263
|
+
vectors: [
|
|
3264
|
+
cols[order[0]][0],
|
|
3265
|
+
cols[order[1]][0],
|
|
3266
|
+
cols[order[2]][0],
|
|
3267
|
+
cols[order[0]][1],
|
|
3268
|
+
cols[order[1]][1],
|
|
3269
|
+
cols[order[2]][1],
|
|
3270
|
+
cols[order[0]][2],
|
|
3271
|
+
cols[order[1]][2],
|
|
3272
|
+
cols[order[2]][2]
|
|
3273
|
+
]
|
|
3274
|
+
};
|
|
3275
|
+
}
|
|
3276
|
+
rotationMatrixToQuaternion(m) {
|
|
3277
|
+
const trace = m[0] + m[4] + m[8];
|
|
3278
|
+
let qw, qx, qy, qz;
|
|
3279
|
+
if (trace > 0) {
|
|
3280
|
+
const s = 0.5 / Math.sqrt(trace + 1);
|
|
3281
|
+
qw = 0.25 / s;
|
|
3282
|
+
qx = (m[5] - m[7]) * s;
|
|
3283
|
+
qy = (m[6] - m[2]) * s;
|
|
3284
|
+
qz = (m[1] - m[3]) * s;
|
|
3285
|
+
} else if (m[0] > m[4] && m[0] > m[8]) {
|
|
3286
|
+
const s = 2 * Math.sqrt(1 + m[0] - m[4] - m[8]);
|
|
3287
|
+
qw = (m[5] - m[7]) / s;
|
|
3288
|
+
qx = 0.25 * s;
|
|
3289
|
+
qy = (m[3] + m[1]) / s;
|
|
3290
|
+
qz = (m[6] + m[2]) / s;
|
|
3291
|
+
} else if (m[4] > m[8]) {
|
|
3292
|
+
const s = 2 * Math.sqrt(1 + m[4] - m[0] - m[8]);
|
|
3293
|
+
qw = (m[6] - m[2]) / s;
|
|
3294
|
+
qx = (m[3] + m[1]) / s;
|
|
3295
|
+
qy = 0.25 * s;
|
|
3296
|
+
qz = (m[7] + m[5]) / s;
|
|
3297
|
+
} else {
|
|
3298
|
+
const s = 2 * Math.sqrt(1 + m[8] - m[0] - m[4]);
|
|
3299
|
+
qw = (m[1] - m[3]) / s;
|
|
3300
|
+
qx = (m[6] + m[2]) / s;
|
|
3301
|
+
qy = (m[7] + m[5]) / s;
|
|
3302
|
+
qz = 0.25 * s;
|
|
3303
|
+
}
|
|
3304
|
+
const norm = Math.sqrt(qx * qx + qy * qy + qz * qz + qw * qw) || 1;
|
|
3305
|
+
return [qx / norm, qy / norm, qz / norm, qw / norm];
|
|
3306
|
+
}
|
|
3307
|
+
generateDemoGrid() {
|
|
3308
|
+
const count = 8;
|
|
3309
|
+
const positions = new Float32Array(count * 3);
|
|
3310
|
+
const scales = new Float32Array(count * 3);
|
|
3311
|
+
const rotations = new Float32Array(count * 4);
|
|
3312
|
+
const colors = new Float32Array(count * 4);
|
|
3313
|
+
const opacities = new Float32Array(count);
|
|
3314
|
+
let i = 0;
|
|
3315
|
+
for (let x = 0; x < 2; x++) {
|
|
3316
|
+
for (let y = 0; y < 2; y++) {
|
|
3317
|
+
for (let z = 0; z < 2; z++) {
|
|
3318
|
+
positions[i * 3] = x * 0.5;
|
|
3319
|
+
positions[i * 3 + 1] = y * 0.5;
|
|
3320
|
+
positions[i * 3 + 2] = z * 0.5;
|
|
3321
|
+
scales[i * 3] = 0.1;
|
|
3322
|
+
scales[i * 3 + 1] = 0.1;
|
|
3323
|
+
scales[i * 3 + 2] = 0.1;
|
|
3324
|
+
rotations[i * 4] = 0;
|
|
3325
|
+
rotations[i * 4 + 1] = 0;
|
|
3326
|
+
rotations[i * 4 + 2] = 0;
|
|
3327
|
+
rotations[i * 4 + 3] = 1;
|
|
3328
|
+
colors[i * 4] = 0.8;
|
|
3329
|
+
colors[i * 4 + 1] = 0.3;
|
|
3330
|
+
colors[i * 4 + 2] = 0.3;
|
|
3331
|
+
colors[i * 4 + 3] = 1;
|
|
3332
|
+
opacities[i] = 1;
|
|
3333
|
+
i++;
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
3336
|
+
}
|
|
3337
|
+
return { positions, scales, rotations, colors, opacities, count };
|
|
3338
|
+
}
|
|
3339
|
+
// ─── glTF builder ─────────────────────────────────────────────────────────
|
|
3340
|
+
buildGLTF(data) {
|
|
3341
|
+
const N = data.count;
|
|
3342
|
+
const bufferData = this.buildBuffer(data);
|
|
3343
|
+
const bufferViews = this.buildBufferViews(N);
|
|
3344
|
+
const accessors = this.buildAccessors(N);
|
|
3345
|
+
const primitive = {
|
|
3346
|
+
attributes: {
|
|
3347
|
+
POSITION: 0,
|
|
3348
|
+
_ROTATION: 1,
|
|
3349
|
+
_SCALE: 2,
|
|
3350
|
+
_OPACITY: 3,
|
|
3351
|
+
COLOR_0: 4
|
|
3352
|
+
},
|
|
3353
|
+
mode: 0,
|
|
3354
|
+
// POINTS
|
|
3355
|
+
extensions: {
|
|
3356
|
+
KHR_gaussian_splatting: {
|
|
3357
|
+
colorSpace: this.options.colorSpace
|
|
3358
|
+
}
|
|
3359
|
+
}
|
|
3360
|
+
};
|
|
3361
|
+
const mesh = {
|
|
3362
|
+
name: "GaussianSplatMesh",
|
|
3363
|
+
primitives: [primitive]
|
|
3364
|
+
};
|
|
3365
|
+
const node = {
|
|
3366
|
+
name: "GaussianSplatNode",
|
|
3367
|
+
mesh: 0
|
|
3368
|
+
};
|
|
3369
|
+
const gltf = {
|
|
3370
|
+
asset: {
|
|
3371
|
+
version: "2.0",
|
|
3372
|
+
generator: this.options.generator,
|
|
3373
|
+
...this.options.copyright ? { copyright: this.options.copyright } : {}
|
|
3374
|
+
},
|
|
3375
|
+
scene: 0,
|
|
3376
|
+
scenes: [{ name: "Scene", nodes: [0] }],
|
|
3377
|
+
nodes: [node],
|
|
3378
|
+
meshes: [mesh],
|
|
3379
|
+
accessors,
|
|
3380
|
+
bufferViews,
|
|
3381
|
+
buffers: [{ byteLength: bufferData.byteLength }],
|
|
3382
|
+
extensionsUsed: ["KHR_gaussian_splatting"]
|
|
3383
|
+
};
|
|
3384
|
+
const stats = {
|
|
3385
|
+
nodeCount: 1,
|
|
3386
|
+
meshCount: 1,
|
|
3387
|
+
materialCount: 0,
|
|
3388
|
+
textureCount: 0,
|
|
3389
|
+
animationCount: 0,
|
|
3390
|
+
totalVertices: N,
|
|
3391
|
+
totalTriangles: 0,
|
|
3392
|
+
fileSizeBytes: 0
|
|
3393
|
+
};
|
|
3394
|
+
if (this.options.format === "glb") {
|
|
3395
|
+
const binary = this.createGLB(gltf, bufferData);
|
|
3396
|
+
stats.fileSizeBytes = binary.byteLength;
|
|
3397
|
+
return { binary, stats };
|
|
3398
|
+
}
|
|
3399
|
+
stats.fileSizeBytes = JSON.stringify(gltf).length + bufferData.byteLength;
|
|
3400
|
+
return { json: gltf, buffer: bufferData, stats };
|
|
3401
|
+
}
|
|
3402
|
+
// ─── Binary layout ──────────────────────────────────────────────────────────
|
|
3403
|
+
buildBuffer(data) {
|
|
3404
|
+
const N = data.count;
|
|
3405
|
+
const logScales = new Float32Array(N * 3);
|
|
3406
|
+
for (let i = 0; i < N * 3; i++) {
|
|
3407
|
+
logScales[i] = Math.log(Math.max(data.scales[i], 1e-8));
|
|
3408
|
+
}
|
|
3409
|
+
const size = N * 3 * 4 + N * 4 * 4 + N * 3 * 4 + N * 4 + N * 4 * 4;
|
|
3410
|
+
const buf = new Uint8Array(size);
|
|
3411
|
+
let off = 0;
|
|
3412
|
+
const write = (arr) => {
|
|
3413
|
+
const view = new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
3414
|
+
buf.set(view, off);
|
|
3415
|
+
off += arr.byteLength;
|
|
3416
|
+
};
|
|
3417
|
+
write(data.positions);
|
|
3418
|
+
write(data.rotations);
|
|
3419
|
+
write(logScales);
|
|
3420
|
+
write(data.opacities);
|
|
3421
|
+
write(data.colors);
|
|
3422
|
+
return buf;
|
|
3423
|
+
}
|
|
3424
|
+
buildBufferViews(N) {
|
|
3425
|
+
let off = 0;
|
|
3426
|
+
const views = [];
|
|
3427
|
+
const add = (len) => {
|
|
3428
|
+
views.push({ buffer: 0, byteOffset: off, byteLength: len });
|
|
3429
|
+
off += len;
|
|
3430
|
+
return views.length - 1;
|
|
3431
|
+
};
|
|
3432
|
+
add(N * 3 * 4);
|
|
3433
|
+
add(N * 4 * 4);
|
|
3434
|
+
add(N * 3 * 4);
|
|
3435
|
+
add(N * 4);
|
|
3436
|
+
add(N * 4 * 4);
|
|
3437
|
+
return views;
|
|
3438
|
+
}
|
|
3439
|
+
buildAccessors(N) {
|
|
3440
|
+
let bv = 0;
|
|
3441
|
+
const accs = [];
|
|
3442
|
+
const add = (type, compType, count) => {
|
|
3443
|
+
accs.push({ bufferView: bv++, componentType: compType, count, type });
|
|
3444
|
+
};
|
|
3445
|
+
add("VEC3", 5126, N);
|
|
3446
|
+
add("VEC4", 5126, N);
|
|
3447
|
+
add("VEC3", 5126, N);
|
|
3448
|
+
add("SCALAR", 5126, N);
|
|
3449
|
+
add("VEC4", 5126, N);
|
|
3450
|
+
return accs;
|
|
3451
|
+
}
|
|
3452
|
+
// ─── GLB assembler (mirrors GLTFPipeline) ─────────────────────────────────
|
|
3453
|
+
createGLB(gltf, buffer) {
|
|
3454
|
+
const jsonString = JSON.stringify(gltf);
|
|
3455
|
+
const jsonBuffer = new TextEncoder().encode(jsonString);
|
|
3456
|
+
const jsonPadding = (4 - jsonBuffer.byteLength % 4) % 4;
|
|
3457
|
+
const paddedJsonLength = jsonBuffer.byteLength + jsonPadding;
|
|
3458
|
+
const binPadding = (4 - buffer.byteLength % 4) % 4;
|
|
3459
|
+
const paddedBinLength = buffer.byteLength + binPadding;
|
|
3460
|
+
const totalSize = 12 + 8 + paddedJsonLength + 8 + paddedBinLength;
|
|
3461
|
+
const output = new ArrayBuffer(totalSize);
|
|
3462
|
+
const view = new DataView(output);
|
|
3463
|
+
const bytes = new Uint8Array(output);
|
|
3464
|
+
let offset = 0;
|
|
3465
|
+
view.setUint32(offset, 1179937895, true);
|
|
3466
|
+
offset += 4;
|
|
3467
|
+
view.setUint32(offset, 2, true);
|
|
3468
|
+
offset += 4;
|
|
3469
|
+
view.setUint32(offset, totalSize, true);
|
|
3470
|
+
offset += 4;
|
|
3471
|
+
view.setUint32(offset, paddedJsonLength, true);
|
|
3472
|
+
offset += 4;
|
|
3473
|
+
view.setUint32(offset, 1313821514, true);
|
|
3474
|
+
offset += 4;
|
|
3475
|
+
bytes.set(jsonBuffer, offset);
|
|
3476
|
+
offset += jsonBuffer.byteLength;
|
|
3477
|
+
for (let i = 0; i < jsonPadding; i++) bytes[offset++] = 32;
|
|
3478
|
+
view.setUint32(offset, paddedBinLength, true);
|
|
3479
|
+
offset += 4;
|
|
3480
|
+
view.setUint32(offset, 5130562, true);
|
|
3481
|
+
offset += 4;
|
|
3482
|
+
bytes.set(buffer, offset);
|
|
3483
|
+
offset += buffer.byteLength;
|
|
3484
|
+
for (let i = 0; i < binPadding; i++) bytes[offset++] = 0;
|
|
3485
|
+
return new Uint8Array(output);
|
|
3486
|
+
}
|
|
3487
|
+
};
|
|
3488
|
+
function createGaussianSplattingCompiler(options) {
|
|
3489
|
+
return new GaussianSplattingCompiler(options);
|
|
3490
|
+
}
|
|
3491
|
+
|
|
3492
|
+
// src/compiler/SpatialPartitionPass.ts
|
|
3493
|
+
var MAX_DEPTH = 8;
|
|
3494
|
+
var SCALE_PER_SPLAT_UNIT = 1e-6;
|
|
3495
|
+
var MIN_SCALE = 1e-9;
|
|
3496
|
+
var SpatialPartitionPass = class {
|
|
3497
|
+
constructor(options = {}) {
|
|
3498
|
+
this.maxDepth = options.maxDepth ?? MAX_DEPTH;
|
|
3499
|
+
this.scalePerSplatUnit = options.scalePerSplatUnit ?? SCALE_PER_SPLAT_UNIT;
|
|
3500
|
+
this.includeUnpositioned = options.includeUnpositioned ?? true;
|
|
3501
|
+
}
|
|
3502
|
+
/**
|
|
3503
|
+
* Run the pass over a HoloComposition and return the serializable result.
|
|
3504
|
+
*/
|
|
3505
|
+
run(composition) {
|
|
3506
|
+
const rawSources = [];
|
|
3507
|
+
this.collectFromComposition(composition, rawSources);
|
|
3508
|
+
if (rawSources.length === 0) {
|
|
3509
|
+
return this.emptyResult(composition.name);
|
|
3510
|
+
}
|
|
3511
|
+
const maxScaleInScene = Math.max(
|
|
3512
|
+
...rawSources.map((s) => Math.max(s.maxSplats * this.scalePerSplatUnit, MIN_SCALE))
|
|
3513
|
+
);
|
|
3514
|
+
const anchors = [];
|
|
3515
|
+
const lodDist = {};
|
|
3516
|
+
let objectsWalked = 0;
|
|
3517
|
+
for (const src of rawSources) {
|
|
3518
|
+
objectsWalked++;
|
|
3519
|
+
if (!this.includeUnpositioned && !src.hasPosition) continue;
|
|
3520
|
+
const scale = Math.max(src.maxSplats * this.scalePerSplatUnit, MIN_SCALE);
|
|
3521
|
+
const lodLevel = this.computeLODLevel(scale, maxScaleInScene);
|
|
3522
|
+
const provenanceHash = src.sourceFile ? deterministicHash(`file:${src.sourceFile}:${src.maxSplats}`) : deterministicHash(`${src.objectName}:${lodLevel}:${src.maxSplats}`);
|
|
3523
|
+
const anchor = {
|
|
3524
|
+
id: `spa_${sanitiseId(src.objectName)}_l${lodLevel}`,
|
|
3525
|
+
position: src.position,
|
|
3526
|
+
scale,
|
|
3527
|
+
lodLevel,
|
|
3528
|
+
gaussianCount: src.maxSplats,
|
|
3529
|
+
importance: src.importance,
|
|
3530
|
+
provenanceHash,
|
|
3531
|
+
...src.sourceFile ? { sourceFile: src.sourceFile } : {}
|
|
3532
|
+
};
|
|
3533
|
+
anchors.push(anchor);
|
|
3534
|
+
lodDist[lodLevel] = (lodDist[lodLevel] ?? 0) + 1;
|
|
3535
|
+
}
|
|
3536
|
+
anchors.sort((a, b) => a.lodLevel - b.lodLevel);
|
|
3537
|
+
const bounds = computeBounds(anchors);
|
|
3538
|
+
const merkleRoot = computeMerkleRoot(anchors);
|
|
3539
|
+
const totalGaussians = anchors.reduce((s, a) => s + a.gaussianCount, 0);
|
|
3540
|
+
const maxLodLevel = anchors.length > 0 ? Math.max(...anchors.map((a) => a.lodLevel)) : 0;
|
|
3541
|
+
return {
|
|
3542
|
+
schema: "spatial-partition/v1",
|
|
3543
|
+
compositionName: composition.name,
|
|
3544
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3545
|
+
anchors,
|
|
3546
|
+
bounds,
|
|
3547
|
+
merkleRoot,
|
|
3548
|
+
totalGaussians,
|
|
3549
|
+
stats: {
|
|
3550
|
+
objectsWalked,
|
|
3551
|
+
anchorsEmitted: anchors.length,
|
|
3552
|
+
lodLevelDistribution: lodDist,
|
|
3553
|
+
maxLodLevel,
|
|
3554
|
+
maxScaleInScene
|
|
3555
|
+
}
|
|
3556
|
+
};
|
|
3557
|
+
}
|
|
3558
|
+
// ── LOD level computation (same algorithm as OctreeLODSystem.computeLODLevelFromScale) ──
|
|
3559
|
+
computeLODLevel(scale, maxScaleInScene) {
|
|
3560
|
+
if (scale <= 0 || maxScaleInScene <= 0) return this.maxDepth - 1;
|
|
3561
|
+
if (scale >= maxScaleInScene) return 0;
|
|
3562
|
+
const ratio = maxScaleInScene / scale;
|
|
3563
|
+
const level = Math.floor(Math.log2(ratio));
|
|
3564
|
+
return Math.min(Math.max(0, level), this.maxDepth - 1);
|
|
3565
|
+
}
|
|
3566
|
+
// ── AST Walk (mirrors GaussianBudgetAnalyzer.collectGaussianSources) ─────────
|
|
3567
|
+
collectFromComposition(composition, out) {
|
|
3568
|
+
if (composition.objects) {
|
|
3569
|
+
for (const obj of composition.objects) {
|
|
3570
|
+
this.collectFromObject(obj, out);
|
|
3571
|
+
}
|
|
3572
|
+
}
|
|
3573
|
+
if (composition.spatialGroups) {
|
|
3574
|
+
for (const group of composition.spatialGroups) {
|
|
3575
|
+
this.collectFromGroup(group, out);
|
|
3576
|
+
}
|
|
3577
|
+
}
|
|
3578
|
+
if (composition.conditionals) {
|
|
3579
|
+
for (const cond of composition.conditionals) {
|
|
3580
|
+
if (cond.objects) {
|
|
3581
|
+
for (const obj of cond.objects) this.collectFromObject(obj, out);
|
|
3582
|
+
}
|
|
3583
|
+
if (cond.elseObjects) {
|
|
3584
|
+
for (const obj of cond.elseObjects) this.collectFromObject(obj, out);
|
|
3585
|
+
}
|
|
3586
|
+
}
|
|
3587
|
+
}
|
|
3588
|
+
if (composition.iterators) {
|
|
3589
|
+
for (const iter of composition.iterators) {
|
|
3590
|
+
if (iter.objects) {
|
|
3591
|
+
for (const obj of iter.objects) this.collectFromObject(obj, out);
|
|
3592
|
+
}
|
|
3593
|
+
}
|
|
3594
|
+
}
|
|
3595
|
+
}
|
|
3596
|
+
collectFromObject(obj, out) {
|
|
3597
|
+
if (obj.traits) {
|
|
3598
|
+
for (const trait of obj.traits) {
|
|
3599
|
+
if (trait.name === "gaussian_splat") {
|
|
3600
|
+
const src = this.extractSource(obj, trait);
|
|
3601
|
+
if (src) out.push(src);
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
}
|
|
3605
|
+
if (obj.children) {
|
|
3606
|
+
for (const child of obj.children) {
|
|
3607
|
+
this.collectFromObject(child, out);
|
|
3608
|
+
}
|
|
3609
|
+
}
|
|
3610
|
+
}
|
|
3611
|
+
collectFromGroup(group, out) {
|
|
3612
|
+
if (group.objects) {
|
|
3613
|
+
for (const obj of group.objects) this.collectFromObject(obj, out);
|
|
3614
|
+
}
|
|
3615
|
+
if (group.groups) {
|
|
3616
|
+
for (const sub of group.groups) this.collectFromGroup(sub, out);
|
|
3617
|
+
}
|
|
3618
|
+
}
|
|
3619
|
+
extractSource(obj, trait) {
|
|
3620
|
+
const config = trait.config ?? {};
|
|
3621
|
+
const maxSplats = typeof config.max_splats === "number" ? config.max_splats : 5e4;
|
|
3622
|
+
const sourceFile = typeof config.src === "string" ? config.src : typeof config.source === "string" ? config.source : void 0;
|
|
3623
|
+
const importance = typeof config.importance === "number" ? Math.max(0, Math.min(1, config.importance)) : 0.5;
|
|
3624
|
+
let posArr = null;
|
|
3625
|
+
if (obj.position && typeof obj.position.x === "number") {
|
|
3626
|
+
posArr = [obj.position.x, obj.position.y, obj.position.z];
|
|
3627
|
+
} else {
|
|
3628
|
+
const posProp = obj.properties?.find((p) => p.key === "position")?.value;
|
|
3629
|
+
if (Array.isArray(posProp) && posProp.length >= 3) {
|
|
3630
|
+
posArr = [Number(posProp[0]), Number(posProp[1]), Number(posProp[2])];
|
|
3631
|
+
} else if (posProp !== null && typeof posProp === "object" && !Array.isArray(posProp) && typeof posProp["x"] === "number") {
|
|
3632
|
+
const pobj = posProp;
|
|
3633
|
+
posArr = [pobj.x, pobj.y, pobj.z];
|
|
3634
|
+
}
|
|
3635
|
+
}
|
|
3636
|
+
return {
|
|
3637
|
+
objectName: obj.name ?? `unnamed_${Math.random().toString(36).slice(2, 7)}`,
|
|
3638
|
+
position: posArr ?? [0, 0, 0],
|
|
3639
|
+
hasPosition: posArr !== null,
|
|
3640
|
+
maxSplats,
|
|
3641
|
+
sourceFile,
|
|
3642
|
+
importance
|
|
3643
|
+
};
|
|
3644
|
+
}
|
|
3645
|
+
// ── Empty-composition fast path ─────────────────────────────────────────────
|
|
3646
|
+
emptyResult(compositionName) {
|
|
3647
|
+
return {
|
|
3648
|
+
schema: "spatial-partition/v1",
|
|
3649
|
+
compositionName,
|
|
3650
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3651
|
+
anchors: [],
|
|
3652
|
+
bounds: {
|
|
3653
|
+
min: { x: 0, y: 0, z: 0 },
|
|
3654
|
+
max: { x: 0, y: 0, z: 0 },
|
|
3655
|
+
center: { x: 0, y: 0, z: 0 },
|
|
3656
|
+
halfSize: 0
|
|
3657
|
+
},
|
|
3658
|
+
merkleRoot: "0".repeat(64),
|
|
3659
|
+
totalGaussians: 0,
|
|
3660
|
+
stats: {
|
|
3661
|
+
objectsWalked: 0,
|
|
3662
|
+
anchorsEmitted: 0,
|
|
3663
|
+
lodLevelDistribution: {},
|
|
3664
|
+
maxLodLevel: 0,
|
|
3665
|
+
maxScaleInScene: 0
|
|
3666
|
+
}
|
|
3667
|
+
};
|
|
3668
|
+
}
|
|
3669
|
+
};
|
|
3670
|
+
function deterministicHash(input) {
|
|
3671
|
+
let h0 = 2166136261;
|
|
3672
|
+
let h1 = 3521423859;
|
|
3673
|
+
for (let i = 0; i < input.length; i++) {
|
|
3674
|
+
const c = input.charCodeAt(i);
|
|
3675
|
+
h0 = Math.imul(h0 ^ c, 16777619) >>> 0;
|
|
3676
|
+
h1 = Math.imul(h1 ^ c, 16777619) >>> 0;
|
|
3677
|
+
}
|
|
3678
|
+
const hex0 = h0.toString(16).padStart(8, "0");
|
|
3679
|
+
const hex1 = h1.toString(16).padStart(8, "0");
|
|
3680
|
+
const base = (hex0 + hex1).repeat(4).slice(0, 64);
|
|
3681
|
+
return base;
|
|
3682
|
+
}
|
|
3683
|
+
function computeMerkleRoot(anchors) {
|
|
3684
|
+
if (anchors.length === 0) return "0".repeat(64);
|
|
3685
|
+
const sorted = [...anchors].sort((a, b) => a.id.localeCompare(b.id));
|
|
3686
|
+
const bytes = new Uint8Array(32);
|
|
3687
|
+
for (const anchor of sorted) {
|
|
3688
|
+
const hash = anchor.provenanceHash.slice(0, 64).padEnd(64, "0");
|
|
3689
|
+
for (let i = 0; i < 32; i++) {
|
|
3690
|
+
const byteHex = hash.slice(i * 2, i * 2 + 2);
|
|
3691
|
+
bytes[i] ^= parseInt(byteHex, 16) || 0;
|
|
3692
|
+
}
|
|
3693
|
+
}
|
|
3694
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3695
|
+
}
|
|
3696
|
+
function computeBounds(anchors) {
|
|
3697
|
+
if (anchors.length === 0) {
|
|
3698
|
+
return {
|
|
3699
|
+
min: { x: 0, y: 0, z: 0 },
|
|
3700
|
+
max: { x: 0, y: 0, z: 0 },
|
|
3701
|
+
center: { x: 0, y: 0, z: 0 },
|
|
3702
|
+
halfSize: 0
|
|
3703
|
+
};
|
|
3704
|
+
}
|
|
3705
|
+
let minX = Infinity, minY = Infinity, minZ = Infinity;
|
|
3706
|
+
let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
|
|
3707
|
+
for (const a of anchors) {
|
|
3708
|
+
const r = a.scale;
|
|
3709
|
+
minX = Math.min(minX, a.position[0] - r);
|
|
3710
|
+
minY = Math.min(minY, a.position[1] - r);
|
|
3711
|
+
minZ = Math.min(minZ, a.position[2] - r);
|
|
3712
|
+
maxX = Math.max(maxX, a.position[0] + r);
|
|
3713
|
+
maxY = Math.max(maxY, a.position[1] + r);
|
|
3714
|
+
maxZ = Math.max(maxZ, a.position[2] + r);
|
|
3715
|
+
}
|
|
3716
|
+
const cx = (minX + maxX) / 2;
|
|
3717
|
+
const cy = (minY + maxY) / 2;
|
|
3718
|
+
const cz = (minZ + maxZ) / 2;
|
|
3719
|
+
const halfSize = Math.max(
|
|
3720
|
+
(maxX - minX) / 2,
|
|
3721
|
+
(maxY - minY) / 2,
|
|
3722
|
+
(maxZ - minZ) / 2
|
|
3723
|
+
);
|
|
3724
|
+
return {
|
|
3725
|
+
min: { x: minX, y: minY, z: minZ },
|
|
3726
|
+
max: { x: maxX, y: maxY, z: maxZ },
|
|
3727
|
+
center: { x: cx, y: cy, z: cz },
|
|
3728
|
+
halfSize
|
|
3729
|
+
};
|
|
3730
|
+
}
|
|
3731
|
+
function sanitiseId(s) {
|
|
3732
|
+
return s.replace(/[^a-zA-Z0-9_]/g, "_").slice(0, 32);
|
|
3733
|
+
}
|
|
3734
|
+
function spatialPartition(composition, options) {
|
|
3735
|
+
return new SpatialPartitionPass(options).run(composition);
|
|
3736
|
+
}
|
|
3737
|
+
|
|
2916
3738
|
// src/types/effects.ts
|
|
2917
3739
|
function effectCategory(effect) {
|
|
2918
3740
|
return effect.split(":")[0];
|
|
@@ -3077,6 +3899,7 @@ var TRAIT_EFFECTS = {
|
|
|
3077
3899
|
// Audio traits
|
|
3078
3900
|
"@audio": ["audio:play"],
|
|
3079
3901
|
"@spatial_audio": ["audio:spatial"],
|
|
3902
|
+
"@gem_resonance": ["audio:spatial", "state:read"],
|
|
3080
3903
|
"@reverb": ["audio:reverb"],
|
|
3081
3904
|
"@music": ["audio:play", "audio:global"],
|
|
3082
3905
|
// State traits
|
|
@@ -3287,6 +4110,7 @@ var TRAIT_EFFECTS = {
|
|
|
3287
4110
|
"@mitosis": [],
|
|
3288
4111
|
"@mock": [],
|
|
3289
4112
|
"@model_load": [],
|
|
4113
|
+
"@modbus": ["io:network"],
|
|
3290
4114
|
"@motion_reduced": ["io:read", "io:write"],
|
|
3291
4115
|
"@mqtt_pub": ["io:network"],
|
|
3292
4116
|
"@mqtt_sink": ["io:network"],
|
|
@@ -3304,6 +4128,7 @@ var TRAIT_EFFECTS = {
|
|
|
3304
4128
|
"@object_tracking": ["state:read"],
|
|
3305
4129
|
"@occlusion": ["io:read", "io:write"],
|
|
3306
4130
|
"@openxr_hal": [],
|
|
4131
|
+
"@opc_ua": ["io:network"],
|
|
3307
4132
|
"@orbital": [],
|
|
3308
4133
|
"@package_signing": ["authority:own"],
|
|
3309
4134
|
"@pagerduty": [],
|
|
@@ -3496,7 +4321,9 @@ function inferFromTraits(traitNames) {
|
|
|
3496
4321
|
sources.set(e, existing);
|
|
3497
4322
|
}
|
|
3498
4323
|
} else {
|
|
3499
|
-
warnings.push(
|
|
4324
|
+
warnings.push(
|
|
4325
|
+
`Unknown trait '${normalized}': cannot infer effects, so the safety checker assumes pure. Register the trait in TRAIT_EFFECTS or add an explicit @effect declaration before relying on this inference.`
|
|
4326
|
+
);
|
|
3500
4327
|
}
|
|
3501
4328
|
}
|
|
3502
4329
|
return { row: new EffectRow(allEffects), sources, warnings };
|
|
@@ -3787,6 +4614,7 @@ var TRAIT_RESOURCE_COSTS = {
|
|
|
3787
4614
|
// ── Audio ──
|
|
3788
4615
|
"@audio": { audioSources: 1 },
|
|
3789
4616
|
"@spatial_audio": { audioSources: 1 },
|
|
4617
|
+
"@gem_resonance": { audioSources: 1 },
|
|
3790
4618
|
"@environmental_audio": { audioSources: 4, memoryMB: 2 },
|
|
3791
4619
|
"@voice_mesh": { audioSources: 1, networkMsgs: 10 },
|
|
3792
4620
|
"@voice_input": { audioSources: 1, memoryMB: 1 },
|
|
@@ -3799,6 +4627,8 @@ var TRAIT_RESOURCE_COSTS = {
|
|
|
3799
4627
|
"@lobby": { networkMsgs: 5, memoryMB: 2 },
|
|
3800
4628
|
"@mqtt_sink": { networkMsgs: 5 },
|
|
3801
4629
|
"@mqtt_source": { networkMsgs: 5 },
|
|
4630
|
+
"@modbus": { networkMsgs: 5 },
|
|
4631
|
+
"@opc_ua": { networkMsgs: 5 },
|
|
3802
4632
|
"@sync_tier": { networkMsgs: 2 },
|
|
3803
4633
|
"@crdt_room": { networkMsgs: 10, memoryMB: 4 },
|
|
3804
4634
|
"@shareplay": { networkMsgs: 5, memoryMB: 2 },
|
|
@@ -4512,6 +5342,7 @@ function quickSafetyCheck(traits, calls, options = {}) {
|
|
|
4512
5342
|
}
|
|
4513
5343
|
|
|
4514
5344
|
// src/compiler/platform/CrossRealityTraitRegistry.ts
|
|
5345
|
+
init_PlatformConditional();
|
|
4515
5346
|
var CATEGORY_DEFAULT_EMBODIMENT = {
|
|
4516
5347
|
vr: "FullAvatar",
|
|
4517
5348
|
ar: "FloatingAgent",
|
|
@@ -4799,6 +5630,7 @@ function createCrossRealityTraitRegistry() {
|
|
|
4799
5630
|
}
|
|
4800
5631
|
|
|
4801
5632
|
// src/compiler/platform/ModalitySelector.ts
|
|
5633
|
+
init_PlatformConditional();
|
|
4802
5634
|
var EMBODIMENT_TO_TARGET = {
|
|
4803
5635
|
FullAvatar: { primary: "openxr", fallback: "r3f" },
|
|
4804
5636
|
FloatingAgent: { primary: "visionos", fallback: "r3f" },
|
|
@@ -4924,7 +5756,7 @@ var CompilerBridge = class {
|
|
|
4924
5756
|
if (this.initialized) return;
|
|
4925
5757
|
try {
|
|
4926
5758
|
const [parserModule, compilerModule] = await Promise.all([
|
|
4927
|
-
import('./
|
|
5759
|
+
import('./HoloScriptPlusParser-F2Z56FJR.js'),
|
|
4928
5760
|
import('./compiler/r3f.js')
|
|
4929
5761
|
]);
|
|
4930
5762
|
this.modules = {
|
|
@@ -5053,6 +5885,16 @@ function getCompilerBridge() {
|
|
|
5053
5885
|
function json(value) {
|
|
5054
5886
|
return JSON.stringify(value, null, 2);
|
|
5055
5887
|
}
|
|
5888
|
+
function unsupportedPipelineStep(kind, type, name) {
|
|
5889
|
+
const typeLabel = type || "unknown";
|
|
5890
|
+
return `[PipelineNodeCompiler] Unsupported pipeline ${kind} type "${typeLabel}" (step: ${name}). PipelineNodeCompiler does not yet emit code for this type.`;
|
|
5891
|
+
}
|
|
5892
|
+
function unsupportedNodeThrow(kind, type, name) {
|
|
5893
|
+
return `(() => { throw new Error(${json(unsupportedPipelineStep(kind, type, name))}); })()`;
|
|
5894
|
+
}
|
|
5895
|
+
function unsupportedPythonRaise(kind, type, name) {
|
|
5896
|
+
return `raise NotImplementedError(${json(unsupportedPipelineStep(kind, type, name))})`;
|
|
5897
|
+
}
|
|
5056
5898
|
function emitSource(source) {
|
|
5057
5899
|
switch (source.type) {
|
|
5058
5900
|
case "rest":
|
|
@@ -5063,17 +5905,29 @@ function emitSource(source) {
|
|
|
5063
5905
|
case "list":
|
|
5064
5906
|
return json(source.items || []);
|
|
5065
5907
|
default:
|
|
5066
|
-
return "
|
|
5908
|
+
return unsupportedNodeThrow("source", source.type, source.name);
|
|
5067
5909
|
}
|
|
5068
5910
|
}
|
|
5069
5911
|
function emitFieldMappingTransform(t) {
|
|
5070
5912
|
const mappings = t.mappings || [];
|
|
5071
|
-
const
|
|
5072
|
-
|
|
5913
|
+
const unwrapMappings = mappings.filter((m) => m.from.endsWith("[]"));
|
|
5914
|
+
const valueMappings = mappings.filter((m) => !m.from.endsWith("[]"));
|
|
5915
|
+
const lines = [];
|
|
5916
|
+
for (const mapping of unwrapMappings) {
|
|
5917
|
+
lines.push(
|
|
5918
|
+
`data = data.flatMap((item) => unwrapPathValues(item, ${json(mapping.from)}).map((value) => ({ ...item, ${json(mapping.to)}: applyTransforms(value, ${json(mapping.transforms || [])}) })));`
|
|
5919
|
+
);
|
|
5920
|
+
}
|
|
5921
|
+
if (valueMappings.length === 0) {
|
|
5922
|
+
return lines.join("\n");
|
|
5923
|
+
}
|
|
5924
|
+
const mapExpr = valueMappings.map(
|
|
5925
|
+
(m) => `${json(m.to)}: applyTransforms(getPathValue(item, ${json(m.from)}), ${json(m.transforms || [])})`
|
|
5073
5926
|
).join(",\n ");
|
|
5074
|
-
|
|
5927
|
+
lines.push(`data = data.map((item) => ({
|
|
5075
5928
|
${mapExpr}
|
|
5076
|
-
}))
|
|
5929
|
+
}));`);
|
|
5930
|
+
return lines.join("\n");
|
|
5077
5931
|
}
|
|
5078
5932
|
function emitTransform(t) {
|
|
5079
5933
|
if ((t.type === "field_mapping" || !t.type) && t.mappings && t.mappings.length > 0) {
|
|
@@ -5105,11 +5959,11 @@ function emitSink(sink) {
|
|
|
5105
5959
|
return `await writeOutput(${json(sink.path || "./pipeline-output.jsonl")}, data, ${json(sink.format || "jsonl")}, ${json(Boolean(sink.append))});`;
|
|
5106
5960
|
case "rest":
|
|
5107
5961
|
case "webhook":
|
|
5108
|
-
return `await
|
|
5962
|
+
return `await postJSON(${json(sink.endpoint || "")}, data, { method: ${json(sink.method || "POST")} });`;
|
|
5109
5963
|
case "mcp":
|
|
5110
5964
|
return `console.warn(${json(`[${sink.name}] mcp sink requires host integration: ${sink.server || ""}/${sink.tool || ""}`)});`;
|
|
5111
5965
|
default:
|
|
5112
|
-
return
|
|
5966
|
+
return `${unsupportedNodeThrow("sink", sink.type, sink.name)};`;
|
|
5113
5967
|
}
|
|
5114
5968
|
}
|
|
5115
5969
|
function emitPythonSource(source) {
|
|
@@ -5122,7 +5976,7 @@ function emitPythonSource(source) {
|
|
|
5122
5976
|
case "list":
|
|
5123
5977
|
return `datasets[${json(source.name)}] = ${json(source.items || [])}`;
|
|
5124
5978
|
default:
|
|
5125
|
-
return
|
|
5979
|
+
return unsupportedPythonRaise("source", source.type, source.name);
|
|
5126
5980
|
}
|
|
5127
5981
|
}
|
|
5128
5982
|
function emitPythonFieldMappingTransform(t) {
|
|
@@ -5171,7 +6025,7 @@ function emitPythonSink(sink) {
|
|
|
5171
6025
|
case "mcp":
|
|
5172
6026
|
return `print(${json(`[${sink.name}] mcp sink requires host integration: ${sink.server || ""}/${sink.tool || ""}`)})`;
|
|
5173
6027
|
default:
|
|
5174
|
-
return
|
|
6028
|
+
return unsupportedPythonRaise("sink", sink.type, sink.name);
|
|
5175
6029
|
}
|
|
5176
6030
|
}
|
|
5177
6031
|
function compilePipelineToNode(pipeline, options = {}) {
|
|
@@ -5188,18 +6042,55 @@ function compilePipelineToNode(pipeline, options = {}) {
|
|
|
5188
6042
|
*/
|
|
5189
6043
|
|
|
5190
6044
|
import fs from 'node:fs/promises';
|
|
6045
|
+
import path from 'node:path';
|
|
6046
|
+
|
|
6047
|
+
const RUN_DATE = new Date().toISOString().slice(0, 10);
|
|
6048
|
+
|
|
6049
|
+
function resolveTemplate(value, context = {}) {
|
|
6050
|
+
if (typeof value !== 'string') return value;
|
|
6051
|
+
return value
|
|
6052
|
+
.replace(/\\$\\{date\\}/g, RUN_DATE)
|
|
6053
|
+
.replace(/\\$\\{env\\.([A-Za-z_][A-Za-z0-9_]*)\\}/g, (_match, name) => process.env[name] ?? '')
|
|
6054
|
+
.replace(/\\$\\{([A-Za-z_][A-Za-z0-9_.]*)\\}/g, (_match, key) => {
|
|
6055
|
+
const found = key.split('.').reduce((acc, part) => (acc && typeof acc === 'object' ? acc[part] : undefined), context);
|
|
6056
|
+
return found === undefined || found === null ? '' : String(found);
|
|
6057
|
+
});
|
|
6058
|
+
}
|
|
6059
|
+
|
|
6060
|
+
function normalizeOutputPath(rawPath, format) {
|
|
6061
|
+
const resolved = resolveTemplate(rawPath);
|
|
6062
|
+
if (!resolved) return format === 'json' ? './pipeline-output.json' : './pipeline-output.jsonl';
|
|
6063
|
+
if (path.extname(resolved)) return resolved;
|
|
6064
|
+
return path.join(resolved, format === 'json' ? 'pipeline-output.json' : 'pipeline-output.jsonl');
|
|
6065
|
+
}
|
|
5191
6066
|
|
|
5192
6067
|
async function fetchJSON(url, init) {
|
|
5193
|
-
|
|
5194
|
-
|
|
6068
|
+
const resolvedUrl = resolveTemplate(url);
|
|
6069
|
+
if (!resolvedUrl) return [];
|
|
6070
|
+
const res = await fetch(resolvedUrl, init);
|
|
5195
6071
|
if (!res.ok) throw new Error(\`Request failed: \${res.status} \${res.statusText}\`);
|
|
5196
6072
|
const body = await res.json();
|
|
5197
6073
|
return Array.isArray(body) ? body : [body];
|
|
5198
6074
|
}
|
|
5199
6075
|
|
|
6076
|
+
async function postJSON(url, data, init) {
|
|
6077
|
+
const resolvedUrl = resolveTemplate(url, { data });
|
|
6078
|
+
if (!resolvedUrl) {
|
|
6079
|
+
console.warn('[PipelineNodeCompiler] skipping empty webhook/rest sink endpoint');
|
|
6080
|
+
return;
|
|
6081
|
+
}
|
|
6082
|
+
const res = await fetch(resolvedUrl, {
|
|
6083
|
+
...init,
|
|
6084
|
+
headers: { 'content-type': 'application/json', ...(init?.headers || {}) },
|
|
6085
|
+
body: JSON.stringify(data),
|
|
6086
|
+
});
|
|
6087
|
+
if (!res.ok) throw new Error(\`Request failed: \${res.status} \${res.statusText}\`);
|
|
6088
|
+
}
|
|
6089
|
+
|
|
5200
6090
|
async function readJSONArray(filePath) {
|
|
5201
|
-
|
|
5202
|
-
|
|
6091
|
+
const resolvedPath = resolveTemplate(filePath);
|
|
6092
|
+
if (!resolvedPath) return [];
|
|
6093
|
+
const raw = await fs.readFile(resolvedPath, 'utf8');
|
|
5203
6094
|
const parsed = JSON.parse(raw);
|
|
5204
6095
|
return Array.isArray(parsed) ? parsed : [parsed];
|
|
5205
6096
|
}
|
|
@@ -5217,6 +6108,22 @@ function applyTransforms(value, transforms) {
|
|
|
5217
6108
|
return v;
|
|
5218
6109
|
}
|
|
5219
6110
|
|
|
6111
|
+
function getPathValue(item, pathExpr) {
|
|
6112
|
+
const cleanPath = String(pathExpr || '').replace(/\\[\\]$/, '');
|
|
6113
|
+
if (!cleanPath) return item;
|
|
6114
|
+
return cleanPath.split('.').reduce((acc, part) => {
|
|
6115
|
+
if (acc == null || typeof acc !== 'object') return undefined;
|
|
6116
|
+
return acc[part];
|
|
6117
|
+
}, item);
|
|
6118
|
+
}
|
|
6119
|
+
|
|
6120
|
+
function unwrapPathValues(item, pathExpr) {
|
|
6121
|
+
const value = getPathValue(item, pathExpr);
|
|
6122
|
+
if (Array.isArray(value)) return value;
|
|
6123
|
+
if (value == null) return [];
|
|
6124
|
+
return [value];
|
|
6125
|
+
}
|
|
6126
|
+
|
|
5220
6127
|
function evalCondition(item, condition) {
|
|
5221
6128
|
try {
|
|
5222
6129
|
const fn = new Function('item', \`with (item) { return (\${condition}); }\`);
|
|
@@ -5237,17 +6144,20 @@ function validateItem(item, fields) {
|
|
|
5237
6144
|
return true;
|
|
5238
6145
|
}
|
|
5239
6146
|
|
|
5240
|
-
async function writeOutput(
|
|
6147
|
+
async function writeOutput(rawPath, data, format, append) {
|
|
6148
|
+
const outputPath = normalizeOutputPath(rawPath, format);
|
|
6149
|
+
await fs.mkdir(path.dirname(outputPath), { recursive: true });
|
|
6150
|
+
|
|
5241
6151
|
if (format === 'json') {
|
|
5242
6152
|
const text = JSON.stringify(data, null, 2);
|
|
5243
|
-
if (append) await fs.appendFile(
|
|
5244
|
-
else await fs.writeFile(
|
|
6153
|
+
if (append) await fs.appendFile(outputPath, text + '\\n');
|
|
6154
|
+
else await fs.writeFile(outputPath, text);
|
|
5245
6155
|
return;
|
|
5246
6156
|
}
|
|
5247
6157
|
|
|
5248
6158
|
const lines = data.map((d) => JSON.stringify(d)).join('\\n') + '\\n';
|
|
5249
|
-
if (append) await fs.appendFile(
|
|
5250
|
-
else await fs.writeFile(
|
|
6159
|
+
if (append) await fs.appendFile(outputPath, lines);
|
|
6160
|
+
else await fs.writeFile(outputPath, lines);
|
|
5251
6161
|
}
|
|
5252
6162
|
|
|
5253
6163
|
export async function runPipeline() {
|
|
@@ -5469,6 +6379,6 @@ function compilePipelineSource(source, options = {}) {
|
|
|
5469
6379
|
return compilePipelineSourceToNode(source, options.node);
|
|
5470
6380
|
}
|
|
5471
6381
|
|
|
5472
|
-
export { A2AAgentCardCompiler, A2AAgentCardCompiler_exports,
|
|
5473
|
-
//# sourceMappingURL=chunk-
|
|
5474
|
-
//# sourceMappingURL=chunk-
|
|
6382
|
+
export { A2AAgentCardCompiler, A2AAgentCardCompiler_exports, BUILTIN_RESOURCES, CAPABILITY_HIERARCHY, CATEGORY_DEFAULT_EMBODIMENT, CompilerBridge, CrossRealityTraitRegistry, EFFECTS_BY_CATEGORY, EFFECT_TO_CAPABILITY, EffectChecker, EffectRow, GaussianSplattingCompiler, HANDOFF_PATH_RULES, LinearTypeChecker, MVC_BUDGET_CONSTRAINTS, NIRCompiler, NIRCompiler_exports, PLATFORM_BUDGETS, PLATFORM_EMBODIMENT_OVERRIDES, ResourceBudgetAnalyzer, SHARED_SORT_SHADER_PATH, SpatialPartitionPass, TRAIT_EFFECTS, TRAIT_RESOURCE_COSTS, TRAIT_RESOURCE_MAP, TRUST_LEVEL_CAPABILITIES, ThreeJSCompiler, ThreeJSCompiler_exports, USDZPipeline, bestCategoryForTraits, buildSafetyReport, checkCapabilities, compilePipelineSource, compilePipelineSourceToNode, compilePipelineSourceToPython, compilePipelineToNode, compilePipelineToPython, createCrossRealityTraitRegistry, createEffectChecker, createGaussianSplattingCompiler, dangerLevel, deriveRequirements, detectMultiUserSharedSort, effectCategory, expandCapabilities, formatReport, generateCertificate, getCompilerBridge, getCrossRealityTraitRegistry, inferFromBuiltins, inferFromTraits, init_A2AAgentCardCompiler, init_NIRCompiler, init_ThreeJSCompiler, isSafeTraitSet, knownBuiltins, knownTraits, quickSafetyCheck, resetCrossRealityTraitRegistry, runSafetyPass, selectModality, selectModalityForAll, spatialPartition };
|
|
6383
|
+
//# sourceMappingURL=chunk-QCCBXSCE.js.map
|
|
6384
|
+
//# sourceMappingURL=chunk-QCCBXSCE.js.map
|