@holoscript/core 7.0.0 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/bin/holoscript.cjs +3 -0
- package/dist/GLTFPipeline-N6B6PJ6G.cjs +38 -0
- package/dist/GLTFPipeline-P3WMNYCN.js +17 -0
- package/dist/HoloScriptPlusParser-7FBIFUFC.js +693 -0
- package/dist/HoloScriptPlusParser-A2W7OCN2.cjs +698 -0
- package/dist/HoloScriptPlusParser-F2Z56FJR.js +10 -0
- package/dist/HoloScriptPlusParser-WKHRIH6T.cjs +27 -0
- package/dist/HoloScriptRuntime-CBYJX3LZ.js +10 -0
- package/dist/HoloScriptRuntime-VJ374RER.cjs +19 -0
- package/dist/USDZExporter-3FWJ25JI.cjs +1037 -0
- package/dist/USDZExporter-D2HQLQYK.js +1035 -0
- 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-2BSMSUCE.js +1941 -0
- package/dist/chunk-2IWC4FP7.cjs +1189 -0
- package/dist/chunk-2M2DPHKB.js +762 -0
- package/dist/chunk-2X7NGX3M.js +2426 -0
- package/dist/chunk-2YSNA2F2.cjs +1274 -0
- package/dist/chunk-3FOKASKO.cjs +348 -0
- package/dist/chunk-3WZEJHUQ.cjs +116 -0
- package/dist/chunk-4C57PR42.js +468 -0
- package/dist/chunk-4GU5GCIY.js +1384 -0
- package/dist/chunk-4N4SXXWF.js +769 -0
- package/dist/chunk-4PDEPEQW.cjs +41 -0
- package/dist/chunk-4R6SBXDB.js +45 -0
- package/dist/chunk-4SDKXQ4C.js +811 -0
- package/dist/chunk-4V2E7U7Q.cjs +2015 -0
- package/dist/chunk-5FSKKMR7.cjs +2092 -0
- package/dist/chunk-5GLCTO44.js +161 -0
- package/dist/chunk-5H2G27PK.cjs +627 -0
- package/dist/chunk-5JEU52DW.js +382 -0
- package/dist/chunk-5NWINHR5.cjs +689 -0
- package/dist/chunk-5S7RKFGR.cjs +446 -0
- package/dist/chunk-5WUNN6ZN.cjs +428 -0
- package/dist/chunk-6CTRH7HT.cjs +1985 -0
- package/dist/chunk-6EX3I5P4.cjs +130 -0
- package/dist/chunk-6Q7RC2MK.cjs +1418 -0
- package/dist/chunk-7H33U5SM.cjs +413 -0
- package/dist/chunk-7M3PNU2M.cjs +672 -0
- package/dist/chunk-7T25IEZ2.js +449 -0
- package/dist/chunk-7V4JI5TB.cjs +6947 -0
- package/dist/chunk-A6KINLZJ.js +236 -0
- package/dist/chunk-ADADVMXY.js +404 -0
- package/dist/chunk-AIA52I7T.cjs +543 -0
- package/dist/chunk-ALC6K7GL.cjs +4402 -0
- package/dist/chunk-ANXZFVY2.js +113 -0
- package/dist/chunk-AOVGZ25K.cjs +56583 -0
- package/dist/chunk-AVJHHUC5.cjs +718 -0
- package/dist/chunk-BGY3SDG3.js +4396 -0
- package/dist/chunk-BOVPWH4H.js +3857 -0
- package/dist/chunk-BRQJKJGT.cjs +20 -0
- package/dist/chunk-C37BHB7N.cjs +636 -0
- package/dist/chunk-CBJY23VL.js +126 -0
- package/dist/chunk-CCATWPXM.js +778 -0
- package/dist/chunk-CIWWXYHZ.cjs +50 -0
- package/dist/chunk-CMT5NMMS.js +669 -0
- package/dist/chunk-CR4FMIWL.cjs +1049 -0
- package/dist/chunk-CR7XRXRN.cjs +639 -0
- package/dist/chunk-CSD27UNQ.js +2176 -0
- package/dist/chunk-D3STJ56J.js +714 -0
- package/dist/chunk-DAJXW4KX.js +725 -0
- package/dist/chunk-DHO2YRIM.js +756 -0
- package/dist/chunk-DTGBOSEM.cjs +319 -0
- package/dist/chunk-E6XXE66V.js +2252 -0
- package/dist/chunk-E7JP3BS3.cjs +61 -0
- package/dist/chunk-EKBKLK7P.js +1169 -0
- package/dist/chunk-EKYL4PE3.cjs +404 -0
- package/dist/chunk-EXKSFGSX.cjs +274 -0
- package/dist/chunk-EXUP2BUM.cjs +1173 -0
- package/dist/chunk-FDSGHPAK.js +130 -0
- package/dist/chunk-FEWUHQNM.cjs +144 -0
- package/dist/chunk-FFAOS5HQ.js +70 -0
- package/dist/chunk-FGGJQRLZ.js +270 -0
- package/dist/chunk-FHP6LXJS.js +415 -0
- package/dist/chunk-FJPADH77.cjs +666 -0
- package/dist/chunk-FL33V6U7.js +421 -0
- package/dist/chunk-FYSPZT4V.cjs +169 -0
- package/dist/chunk-GIOYPNTH.js +5575 -0
- package/dist/chunk-GJNCFRJU.cjs +125 -0
- package/dist/chunk-GMP623FG.cjs +1508 -0
- package/dist/chunk-GQHQOPXZ.cjs +5580 -0
- package/dist/chunk-GTU2Z2WW.cjs +262 -0
- package/dist/chunk-GYZE55MO.js +2007 -0
- package/dist/chunk-GZG4KA4E.js +529 -0
- package/dist/chunk-H652NHX5.js +600 -0
- package/dist/chunk-HCCQLAA4.cjs +74 -0
- package/dist/chunk-HKEXJUWS.cjs +4007 -0
- package/dist/chunk-HNDK4IQU.cjs +5737 -0
- package/dist/chunk-HR2OSYVQ.js +56165 -0
- package/dist/chunk-HYNTS5CP.js +422 -0
- package/dist/chunk-I6XZ5DZF.cjs +488 -0
- package/dist/chunk-ILRBGFVD.cjs +72 -0
- package/dist/chunk-IUDGEUDO.cjs +1409 -0
- package/dist/chunk-IUTY5WQ2.cjs +424 -0
- package/dist/chunk-IVY74O6C.js +247 -0
- package/dist/chunk-IWC5DM2M.cjs +611 -0
- package/dist/chunk-J32ZJZJH.js +554 -0
- package/dist/chunk-J52VSAQ7.js +6884 -0
- package/dist/chunk-J6M4FPK5.js +421 -0
- package/dist/chunk-J7XZV333.js +844 -0
- package/dist/chunk-JBNDTXXV.cjs +2433 -0
- package/dist/chunk-JC5YBPSF.cjs +984 -0
- package/dist/chunk-JD7CIZ33.js +1949 -0
- package/dist/chunk-JIBL5LRK.js +4287 -0
- package/dist/chunk-JIYN45TV.cjs +2525 -0
- package/dist/chunk-K574J76X.cjs +457 -0
- package/dist/chunk-KHDZJE5D.cjs +2196 -0
- package/dist/chunk-KKFZ3B6J.cjs +557 -0
- package/dist/chunk-KKP7JKN4.cjs +6002 -0
- package/dist/chunk-KPJL34Y7.cjs +186 -0
- package/dist/chunk-KQCN6AKJ.cjs +3042 -0
- package/dist/chunk-L5LKKENW.cjs +424 -0
- package/dist/chunk-LHAXPADA.js +882 -0
- package/dist/chunk-LM2VU56C.cjs +37 -0
- package/dist/chunk-M56JSP4A.js +400 -0
- package/dist/chunk-MBOOR7X4.js +18 -0
- package/dist/chunk-MQWAT42R.cjs +4310 -0
- package/dist/chunk-MXFUTKCO.js +56 -0
- package/dist/chunk-MYY4PMWX.cjs +264 -0
- package/dist/chunk-N75IH2HY.js +258 -0
- package/dist/chunk-NCWCUZNS.cjs +72 -0
- package/dist/chunk-NG77ATEW.cjs +778 -0
- package/dist/chunk-NW5G5FBQ.js +215 -0
- package/dist/chunk-OBIYPYYS.cjs +1993 -0
- package/dist/chunk-OH2FAIVU.js +608 -0
- package/dist/chunk-OIQYIIO3.cjs +473 -0
- package/dist/chunk-OL46QLBJ.js +61 -0
- package/dist/chunk-OMXII44L.js +5386 -0
- package/dist/chunk-OSYNRVOV.cjs +243 -0
- package/dist/chunk-PGANYCAG.cjs +220 -0
- package/dist/chunk-PHENW4MQ.js +65 -0
- package/dist/chunk-PY37LNDP.js +686 -0
- package/dist/chunk-Q56TT7IL.js +483 -0
- package/dist/chunk-QD32ADK6.js +1046 -0
- package/dist/chunk-QPOQ7VPI.js +1491 -0
- package/dist/chunk-QPSKHBJP.js +5963 -0
- package/dist/chunk-QXH7QDSZ.js +1989 -0
- package/dist/chunk-R24NNAEG.js +1399 -0
- package/dist/chunk-R75BSDH7.cjs +50 -0
- package/dist/chunk-RARB3MBR.js +207 -0
- package/dist/chunk-ROHLEP2W.cjs +847 -0
- package/dist/chunk-S3MDHNKB.cjs +490 -0
- package/dist/chunk-S6YWHCKV.cjs +410 -0
- package/dist/chunk-SIEXCILW.js +229 -0
- package/dist/chunk-SLU6UPJI.cjs +410 -0
- package/dist/chunk-SMIWS6DE.cjs +212 -0
- package/dist/chunk-T5J7ZKP3.cjs +4885 -0
- package/dist/chunk-TDCNJHWO.js +341 -0
- package/dist/chunk-TG7O4WBC.js +406 -0
- package/dist/chunk-THCK6ECW.js +2085 -0
- package/dist/chunk-TJHVSBP2.js +439 -0
- package/dist/chunk-TVHSPJ4N.cjs +606 -0
- package/dist/chunk-TWUXUCEW.cjs +781 -0
- package/dist/chunk-U44IKGG7.cjs +5390 -0
- package/dist/chunk-UFZZ7TSN.cjs +886 -0
- package/dist/chunk-UJXISJBN.js +487 -0
- package/dist/chunk-UOIGFQXC.cjs +9750 -0
- package/dist/chunk-URG2SJLK.js +2521 -0
- package/dist/chunk-UWJHCOH2.js +623 -0
- package/dist/chunk-V6MKC2FZ.js +979 -0
- package/dist/chunk-VJ3L7CHT.cjs +169 -0
- package/dist/chunk-VMLKSV26.js +1216 -0
- package/dist/chunk-VVKVQZI6.js +55 -0
- package/dist/chunk-W6RW64BB.cjs +1219 -0
- package/dist/chunk-WKX5AMOY.js +309 -0
- package/dist/chunk-WNNE3PO3.js +34 -0
- package/dist/chunk-WRKUDAZJ.js +3038 -0
- package/dist/chunk-WRLUBRKS.cjs +1943 -0
- package/dist/chunk-WRNEH5MO.js +3169 -0
- package/dist/chunk-WRWEX5ZF.js +658 -0
- package/dist/chunk-X3GJPRVK.cjs +3246 -0
- package/dist/chunk-X3UVCWNL.cjs +2257 -0
- package/dist/chunk-XB274MW5.cjs +814 -0
- package/dist/chunk-XHIV6326.cjs +793 -0
- package/dist/chunk-XIVIE43A.cjs +729 -0
- package/dist/chunk-XJAN7CZG.cjs +432 -0
- package/dist/chunk-XKTPFXGA.js +164 -0
- package/dist/chunk-XL6INWKT.js +121 -0
- package/dist/chunk-XSFNHP2E.js +632 -0
- package/dist/chunk-XT6JY5W5.js +9684 -0
- package/dist/chunk-XUILI4KB.cjs +430 -0
- package/dist/chunk-YF2I3MV3.js +46 -0
- package/dist/chunk-YIMN575O.js +4847 -0
- package/dist/chunk-YIVFJNYV.js +176 -0
- package/dist/chunk-YKGPCZEE.cjs +237 -0
- package/dist/chunk-YN2YWTXW.js +5731 -0
- package/dist/chunk-YN6V7R3L.cjs +327 -0
- package/dist/chunk-YQELFNJV.js +39 -0
- package/dist/chunk-YVD3CSO3.js +1183 -0
- package/dist/chunk-YVOAF4ML.js +623 -0
- package/dist/chunk-YWOBW2PV.cjs +759 -0
- package/dist/chunk-YYXH45E2.js +426 -0
- package/dist/chunk-ZDSYWBIE.cjs +69 -0
- package/dist/chunk-ZU7NIRT6.js +325 -0
- package/dist/chunk-ZZ7RO2UQ.js +1243 -0
- package/dist/cli/holoscript-runner.cjs +2255 -0
- package/dist/cli/holoscript-runner.js +2230 -0
- package/dist/codebase/index.cjs +336 -0
- package/dist/codebase/index.js +331 -0
- package/dist/compiler/agent-inference.cjs +31 -0
- package/dist/compiler/agent-inference.js +8 -0
- package/dist/compiler/android-xr.cjs +24 -0
- package/dist/compiler/android-xr.js +14 -0
- package/dist/compiler/android.cjs +24 -0
- package/dist/compiler/android.js +14 -0
- package/dist/compiler/ar.cjs +23 -0
- package/dist/compiler/ar.js +11 -0
- package/dist/compiler/babylon.cjs +21 -0
- package/dist/compiler/babylon.js +15 -0
- package/dist/compiler/business-quest.cjs +43 -0
- package/dist/compiler/business-quest.js +4 -0
- package/dist/compiler/coco.cjs +27 -0
- package/dist/compiler/coco.js +4 -0
- 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 +609 -0
- package/dist/compiler/domain-block-utils.js +11 -0
- package/dist/compiler/dtdl.cjs +27 -0
- package/dist/compiler/dtdl.js +11 -0
- package/dist/compiler/gltf-pipeline.cjs +39 -0
- package/dist/compiler/gltf-pipeline.js +4 -0
- package/dist/compiler/godot.cjs +18 -0
- package/dist/compiler/godot.js +12 -0
- package/dist/compiler/incremental.cjs +34 -0
- package/dist/compiler/incremental.js +9 -0
- package/dist/compiler/index.cjs +5408 -0
- package/dist/compiler/index.d.ts +334 -21
- package/dist/compiler/index.js +5069 -0
- package/dist/compiler/ios.cjs +23 -0
- package/dist/compiler/ios.js +13 -0
- 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 +24 -0
- package/dist/compiler/multi-layer.js +15 -0
- package/dist/compiler/nodetoy.cjs +23 -0
- package/dist/compiler/nodetoy.d.ts +69 -0
- package/dist/compiler/nodetoy.js +4 -0
- package/dist/compiler/openxr.cjs +19 -0
- package/dist/compiler/openxr.js +13 -0
- package/dist/compiler/playcanvas.cjs +19 -0
- package/dist/compiler/playcanvas.js +13 -0
- package/dist/compiler/r3f.cjs +39 -0
- package/dist/compiler/r3f.d.ts +22 -0
- package/dist/compiler/r3f.js +17 -0
- package/dist/compiler/remotion.cjs +23 -0
- package/dist/compiler/remotion.js +4 -0
- package/dist/compiler/reproducibility.cjs +39 -0
- package/dist/compiler/reproducibility.js +4 -0
- package/dist/compiler/sdf.cjs +24 -0
- package/dist/compiler/sdf.js +12 -0
- package/dist/compiler/semantic-scene.cjs +31 -0
- package/dist/compiler/semantic-scene.js +4 -0
- package/dist/compiler/state.cjs +21 -0
- package/dist/compiler/state.js +11 -0
- package/dist/compiler/trait-composition.cjs +30 -0
- package/dist/compiler/trait-composition.js +9 -0
- package/dist/compiler/unity.cjs +19 -0
- package/dist/compiler/unity.js +13 -0
- package/dist/compiler/unreal.cjs +23 -0
- package/dist/compiler/unreal.js +13 -0
- package/dist/compiler/urdf.cjs +52 -0
- package/dist/compiler/urdf.js +12 -0
- package/dist/compiler/usd-physics.cjs +26 -0
- package/dist/compiler/usd-physics.js +9 -0
- package/dist/compiler/visionos.cjs +19 -0
- package/dist/compiler/visionos.js +13 -0
- package/dist/compiler/vrchat.cjs +22 -0
- package/dist/compiler/vrchat.js +12 -0
- package/dist/compiler/vrr.cjs +24 -0
- package/dist/compiler/vrr.js +12 -0
- package/dist/compiler/wasm.cjs +36 -0
- package/dist/compiler/wasm.js +12 -0
- package/dist/compiler/webgpu.cjs +18 -0
- package/dist/compiler/webgpu.js +12 -0
- package/dist/coordinators/index.cjs +1266 -0
- package/dist/coordinators/index.d.ts +72 -1
- package/dist/coordinators/index.js +1259 -0
- package/dist/debugger.cjs +24 -0
- package/dist/debugger.js +11 -0
- package/dist/dist-ACXG6IH5.cjs +3113 -0
- package/dist/dist-VD4L6V7Q.js +3076 -0
- package/dist/entries/interop.cjs +64 -0
- package/dist/entries/interop.js +7 -0
- package/dist/entries/scripting.cjs +55 -0
- package/dist/entries/scripting.js +10 -0
- 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 +44660 -0
- package/dist/index.d.ts +978 -21
- package/dist/index.js +41422 -0
- package/dist/math/tropical-spmv.cjs +45 -0
- package/dist/math/tropical-spmv.js +4 -0
- package/dist/math/vec3.cjs +57 -0
- package/dist/math/vec3.js +4 -0
- package/dist/ml-dsa-FSKBTE3W.cjs +1265 -0
- package/dist/ml-dsa-Z7JDKW4L.js +1265 -0
- package/dist/paper-0c-spike/index.cjs +150 -0
- package/dist/paper-0c-spike/index.js +141 -0
- package/dist/parser.cjs +61 -0
- package/dist/parser.d.ts +11 -0
- package/dist/parser.js +12 -0
- package/dist/playwright-3AT3AKTV.cjs +98673 -0
- package/dist/playwright-VZPDVUEQ.js +98660 -0
- package/dist/reconstruction/index.cjs +153 -0
- package/dist/reconstruction/index.d.ts +29 -2
- package/dist/reconstruction/index.js +8 -0
- package/dist/runtime.cjs +316 -0
- package/dist/runtime.d.ts +61 -0
- package/dist/runtime.js +31 -0
- package/dist/self-improvement/index.cjs +563 -0
- package/dist/self-improvement/index.js +545 -0
- package/dist/src-4ROC227P.cjs +2094 -0
- package/dist/src-HCCCSYP7.js +2073 -0
- package/dist/storage/index.cjs +38 -0
- package/dist/storage/index.js +5 -0
- package/dist/testing.cjs +25 -0
- package/dist/testing.d.ts +70 -0
- package/dist/testing.js +4 -0
- package/dist/traitDocs/traitDocs.cjs +33 -0
- package/dist/traitDocs/traitDocs.js +7 -0
- package/dist/traits/botanical-lotus.cjs +177 -0
- package/dist/traits/botanical-lotus.d.ts +502 -0
- package/dist/traits/botanical-lotus.js +7 -0
- package/dist/traits/engines/index.cjs +520 -0
- package/dist/traits/engines/index.js +380 -0
- package/dist/traits/index.cjs +24548 -0
- package/dist/traits/index.d.ts +171 -35
- package/dist/traits/index.js +21638 -0
- 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 +19 -0
- package/dist/type-checker.js +6 -0
- 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 +93 -49
|
@@ -0,0 +1,4007 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkKKP7JKN4_cjs = require('./chunk-KKP7JKN4.cjs');
|
|
4
|
+
var chunkHCCQLAA4_cjs = require('./chunk-HCCQLAA4.cjs');
|
|
5
|
+
|
|
6
|
+
// src/compiler/DomainBlockCompilerMixin.ts
|
|
7
|
+
function esc(value, target) {
|
|
8
|
+
return chunkKKP7JKN4_cjs.escapeStringValue(value, target);
|
|
9
|
+
}
|
|
10
|
+
function isPhysicalMaterial(mat) {
|
|
11
|
+
return PHYSICAL_MATERIAL_KEYS.some((k) => mat[k] !== void 0);
|
|
12
|
+
}
|
|
13
|
+
function compileMaterialBlock(block) {
|
|
14
|
+
const type = block.keyword === "unlit_material" ? "unlit" : block.keyword === "shader" ? "shader" : "pbr";
|
|
15
|
+
const textureMaps = {};
|
|
16
|
+
const otherProps = {};
|
|
17
|
+
for (const [key, value] of Object.entries(block.properties || {})) {
|
|
18
|
+
if (key.endsWith("_map")) {
|
|
19
|
+
textureMaps[key] = String(value);
|
|
20
|
+
} else {
|
|
21
|
+
otherProps[key] = value;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
name: block.name || "unnamed",
|
|
26
|
+
type,
|
|
27
|
+
baseColor: otherProps.baseColor,
|
|
28
|
+
roughness: otherProps.roughness,
|
|
29
|
+
metallic: otherProps.metallic,
|
|
30
|
+
opacity: otherProps.opacity,
|
|
31
|
+
ior: otherProps.ior,
|
|
32
|
+
emissiveColor: otherProps.emissive_color,
|
|
33
|
+
emissiveIntensity: otherProps.emissive_intensity,
|
|
34
|
+
clearcoat: otherProps.clearcoat ?? otherProps.clear_coat,
|
|
35
|
+
clearcoatRoughness: otherProps.clearcoat_roughness ?? otherProps.clearcoatRoughness,
|
|
36
|
+
transmission: otherProps.transmission,
|
|
37
|
+
thickness: otherProps.thickness,
|
|
38
|
+
sheen: otherProps.sheen,
|
|
39
|
+
sheenColor: otherProps.sheen_color ?? otherProps.sheenColor,
|
|
40
|
+
sheenRoughness: otherProps.sheen_roughness ?? otherProps.sheenRoughness,
|
|
41
|
+
specularIntensity: otherProps.specular_intensity ?? otherProps.specularIntensity,
|
|
42
|
+
iridescence: otherProps.iridescence,
|
|
43
|
+
attenuationColor: otherProps.attenuation_color ?? otherProps.attenuationColor,
|
|
44
|
+
attenuationDistance: otherProps.attenuation_distance ?? otherProps.attenuationDistance,
|
|
45
|
+
textureMaps,
|
|
46
|
+
traits: block.traits || []
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function compilePhysicsBlock(block) {
|
|
50
|
+
const colliders = [];
|
|
51
|
+
const forceFields = [];
|
|
52
|
+
const joints = [];
|
|
53
|
+
let rigidbody;
|
|
54
|
+
for (const child of block.children || []) {
|
|
55
|
+
const c = child;
|
|
56
|
+
if (c.type !== "DomainBlock") continue;
|
|
57
|
+
const kw = c.keyword;
|
|
58
|
+
if (kw === "collider" || kw === "trigger") {
|
|
59
|
+
colliders.push({
|
|
60
|
+
type: kw,
|
|
61
|
+
shape: c.name,
|
|
62
|
+
// shape stored as name for collider blocks
|
|
63
|
+
properties: c.properties || {}
|
|
64
|
+
});
|
|
65
|
+
} else if (kw === "rigidbody") {
|
|
66
|
+
rigidbody = { properties: c.properties || {} };
|
|
67
|
+
} else if ([
|
|
68
|
+
"force_field",
|
|
69
|
+
"gravity_zone",
|
|
70
|
+
"wind_zone",
|
|
71
|
+
"buoyancy_zone",
|
|
72
|
+
"magnetic_field",
|
|
73
|
+
"drag_zone"
|
|
74
|
+
].includes(kw)) {
|
|
75
|
+
forceFields.push({
|
|
76
|
+
keyword: kw,
|
|
77
|
+
name: c.name,
|
|
78
|
+
properties: c.properties || {}
|
|
79
|
+
});
|
|
80
|
+
} else {
|
|
81
|
+
joints.push({
|
|
82
|
+
keyword: kw,
|
|
83
|
+
name: c.name,
|
|
84
|
+
properties: c.properties || {}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
keyword: block.keyword,
|
|
90
|
+
name: block.name,
|
|
91
|
+
properties: block.properties || {},
|
|
92
|
+
colliders: colliders.length > 0 ? colliders : void 0,
|
|
93
|
+
rigidbody,
|
|
94
|
+
forceFields: forceFields.length > 0 ? forceFields : void 0,
|
|
95
|
+
joints: joints.length > 0 ? joints : void 0
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function compileParticleBlock(block) {
|
|
99
|
+
const modules = [];
|
|
100
|
+
for (const child of block.children || []) {
|
|
101
|
+
const c = child;
|
|
102
|
+
if (c.type === "DomainBlock") {
|
|
103
|
+
modules.push({
|
|
104
|
+
type: c.keyword,
|
|
105
|
+
properties: c.properties || {}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
keyword: block.keyword,
|
|
111
|
+
name: block.name || "unnamed",
|
|
112
|
+
traits: block.traits || [],
|
|
113
|
+
properties: block.properties || {},
|
|
114
|
+
modules
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function compilePostProcessingBlock(block) {
|
|
118
|
+
const effects = [];
|
|
119
|
+
for (const child of block.children || []) {
|
|
120
|
+
const c = child;
|
|
121
|
+
if (c.type === "DomainBlock") {
|
|
122
|
+
effects.push({
|
|
123
|
+
type: c.keyword,
|
|
124
|
+
properties: c.properties || {}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
keyword: block.keyword,
|
|
130
|
+
name: block.name,
|
|
131
|
+
effects
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function compileAudioSourceBlock(block) {
|
|
135
|
+
return {
|
|
136
|
+
keyword: block.keyword,
|
|
137
|
+
name: block.name || "unnamed",
|
|
138
|
+
traits: block.traits || [],
|
|
139
|
+
properties: block.properties || {}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function compileWeatherBlock(block) {
|
|
143
|
+
const layers = [];
|
|
144
|
+
for (const child of block.children || []) {
|
|
145
|
+
const c = child;
|
|
146
|
+
if (c.type === "DomainBlock") {
|
|
147
|
+
layers.push({
|
|
148
|
+
type: c.keyword,
|
|
149
|
+
properties: c.properties || {}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
keyword: block.keyword,
|
|
155
|
+
name: block.name,
|
|
156
|
+
traits: block.traits || [],
|
|
157
|
+
properties: block.properties || {},
|
|
158
|
+
layers
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function particlesToR3F(ps, tier) {
|
|
162
|
+
const scale = tier?.particleScale ?? 1;
|
|
163
|
+
const props = [];
|
|
164
|
+
if (ps.properties.rate)
|
|
165
|
+
props.push(`rate={${Math.round(ps.properties.rate * scale)}}`);
|
|
166
|
+
if (ps.properties.max_particles)
|
|
167
|
+
props.push(`maxParticles={${Math.round(ps.properties.max_particles * scale)}}`);
|
|
168
|
+
if (ps.properties.start_lifetime) {
|
|
169
|
+
const lt = ps.properties.start_lifetime;
|
|
170
|
+
props.push(Array.isArray(lt) ? `lifetime={[${lt.join(", ")}]}` : `lifetime={${lt}}`);
|
|
171
|
+
}
|
|
172
|
+
if (ps.properties.start_speed) {
|
|
173
|
+
const sp = ps.properties.start_speed;
|
|
174
|
+
props.push(Array.isArray(sp) ? `speed={[${sp.join(", ")}]}` : `speed={${sp}}`);
|
|
175
|
+
}
|
|
176
|
+
if (ps.properties.gravity_modifier !== void 0) {
|
|
177
|
+
props.push(`gravityModifier={${ps.properties.gravity_modifier}}`);
|
|
178
|
+
}
|
|
179
|
+
const isLooping = ps.traits.includes("looping");
|
|
180
|
+
if (isLooping) props.push("loop");
|
|
181
|
+
const modulesJSX = ps.modules.map((m) => {
|
|
182
|
+
const mProps = Object.entries(m.properties).map(([k, v]) => {
|
|
183
|
+
const camel = k.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
184
|
+
return typeof v === "string" ? `${camel}="${v}"` : `${camel}={${JSON.stringify(v)}}`;
|
|
185
|
+
}).join(" ");
|
|
186
|
+
return ` <${m.type} ${mProps} />`;
|
|
187
|
+
}).join("\n");
|
|
188
|
+
return [`<ParticleSystem name="${ps.name}" ${props.join(" ")}>`, modulesJSX, "</ParticleSystem>"].filter(Boolean).join("\n");
|
|
189
|
+
}
|
|
190
|
+
function postProcessingToR3F(pp) {
|
|
191
|
+
const effectsJSX = pp.effects.map((e) => {
|
|
192
|
+
const componentName = e.type.split("_").map((w) => w[0].toUpperCase() + w.slice(1)).join("");
|
|
193
|
+
const props = Object.entries(e.properties).map(([k, v]) => {
|
|
194
|
+
const camel = k.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
195
|
+
return typeof v === "string" ? `${camel}="${v}"` : `${camel}={${JSON.stringify(v)}}`;
|
|
196
|
+
}).join(" ");
|
|
197
|
+
return ` <${componentName} ${props} />`;
|
|
198
|
+
}).join("\n");
|
|
199
|
+
return ["<EffectComposer>", effectsJSX, "</EffectComposer>"].join("\n");
|
|
200
|
+
}
|
|
201
|
+
function audioSourceToR3F(audio) {
|
|
202
|
+
const spatialBlend = typeof audio.properties.spatial_blend === "number" ? audio.properties.spatial_blend : 0;
|
|
203
|
+
const isSpatial = audio.traits.includes("spatial") || spatialBlend > 0;
|
|
204
|
+
const tag = isSpatial ? "PositionalAudio" : "Audio";
|
|
205
|
+
const props = [];
|
|
206
|
+
if (audio.properties.clip) props.push(`url="${audio.properties.clip}"`);
|
|
207
|
+
if (audio.properties.volume !== void 0) props.push(`volume={${audio.properties.volume}}`);
|
|
208
|
+
if (audio.properties.loop !== void 0) props.push(`loop={${audio.properties.loop}}`);
|
|
209
|
+
if (isSpatial && audio.properties.max_distance) {
|
|
210
|
+
props.push(`distance={${audio.properties.max_distance}}`);
|
|
211
|
+
}
|
|
212
|
+
if (audio.properties.play_on_awake) props.push("autoplay");
|
|
213
|
+
return `<${tag} name="${audio.name}" ${props.join(" ")} />`;
|
|
214
|
+
}
|
|
215
|
+
function weatherToUSD(weather) {
|
|
216
|
+
const lines = [`def Scope "${weather.name || "Weather"}" {`];
|
|
217
|
+
for (const [key, value] of Object.entries(weather.properties)) {
|
|
218
|
+
lines.push(
|
|
219
|
+
` custom ${typeof value === "number" ? "float" : "string"} ${key} = ${JSON.stringify(value)}`
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
for (const layer of weather.layers) {
|
|
223
|
+
lines.push(` def Scope "${layer.type}" {`);
|
|
224
|
+
for (const [key, value] of Object.entries(layer.properties)) {
|
|
225
|
+
const usdType = typeof value === "number" ? "float" : typeof value === "boolean" ? "bool" : Array.isArray(value) ? "float3" : "string";
|
|
226
|
+
const usdVal = Array.isArray(value) ? `(${value.join(", ")})` : JSON.stringify(value);
|
|
227
|
+
lines.push(` custom ${usdType} ${key} = ${usdVal}`);
|
|
228
|
+
}
|
|
229
|
+
lines.push(" }");
|
|
230
|
+
}
|
|
231
|
+
lines.push("}");
|
|
232
|
+
return lines.join("\n");
|
|
233
|
+
}
|
|
234
|
+
function materialToR3F(mat, tier) {
|
|
235
|
+
const shaderLevel = tier?.shaderComplexity ?? "physical";
|
|
236
|
+
if (shaderLevel === "basic" && mat.type !== "unlit") {
|
|
237
|
+
const props2 = [
|
|
238
|
+
mat.baseColor ? `color="${mat.baseColor}"` : "",
|
|
239
|
+
mat.opacity !== void 0 ? `opacity={${mat.opacity}} transparent` : ""
|
|
240
|
+
].filter(Boolean).join(" ");
|
|
241
|
+
return `<meshBasicMaterial ${props2} />`;
|
|
242
|
+
}
|
|
243
|
+
if (mat.type === "unlit") {
|
|
244
|
+
const props2 = [
|
|
245
|
+
mat.emissiveColor ? `emissive="${mat.emissiveColor}"` : "",
|
|
246
|
+
mat.emissiveIntensity ? `emissiveIntensity={${mat.emissiveIntensity}}` : "",
|
|
247
|
+
mat.opacity !== void 0 ? `opacity={${mat.opacity}} transparent` : ""
|
|
248
|
+
].filter(Boolean).join(" ");
|
|
249
|
+
return `<meshBasicMaterial ${props2} />`;
|
|
250
|
+
}
|
|
251
|
+
const props = [
|
|
252
|
+
mat.baseColor ? `color="${mat.baseColor}"` : "",
|
|
253
|
+
mat.roughness !== void 0 ? `roughness={${mat.roughness}}` : "",
|
|
254
|
+
mat.metallic !== void 0 ? `metalness={${mat.metallic}}` : "",
|
|
255
|
+
mat.opacity !== void 0 ? `opacity={${mat.opacity}} transparent` : "",
|
|
256
|
+
mat.emissiveColor ? `emissive="${mat.emissiveColor}"` : "",
|
|
257
|
+
mat.emissiveIntensity ? `emissiveIntensity={${mat.emissiveIntensity}}` : ""
|
|
258
|
+
].filter(Boolean).join(" ");
|
|
259
|
+
const textures = Object.entries(mat.textureMaps).map(([type, path]) => {
|
|
260
|
+
const propName = type.replace(/_map$/, "Map").replace(/^albedo/, "");
|
|
261
|
+
return `${propName}={useTexture("${path}")}`;
|
|
262
|
+
}).join(" ");
|
|
263
|
+
if (isPhysicalMaterial(mat)) {
|
|
264
|
+
const physical = [
|
|
265
|
+
mat.ior !== void 0 ? `ior={${mat.ior}}` : "",
|
|
266
|
+
mat.clearcoat !== void 0 ? `clearcoat={${mat.clearcoat}}` : "",
|
|
267
|
+
mat.clearcoatRoughness !== void 0 ? `clearcoatRoughness={${mat.clearcoatRoughness}}` : "",
|
|
268
|
+
mat.transmission !== void 0 ? `transmission={${mat.transmission}}` : "",
|
|
269
|
+
mat.thickness !== void 0 ? `thickness={${mat.thickness}}` : "",
|
|
270
|
+
mat.sheen !== void 0 ? `sheen={${mat.sheen}}` : "",
|
|
271
|
+
mat.sheenColor ? `sheenColor="${mat.sheenColor}"` : "",
|
|
272
|
+
mat.sheenRoughness !== void 0 ? `sheenRoughness={${mat.sheenRoughness}}` : "",
|
|
273
|
+
mat.specularIntensity !== void 0 ? `specularIntensity={${mat.specularIntensity}}` : "",
|
|
274
|
+
mat.iridescence !== void 0 ? `iridescence={${mat.iridescence}}` : "",
|
|
275
|
+
mat.attenuationColor ? `attenuationColor="${mat.attenuationColor}"` : "",
|
|
276
|
+
mat.attenuationDistance !== void 0 ? `attenuationDistance={${mat.attenuationDistance}}` : ""
|
|
277
|
+
].filter(Boolean).join(" ");
|
|
278
|
+
return `<meshPhysicalMaterial ${props} ${physical} ${textures} />`;
|
|
279
|
+
}
|
|
280
|
+
return `<meshStandardMaterial ${props} ${textures} />`;
|
|
281
|
+
}
|
|
282
|
+
function materialToUSD(mat) {
|
|
283
|
+
const lines = [
|
|
284
|
+
`def Material "${mat.name}" {`,
|
|
285
|
+
` token outputs:surface.connect = <${mat.name}/PBRShader.outputs:surface>`,
|
|
286
|
+
` def Shader "PBRShader" {`,
|
|
287
|
+
` uniform token info:id = "UsdPreviewSurface"`
|
|
288
|
+
];
|
|
289
|
+
if (mat.baseColor)
|
|
290
|
+
lines.push(` color3f inputs:diffuseColor = (${hexToRGB(mat.baseColor)})`);
|
|
291
|
+
if (mat.roughness !== void 0) lines.push(` float inputs:roughness = ${mat.roughness}`);
|
|
292
|
+
if (mat.metallic !== void 0) lines.push(` float inputs:metallic = ${mat.metallic}`);
|
|
293
|
+
if (mat.opacity !== void 0) lines.push(` float inputs:opacity = ${mat.opacity}`);
|
|
294
|
+
if (mat.ior !== void 0) lines.push(` float inputs:ior = ${mat.ior}`);
|
|
295
|
+
if (mat.emissiveColor) {
|
|
296
|
+
const rgb = hexToRGB(mat.emissiveColor).split(", ").map(Number);
|
|
297
|
+
const intensity = mat.emissiveIntensity ?? 1;
|
|
298
|
+
const scaled = rgb.map((c) => Math.min(1, c * intensity));
|
|
299
|
+
lines.push(` color3f inputs:emissiveColor = (${scaled.join(", ")})`);
|
|
300
|
+
}
|
|
301
|
+
lines.push(` token outputs:surface`);
|
|
302
|
+
lines.push(` }`);
|
|
303
|
+
const texEntries = Object.entries(mat.textureMaps);
|
|
304
|
+
if (texEntries.length > 0) {
|
|
305
|
+
const TEX_MAP = {
|
|
306
|
+
albedo_map: { input: "diffuseColor", type: "rgb" },
|
|
307
|
+
normal_map: { input: "normal", type: "rgb" },
|
|
308
|
+
roughness_map: { input: "roughness", type: "r" },
|
|
309
|
+
metallic_map: { input: "metallic", type: "r" },
|
|
310
|
+
ao_map: { input: "occlusion", type: "r" },
|
|
311
|
+
emission_map: { input: "emissiveColor", type: "rgb" },
|
|
312
|
+
displacement_map: { input: "displacement", type: "r" }
|
|
313
|
+
};
|
|
314
|
+
lines.push(` def Shader "stReader" {`);
|
|
315
|
+
lines.push(` uniform token info:id = "UsdPrimvarReader_float2"`);
|
|
316
|
+
lines.push(` token inputs:varname = "st"`);
|
|
317
|
+
lines.push(` float2 outputs:result`);
|
|
318
|
+
lines.push(` }`);
|
|
319
|
+
for (const [channel, path] of texEntries) {
|
|
320
|
+
const mapping = TEX_MAP[channel];
|
|
321
|
+
if (!mapping) continue;
|
|
322
|
+
const readerName = `${mapping.input}Texture`;
|
|
323
|
+
lines.push(` def Shader "${readerName}" {`);
|
|
324
|
+
lines.push(` uniform token info:id = "UsdUVTexture"`);
|
|
325
|
+
lines.push(` asset inputs:file = @textures/${path}@`);
|
|
326
|
+
lines.push(` float2 inputs:st.connect = <${mat.name}/stReader.outputs:result>`);
|
|
327
|
+
if (mapping.type === "rgb") {
|
|
328
|
+
lines.push(` color3f outputs:rgb`);
|
|
329
|
+
} else {
|
|
330
|
+
lines.push(` float outputs:r`);
|
|
331
|
+
}
|
|
332
|
+
lines.push(` }`);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
lines.push(`}`);
|
|
336
|
+
return lines.join("\n");
|
|
337
|
+
}
|
|
338
|
+
function materialToGLTF(mat) {
|
|
339
|
+
const gltfMat = { name: mat.name };
|
|
340
|
+
if (mat.type === "pbr" || mat.type === "shader") {
|
|
341
|
+
gltfMat.pbrMetallicRoughness = {
|
|
342
|
+
baseColorFactor: mat.baseColor ? hexToRGBA(mat.baseColor, mat.opacity ?? 1) : [1, 1, 1, 1],
|
|
343
|
+
metallicFactor: mat.metallic ?? 0,
|
|
344
|
+
roughnessFactor: mat.roughness ?? 0.5
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
if (mat.emissiveColor) {
|
|
348
|
+
gltfMat.emissiveFactor = hexToRGB(mat.emissiveColor).split(", ").map(Number);
|
|
349
|
+
}
|
|
350
|
+
return gltfMat;
|
|
351
|
+
}
|
|
352
|
+
function jointKeywordToURDF(keyword) {
|
|
353
|
+
switch (keyword) {
|
|
354
|
+
case "hinge":
|
|
355
|
+
return "revolute";
|
|
356
|
+
case "slider":
|
|
357
|
+
case "prismatic":
|
|
358
|
+
return "prismatic";
|
|
359
|
+
case "ball_socket":
|
|
360
|
+
return "ball";
|
|
361
|
+
case "fixed_joint":
|
|
362
|
+
return "fixed";
|
|
363
|
+
case "d6_joint":
|
|
364
|
+
return "floating";
|
|
365
|
+
case "spring_joint":
|
|
366
|
+
return "revolute";
|
|
367
|
+
// closest URDF equivalent
|
|
368
|
+
default:
|
|
369
|
+
return "fixed";
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
function colliderToURDF(collider) {
|
|
373
|
+
const shape = collider.shape || "box";
|
|
374
|
+
const props = collider.properties;
|
|
375
|
+
const lines = [" <collision>"];
|
|
376
|
+
switch (shape) {
|
|
377
|
+
case "sphere":
|
|
378
|
+
lines.push(` <geometry><sphere radius="${props.radius || 0.5}"/></geometry>`);
|
|
379
|
+
break;
|
|
380
|
+
case "capsule":
|
|
381
|
+
lines.push(
|
|
382
|
+
` <geometry><cylinder radius="${props.radius || 0.5}" length="${props.height || 1}"/></geometry>`
|
|
383
|
+
);
|
|
384
|
+
break;
|
|
385
|
+
case "box":
|
|
386
|
+
default: {
|
|
387
|
+
const size = Array.isArray(props.size) ? props.size.join(" ") : "1 1 1";
|
|
388
|
+
lines.push(` <geometry><box size="${size}"/></geometry>`);
|
|
389
|
+
break;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
lines.push(" </collision>");
|
|
393
|
+
return lines.join("\n");
|
|
394
|
+
}
|
|
395
|
+
function rigidbodyToURDF(rb) {
|
|
396
|
+
const mass = rb.properties.mass ?? 1;
|
|
397
|
+
const inertiaValues = Array.isArray(rb.properties.inertia) ? rb.properties.inertia : void 0;
|
|
398
|
+
return [
|
|
399
|
+
" <inertial>",
|
|
400
|
+
` <mass value="${mass}"/>`,
|
|
401
|
+
inertiaValues ? ` <inertia ixx="${inertiaValues[0] || 0}" iyy="${inertiaValues[1] || 0}" izz="${inertiaValues[2] || 0}" ixy="0" ixz="0" iyz="0"/>` : ` <inertia ixx="0.01" iyy="0.01" izz="0.01" ixy="0" ixz="0" iyz="0"/>`,
|
|
402
|
+
" </inertial>"
|
|
403
|
+
].join("\n");
|
|
404
|
+
}
|
|
405
|
+
function physicsToURDF(physics) {
|
|
406
|
+
const parts = [];
|
|
407
|
+
if (physics.keyword === "articulation") {
|
|
408
|
+
const joints = (physics.joints || []).map((j) => {
|
|
409
|
+
const props = j.properties;
|
|
410
|
+
const limitsValues = Array.isArray(props.limits) ? props.limits : void 0;
|
|
411
|
+
return [
|
|
412
|
+
` <joint name="${j.name}" type="${jointKeywordToURDF(j.keyword)}">`,
|
|
413
|
+
props.axis ? ` <axis xyz="${Array.isArray(props.axis) ? props.axis.join(" ") : "0 0 1"}"/>` : "",
|
|
414
|
+
limitsValues ? ` <limit lower="${limitsValues[0]}" upper="${limitsValues[1]}"/>` : "",
|
|
415
|
+
props.damping ? ` <dynamics damping="${props.damping}"/>` : "",
|
|
416
|
+
` </joint>`
|
|
417
|
+
].filter(Boolean).join("\n");
|
|
418
|
+
});
|
|
419
|
+
parts.push(...joints);
|
|
420
|
+
}
|
|
421
|
+
if (physics.colliders) {
|
|
422
|
+
for (const collider of physics.colliders) {
|
|
423
|
+
parts.push(colliderToURDF(collider));
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
if (physics.rigidbody) {
|
|
427
|
+
parts.push(rigidbodyToURDF(physics.rigidbody));
|
|
428
|
+
}
|
|
429
|
+
if (physics.forceFields) {
|
|
430
|
+
for (const ff of physics.forceFields) {
|
|
431
|
+
parts.push(
|
|
432
|
+
` <!-- ${ff.keyword} "${ff.name || ""}" strength="${ff.properties.strength || 0}" -->`
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
if (parts.length > 0) return parts.join("\n");
|
|
437
|
+
return `<!-- ${physics.keyword} ${physics.name || ""} -->`;
|
|
438
|
+
}
|
|
439
|
+
function materialToUnity(mat, varPrefix) {
|
|
440
|
+
const lines = [];
|
|
441
|
+
lines.push(`// Material: ${mat.name}`);
|
|
442
|
+
lines.push(
|
|
443
|
+
`var ${varPrefix}Mat = new Material(Shader.Find("${mat.type === "unlit" ? "Unlit/Color" : "Standard"}"));`
|
|
444
|
+
);
|
|
445
|
+
if (mat.baseColor) lines.push(`${varPrefix}Mat.color = ${hexToUnityColor(mat.baseColor)};`);
|
|
446
|
+
if (mat.roughness !== void 0)
|
|
447
|
+
lines.push(`${varPrefix}Mat.SetFloat("_Smoothness", ${(1 - mat.roughness).toFixed(3)}f);`);
|
|
448
|
+
if (mat.metallic !== void 0)
|
|
449
|
+
lines.push(`${varPrefix}Mat.SetFloat("_Metallic", ${mat.metallic}f);`);
|
|
450
|
+
if (mat.opacity !== void 0 && mat.opacity < 1) {
|
|
451
|
+
lines.push(`${varPrefix}Mat.SetFloat("_Mode", 3); // Transparent`);
|
|
452
|
+
lines.push(
|
|
453
|
+
`${varPrefix}Mat.color = new Color(${varPrefix}Mat.color.r, ${varPrefix}Mat.color.g, ${varPrefix}Mat.color.b, ${mat.opacity}f);`
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
if (mat.emissiveColor) {
|
|
457
|
+
lines.push(`${varPrefix}Mat.EnableKeyword("_EMISSION");`);
|
|
458
|
+
lines.push(
|
|
459
|
+
`${varPrefix}Mat.SetColor("_EmissionColor", ${hexToUnityColor(mat.emissiveColor)}${mat.emissiveIntensity ? ` * ${mat.emissiveIntensity}f` : ""});`
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
for (const [mapType, path] of Object.entries(mat.textureMaps)) {
|
|
463
|
+
const shaderProp = mapType === "albedo_map" ? "_MainTex" : mapType === "normal_map" ? "_BumpMap" : mapType === "metallic_map" ? "_MetallicGlossMap" : mapType === "roughness_map" ? "_SpecGlossMap" : mapType === "emission_map" ? "_EmissionMap" : mapType === "occlusion_map" ? "_OcclusionMap" : `_${mapType.replace(/_map$/, "")}`;
|
|
464
|
+
lines.push(
|
|
465
|
+
`${varPrefix}Mat.SetTexture("${shaderProp}", Resources.Load<Texture2D>("${path}"));`
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
return lines.join("\n");
|
|
469
|
+
}
|
|
470
|
+
function physicsToUnity(physics, varPrefix) {
|
|
471
|
+
const lines = [];
|
|
472
|
+
lines.push(`// Physics: ${physics.keyword} "${physics.name || ""}"`);
|
|
473
|
+
if (physics.rigidbody) {
|
|
474
|
+
lines.push(`var ${varPrefix}RB = ${varPrefix}GO.AddComponent<Rigidbody>();`);
|
|
475
|
+
const rb = physics.rigidbody.properties;
|
|
476
|
+
if (rb.mass !== void 0) lines.push(`${varPrefix}RB.mass = ${rb.mass}f;`);
|
|
477
|
+
if (rb.drag !== void 0) lines.push(`${varPrefix}RB.drag = ${rb.drag}f;`);
|
|
478
|
+
if (rb.angular_damping !== void 0)
|
|
479
|
+
lines.push(`${varPrefix}RB.angularDrag = ${rb.angular_damping}f;`);
|
|
480
|
+
if (rb.use_gravity === false) lines.push(`${varPrefix}RB.useGravity = false;`);
|
|
481
|
+
}
|
|
482
|
+
if (physics.colliders) {
|
|
483
|
+
for (let i = 0; i < physics.colliders.length; i++) {
|
|
484
|
+
const c = physics.colliders[i];
|
|
485
|
+
const shape = c.shape || "box";
|
|
486
|
+
const colVar = `${varPrefix}Col${i}`;
|
|
487
|
+
if (shape === "sphere") {
|
|
488
|
+
lines.push(`var ${colVar} = ${varPrefix}GO.AddComponent<SphereCollider>();`);
|
|
489
|
+
if (c.properties.radius) lines.push(`${colVar}.radius = ${c.properties.radius}f;`);
|
|
490
|
+
} else if (shape === "capsule") {
|
|
491
|
+
lines.push(`var ${colVar} = ${varPrefix}GO.AddComponent<CapsuleCollider>();`);
|
|
492
|
+
if (c.properties.radius) lines.push(`${colVar}.radius = ${c.properties.radius}f;`);
|
|
493
|
+
if (c.properties.height) lines.push(`${colVar}.height = ${c.properties.height}f;`);
|
|
494
|
+
} else {
|
|
495
|
+
lines.push(`var ${colVar} = ${varPrefix}GO.AddComponent<BoxCollider>();`);
|
|
496
|
+
if (c.properties.size && Array.isArray(c.properties.size)) {
|
|
497
|
+
lines.push(`${colVar}.size = new Vector3(${c.properties.size.join("f, ")}f);`);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
if (c.type === "trigger") lines.push(`${colVar}.isTrigger = true;`);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
if (physics.forceFields) {
|
|
504
|
+
for (const ff of physics.forceFields) {
|
|
505
|
+
if (ff.keyword === "wind_zone") {
|
|
506
|
+
lines.push(`var ${varPrefix}Wind = ${varPrefix}GO.AddComponent<WindZone>();`);
|
|
507
|
+
if (ff.properties.strength)
|
|
508
|
+
lines.push(`${varPrefix}Wind.windMain = ${ff.properties.strength}f;`);
|
|
509
|
+
} else {
|
|
510
|
+
lines.push(`// ${ff.keyword} "${ff.name || ""}": ${JSON.stringify(ff.properties)}`);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
if (physics.joints) {
|
|
515
|
+
for (const j of physics.joints) {
|
|
516
|
+
lines.push(`// Joint: ${j.keyword} "${j.name || ""}" \u2014 use ConfigurableJoint or HingeJoint`);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return lines.join("\n");
|
|
520
|
+
}
|
|
521
|
+
function particlesToUnity(ps, varPrefix) {
|
|
522
|
+
const lines = [];
|
|
523
|
+
lines.push(`// Particles: ${ps.name}`);
|
|
524
|
+
lines.push(`var ${varPrefix}PS = ${varPrefix}GO.AddComponent<ParticleSystem>();`);
|
|
525
|
+
lines.push(`var ${varPrefix}Main = ${varPrefix}PS.main;`);
|
|
526
|
+
if (ps.properties.max_particles)
|
|
527
|
+
lines.push(`${varPrefix}Main.maxParticles = ${ps.properties.max_particles};`);
|
|
528
|
+
if (ps.properties.start_lifetime) {
|
|
529
|
+
const lt = ps.properties.start_lifetime;
|
|
530
|
+
lines.push(`${varPrefix}Main.startLifetime = ${Array.isArray(lt) ? lt[0] : lt}f;`);
|
|
531
|
+
}
|
|
532
|
+
if (ps.properties.start_speed) {
|
|
533
|
+
const sp = ps.properties.start_speed;
|
|
534
|
+
lines.push(`${varPrefix}Main.startSpeed = ${Array.isArray(sp) ? sp[0] : sp}f;`);
|
|
535
|
+
}
|
|
536
|
+
if (ps.properties.gravity_modifier !== void 0) {
|
|
537
|
+
lines.push(`${varPrefix}Main.gravityModifier = ${ps.properties.gravity_modifier}f;`);
|
|
538
|
+
}
|
|
539
|
+
if (ps.traits.includes("looping")) lines.push(`${varPrefix}Main.loop = true;`);
|
|
540
|
+
for (const m of ps.modules) {
|
|
541
|
+
lines.push(`// Module: ${m.type} \u2014 ${JSON.stringify(m.properties)}`);
|
|
542
|
+
}
|
|
543
|
+
return lines.join("\n");
|
|
544
|
+
}
|
|
545
|
+
function postProcessingToUnity(pp) {
|
|
546
|
+
const lines = [];
|
|
547
|
+
lines.push("// Post-Processing (URP Volume Profile)");
|
|
548
|
+
for (const e of pp.effects) {
|
|
549
|
+
const className = e.type.split("_").map((w) => w[0].toUpperCase() + w.slice(1)).join("");
|
|
550
|
+
lines.push(`// Effect: ${className}`);
|
|
551
|
+
for (const [k, v] of Object.entries(e.properties)) {
|
|
552
|
+
lines.push(`// ${k} = ${JSON.stringify(v)}`);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
return lines.join("\n");
|
|
556
|
+
}
|
|
557
|
+
function audioSourceToUnity(audio, varPrefix) {
|
|
558
|
+
const lines = [];
|
|
559
|
+
lines.push(`// Audio: ${audio.name} (${audio.keyword})`);
|
|
560
|
+
if (audio.keyword === "reverb_zone") {
|
|
561
|
+
lines.push(`var ${varPrefix}Reverb = ${varPrefix}GO.AddComponent<AudioReverbZone>();`);
|
|
562
|
+
if (audio.properties.min_distance)
|
|
563
|
+
lines.push(`${varPrefix}Reverb.minDistance = ${audio.properties.min_distance}f;`);
|
|
564
|
+
if (audio.properties.max_distance)
|
|
565
|
+
lines.push(`${varPrefix}Reverb.maxDistance = ${audio.properties.max_distance}f;`);
|
|
566
|
+
} else {
|
|
567
|
+
lines.push(`var ${varPrefix}AS = ${varPrefix}GO.AddComponent<AudioSource>();`);
|
|
568
|
+
if (audio.properties.clip)
|
|
569
|
+
lines.push(
|
|
570
|
+
`${varPrefix}AS.clip = Resources.Load<AudioClip>("Audio/${audio.properties.clip}");`
|
|
571
|
+
);
|
|
572
|
+
if (audio.properties.volume !== void 0)
|
|
573
|
+
lines.push(`${varPrefix}AS.volume = ${audio.properties.volume}f;`);
|
|
574
|
+
if (audio.properties.loop !== void 0)
|
|
575
|
+
lines.push(`${varPrefix}AS.loop = ${audio.properties.loop};`);
|
|
576
|
+
if (audio.properties.spatial_blend !== void 0)
|
|
577
|
+
lines.push(`${varPrefix}AS.spatialBlend = ${audio.properties.spatial_blend}f;`);
|
|
578
|
+
if (audio.properties.max_distance)
|
|
579
|
+
lines.push(`${varPrefix}AS.maxDistance = ${audio.properties.max_distance}f;`);
|
|
580
|
+
if (audio.traits.includes("spatial") || audio.traits.includes("hrtf")) {
|
|
581
|
+
lines.push(`${varPrefix}AS.spatialBlend = 1.0f;`);
|
|
582
|
+
}
|
|
583
|
+
if (audio.properties.play_on_awake) lines.push(`${varPrefix}AS.playOnAwake = true;`);
|
|
584
|
+
}
|
|
585
|
+
return lines.join("\n");
|
|
586
|
+
}
|
|
587
|
+
function weatherToUnity(weather) {
|
|
588
|
+
const lines = [];
|
|
589
|
+
lines.push(`// Weather: ${weather.keyword} "${weather.name || ""}"`);
|
|
590
|
+
for (const layer of weather.layers) {
|
|
591
|
+
lines.push(`// Layer: ${layer.type} \u2014 ${JSON.stringify(layer.properties)}`);
|
|
592
|
+
}
|
|
593
|
+
if (weather.properties.intensity !== void 0) {
|
|
594
|
+
lines.push(`// Intensity: ${weather.properties.intensity}`);
|
|
595
|
+
}
|
|
596
|
+
return lines.join("\n");
|
|
597
|
+
}
|
|
598
|
+
function materialToUnreal(mat, varPrefix) {
|
|
599
|
+
const lines = [];
|
|
600
|
+
lines.push(`// Material: ${mat.name}`);
|
|
601
|
+
lines.push(`UMaterialInstanceDynamic* ${varPrefix}Mat = UMaterialInstanceDynamic::Create(`);
|
|
602
|
+
lines.push(
|
|
603
|
+
` LoadObject<UMaterial>(nullptr, TEXT("/Game/Materials/M_${mat.type === "unlit" ? "Unlit" : "PBR"}")), this);`
|
|
604
|
+
);
|
|
605
|
+
if (mat.baseColor) {
|
|
606
|
+
const [r, g, b] = hexToRGBTuple(mat.baseColor);
|
|
607
|
+
lines.push(
|
|
608
|
+
`${varPrefix}Mat->SetVectorParameterValue(TEXT("BaseColor"), FLinearColor(${r}f, ${g}f, ${b}f));`
|
|
609
|
+
);
|
|
610
|
+
}
|
|
611
|
+
if (mat.roughness !== void 0)
|
|
612
|
+
lines.push(`${varPrefix}Mat->SetScalarParameterValue(TEXT("Roughness"), ${mat.roughness}f);`);
|
|
613
|
+
if (mat.metallic !== void 0)
|
|
614
|
+
lines.push(`${varPrefix}Mat->SetScalarParameterValue(TEXT("Metallic"), ${mat.metallic}f);`);
|
|
615
|
+
if (mat.opacity !== void 0)
|
|
616
|
+
lines.push(`${varPrefix}Mat->SetScalarParameterValue(TEXT("Opacity"), ${mat.opacity}f);`);
|
|
617
|
+
if (mat.emissiveColor) {
|
|
618
|
+
const [r, g, b] = hexToRGBTuple(mat.emissiveColor);
|
|
619
|
+
const intensity = mat.emissiveIntensity ?? 1;
|
|
620
|
+
lines.push(
|
|
621
|
+
`${varPrefix}Mat->SetVectorParameterValue(TEXT("EmissiveColor"), FLinearColor(${r * intensity}f, ${g * intensity}f, ${b * intensity}f));`
|
|
622
|
+
);
|
|
623
|
+
}
|
|
624
|
+
for (const [mapType, path] of Object.entries(mat.textureMaps)) {
|
|
625
|
+
lines.push(
|
|
626
|
+
`${varPrefix}Mat->SetTextureParameterValue(TEXT("${mapType}"), LoadObject<UTexture2D>(nullptr, TEXT("/Game/Textures/${path}")));`
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
return lines.join("\n");
|
|
630
|
+
}
|
|
631
|
+
function physicsToUnreal(physics, varPrefix) {
|
|
632
|
+
const lines = [];
|
|
633
|
+
lines.push(`// Physics: ${physics.keyword} "${physics.name || ""}"`);
|
|
634
|
+
if (physics.rigidbody) {
|
|
635
|
+
const rb = physics.rigidbody.properties;
|
|
636
|
+
lines.push(`${varPrefix}Mesh->SetSimulatePhysics(true);`);
|
|
637
|
+
if (rb.mass !== void 0)
|
|
638
|
+
lines.push(`${varPrefix}Mesh->SetMassOverrideInKg(NAME_None, ${rb.mass}f);`);
|
|
639
|
+
if (rb.drag !== void 0) lines.push(`${varPrefix}Mesh->SetLinearDamping(${rb.drag}f);`);
|
|
640
|
+
if (rb.angular_damping !== void 0)
|
|
641
|
+
lines.push(`${varPrefix}Mesh->SetAngularDamping(${rb.angular_damping}f);`);
|
|
642
|
+
if (rb.use_gravity === false) lines.push(`${varPrefix}Mesh->SetEnableGravity(false);`);
|
|
643
|
+
}
|
|
644
|
+
if (physics.colliders) {
|
|
645
|
+
for (const c of physics.colliders) {
|
|
646
|
+
const shape = c.shape || "box";
|
|
647
|
+
if (shape === "sphere") {
|
|
648
|
+
lines.push(
|
|
649
|
+
`auto* ${varPrefix}Sphere = CreateDefaultSubobject<USphereComponent>(TEXT("${varPrefix}Sphere"));`
|
|
650
|
+
);
|
|
651
|
+
if (c.properties.radius)
|
|
652
|
+
lines.push(`${varPrefix}Sphere->SetSphereRadius(${c.properties.radius}f);`);
|
|
653
|
+
} else if (shape === "capsule") {
|
|
654
|
+
lines.push(
|
|
655
|
+
`auto* ${varPrefix}Capsule = CreateDefaultSubobject<UCapsuleComponent>(TEXT("${varPrefix}Capsule"));`
|
|
656
|
+
);
|
|
657
|
+
} else {
|
|
658
|
+
lines.push(
|
|
659
|
+
`auto* ${varPrefix}Box = CreateDefaultSubobject<UBoxComponent>(TEXT("${varPrefix}Box"));`
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
if (physics.forceFields) {
|
|
665
|
+
for (const ff of physics.forceFields) {
|
|
666
|
+
lines.push(
|
|
667
|
+
`// Force field: ${ff.keyword} "${ff.name || ""}" \u2014 ${JSON.stringify(ff.properties)}`
|
|
668
|
+
);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
if (physics.joints) {
|
|
672
|
+
for (const j of physics.joints) {
|
|
673
|
+
lines.push(
|
|
674
|
+
`auto* ${varPrefix}Constraint = CreateDefaultSubobject<UPhysicsConstraintComponent>(TEXT("${j.name || varPrefix + "Joint"}"));`
|
|
675
|
+
);
|
|
676
|
+
lines.push(`// Joint type: ${j.keyword} \u2014 configure constraint limits`);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
return lines.join("\n");
|
|
680
|
+
}
|
|
681
|
+
function particlesToUnreal(ps, varPrefix) {
|
|
682
|
+
const lines = [];
|
|
683
|
+
lines.push(`// Niagara Particles: ${ps.name}`);
|
|
684
|
+
lines.push(
|
|
685
|
+
`auto* ${varPrefix}Niagara = CreateDefaultSubobject<UNiagaraComponent>(TEXT("${ps.name}"));`
|
|
686
|
+
);
|
|
687
|
+
lines.push(`${varPrefix}Niagara->SetupAttachment(RootComponent);`);
|
|
688
|
+
if (ps.properties.rate)
|
|
689
|
+
lines.push(`${varPrefix}Niagara->SetVariableFloat(TEXT("SpawnRate"), ${ps.properties.rate}f);`);
|
|
690
|
+
if (ps.properties.start_lifetime)
|
|
691
|
+
lines.push(
|
|
692
|
+
`${varPrefix}Niagara->SetVariableFloat(TEXT("Lifetime"), ${Array.isArray(ps.properties.start_lifetime) ? ps.properties.start_lifetime[0] : ps.properties.start_lifetime}f);`
|
|
693
|
+
);
|
|
694
|
+
if (ps.traits.includes("looping"))
|
|
695
|
+
lines.push(`${varPrefix}Niagara->SetVariableBool(TEXT("Looping"), true);`);
|
|
696
|
+
for (const m of ps.modules) {
|
|
697
|
+
lines.push(`// Module: ${m.type} \u2014 ${JSON.stringify(m.properties)}`);
|
|
698
|
+
}
|
|
699
|
+
return lines.join("\n");
|
|
700
|
+
}
|
|
701
|
+
function postProcessingToUnreal(pp, varPrefix) {
|
|
702
|
+
const lines = [];
|
|
703
|
+
lines.push(`// Post-Processing: ${pp.keyword}`);
|
|
704
|
+
lines.push(
|
|
705
|
+
`auto* ${varPrefix}PP = CreateDefaultSubobject<UPostProcessComponent>(TEXT("PostProcess"));`
|
|
706
|
+
);
|
|
707
|
+
lines.push(`${varPrefix}PP->SetupAttachment(RootComponent);`);
|
|
708
|
+
for (const e of pp.effects) {
|
|
709
|
+
if (e.type === "bloom") {
|
|
710
|
+
lines.push(`${varPrefix}PP->Settings.bOverride_BloomIntensity = true;`);
|
|
711
|
+
if (e.properties.intensity)
|
|
712
|
+
lines.push(`${varPrefix}PP->Settings.BloomIntensity = ${e.properties.intensity}f;`);
|
|
713
|
+
if (e.properties.threshold)
|
|
714
|
+
lines.push(`${varPrefix}PP->Settings.BloomThreshold = ${e.properties.threshold}f;`);
|
|
715
|
+
} else if (e.type === "depth_of_field") {
|
|
716
|
+
lines.push(`${varPrefix}PP->Settings.bOverride_DepthOfFieldFocalDistance = true;`);
|
|
717
|
+
if (e.properties.focal_distance)
|
|
718
|
+
lines.push(
|
|
719
|
+
`${varPrefix}PP->Settings.DepthOfFieldFocalDistance = ${e.properties.focal_distance}f;`
|
|
720
|
+
);
|
|
721
|
+
} else {
|
|
722
|
+
lines.push(`// Effect: ${e.type} \u2014 ${JSON.stringify(e.properties)}`);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
return lines.join("\n");
|
|
726
|
+
}
|
|
727
|
+
function audioSourceToUnreal(audio, varPrefix) {
|
|
728
|
+
const lines = [];
|
|
729
|
+
lines.push(`// Audio: ${audio.name} (${audio.keyword})`);
|
|
730
|
+
lines.push(
|
|
731
|
+
`auto* ${varPrefix}Audio = CreateDefaultSubobject<UAudioComponent>(TEXT("${audio.name}"));`
|
|
732
|
+
);
|
|
733
|
+
lines.push(`${varPrefix}Audio->SetupAttachment(RootComponent);`);
|
|
734
|
+
if (audio.properties.clip)
|
|
735
|
+
lines.push(
|
|
736
|
+
`${varPrefix}Audio->SetSound(LoadObject<USoundWave>(nullptr, TEXT("/Game/Audio/${audio.properties.clip}")));`
|
|
737
|
+
);
|
|
738
|
+
if (audio.properties.volume !== void 0)
|
|
739
|
+
lines.push(`${varPrefix}Audio->SetVolumeMultiplier(${audio.properties.volume}f);`);
|
|
740
|
+
if (audio.properties.loop !== void 0)
|
|
741
|
+
lines.push(`${varPrefix}Audio->bIsLooping = ${audio.properties.loop ? "true" : "false"};`);
|
|
742
|
+
if (audio.traits.includes("spatial") || typeof audio.properties.spatial_blend === "number" && audio.properties.spatial_blend > 0) {
|
|
743
|
+
lines.push(`${varPrefix}Audio->bOverrideAttenuation = true;`);
|
|
744
|
+
if (audio.properties.max_distance)
|
|
745
|
+
lines.push(
|
|
746
|
+
`${varPrefix}Audio->AttenuationOverrides.FalloffDistance = ${audio.properties.max_distance}f;`
|
|
747
|
+
);
|
|
748
|
+
}
|
|
749
|
+
if (audio.properties.play_on_awake) lines.push(`${varPrefix}Audio->bAutoActivate = true;`);
|
|
750
|
+
return lines.join("\n");
|
|
751
|
+
}
|
|
752
|
+
function weatherToUnreal(weather) {
|
|
753
|
+
const lines = [];
|
|
754
|
+
lines.push(`// Weather: ${weather.keyword} "${weather.name || ""}"`);
|
|
755
|
+
lines.push("// Use UltraDynamicSky or custom weather system");
|
|
756
|
+
for (const layer of weather.layers) {
|
|
757
|
+
lines.push(`// Layer: ${layer.type} \u2014 ${JSON.stringify(layer.properties)}`);
|
|
758
|
+
}
|
|
759
|
+
return lines.join("\n");
|
|
760
|
+
}
|
|
761
|
+
function materialToGodot(mat, varPrefix) {
|
|
762
|
+
const lines = [];
|
|
763
|
+
lines.push(`# Material: ${mat.name}`);
|
|
764
|
+
if (mat.type === "unlit") {
|
|
765
|
+
lines.push(`var ${varPrefix}_mat = StandardMaterial3D.new()`);
|
|
766
|
+
lines.push(`${varPrefix}_mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED`);
|
|
767
|
+
} else {
|
|
768
|
+
lines.push(`var ${varPrefix}_mat = StandardMaterial3D.new()`);
|
|
769
|
+
}
|
|
770
|
+
if (mat.baseColor) lines.push(`${varPrefix}_mat.albedo_color = Color.html("${mat.baseColor}")`);
|
|
771
|
+
if (mat.roughness !== void 0) lines.push(`${varPrefix}_mat.roughness = ${mat.roughness}`);
|
|
772
|
+
if (mat.metallic !== void 0) lines.push(`${varPrefix}_mat.metallic = ${mat.metallic}`);
|
|
773
|
+
if (mat.opacity !== void 0 && mat.opacity < 1) {
|
|
774
|
+
lines.push(`${varPrefix}_mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA`);
|
|
775
|
+
lines.push(`${varPrefix}_mat.albedo_color.a = ${mat.opacity}`);
|
|
776
|
+
}
|
|
777
|
+
if (mat.emissiveColor) {
|
|
778
|
+
lines.push(`${varPrefix}_mat.emission_enabled = true`);
|
|
779
|
+
lines.push(`${varPrefix}_mat.emission = Color.html("${mat.emissiveColor}")`);
|
|
780
|
+
if (mat.emissiveIntensity)
|
|
781
|
+
lines.push(`${varPrefix}_mat.emission_energy_multiplier = ${mat.emissiveIntensity}`);
|
|
782
|
+
}
|
|
783
|
+
for (const [mapType, path] of Object.entries(mat.textureMaps)) {
|
|
784
|
+
const prop = mapType === "albedo_map" ? "albedo_texture" : mapType === "normal_map" ? "normal_texture" : mapType === "metallic_map" ? "metallic_texture" : mapType === "roughness_map" ? "roughness_texture" : mapType === "emission_map" ? "emission_texture" : `${mapType.replace(/_map$/, "_texture")}`;
|
|
785
|
+
lines.push(`${varPrefix}_mat.${prop} = load("res://${path}")`);
|
|
786
|
+
}
|
|
787
|
+
return lines.join("\n");
|
|
788
|
+
}
|
|
789
|
+
function physicsToGodot(physics, varPrefix) {
|
|
790
|
+
const lines = [];
|
|
791
|
+
lines.push(`# Physics: ${physics.keyword} "${physics.name || ""}"`);
|
|
792
|
+
if (physics.rigidbody) {
|
|
793
|
+
const rb = physics.rigidbody.properties;
|
|
794
|
+
lines.push(`var ${varPrefix}_rb = RigidBody3D.new()`);
|
|
795
|
+
if (rb.mass !== void 0) lines.push(`${varPrefix}_rb.mass = ${rb.mass}`);
|
|
796
|
+
if (rb.drag !== void 0) lines.push(`${varPrefix}_rb.linear_damp = ${rb.drag}`);
|
|
797
|
+
if (rb.angular_damping !== void 0)
|
|
798
|
+
lines.push(`${varPrefix}_rb.angular_damp = ${rb.angular_damping}`);
|
|
799
|
+
if (rb.use_gravity === false) lines.push(`${varPrefix}_rb.gravity_scale = 0.0`);
|
|
800
|
+
}
|
|
801
|
+
if (physics.colliders) {
|
|
802
|
+
for (let i = 0; i < physics.colliders.length; i++) {
|
|
803
|
+
const c = physics.colliders[i];
|
|
804
|
+
const shape = c.shape || "box";
|
|
805
|
+
if (shape === "sphere") {
|
|
806
|
+
lines.push(`var ${varPrefix}_col${i} = CollisionShape3D.new()`);
|
|
807
|
+
lines.push(`${varPrefix}_col${i}.shape = SphereShape3D.new()`);
|
|
808
|
+
if (c.properties.radius)
|
|
809
|
+
lines.push(`${varPrefix}_col${i}.shape.radius = ${c.properties.radius}`);
|
|
810
|
+
} else if (shape === "capsule") {
|
|
811
|
+
lines.push(`var ${varPrefix}_col${i} = CollisionShape3D.new()`);
|
|
812
|
+
lines.push(`${varPrefix}_col${i}.shape = CapsuleShape3D.new()`);
|
|
813
|
+
} else {
|
|
814
|
+
lines.push(`var ${varPrefix}_col${i} = CollisionShape3D.new()`);
|
|
815
|
+
lines.push(`${varPrefix}_col${i}.shape = BoxShape3D.new()`);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
if (physics.forceFields) {
|
|
820
|
+
for (const ff of physics.forceFields) {
|
|
821
|
+
lines.push(
|
|
822
|
+
`# Force field: ${ff.keyword} "${ff.name || ""}" \u2014 ${JSON.stringify(ff.properties)}`
|
|
823
|
+
);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
if (physics.joints) {
|
|
827
|
+
for (const j of physics.joints) {
|
|
828
|
+
const jointType = j.keyword === "hinge" ? "HingeJoint3D" : j.keyword === "slider" ? "SliderJoint3D" : "Generic6DOFJoint3D";
|
|
829
|
+
lines.push(`var ${varPrefix}_joint = ${jointType}.new()`);
|
|
830
|
+
lines.push(`# Joint: ${j.keyword} "${j.name || ""}" \u2014 ${JSON.stringify(j.properties)}`);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
return lines.join("\n");
|
|
834
|
+
}
|
|
835
|
+
function particlesToGodot(ps, varPrefix) {
|
|
836
|
+
const lines = [];
|
|
837
|
+
lines.push(`# Particles: ${ps.name}`);
|
|
838
|
+
lines.push(`var ${varPrefix}_particles = GPUParticles3D.new()`);
|
|
839
|
+
lines.push(`${varPrefix}_particles.name = "${ps.name}"`);
|
|
840
|
+
if (ps.properties.max_particles)
|
|
841
|
+
lines.push(`${varPrefix}_particles.amount = ${ps.properties.max_particles}`);
|
|
842
|
+
if (ps.properties.start_lifetime) {
|
|
843
|
+
const lt = Array.isArray(ps.properties.start_lifetime) ? ps.properties.start_lifetime[0] : ps.properties.start_lifetime;
|
|
844
|
+
lines.push(`${varPrefix}_particles.lifetime = ${lt}`);
|
|
845
|
+
}
|
|
846
|
+
if (ps.traits.includes("looping")) lines.push(`${varPrefix}_particles.one_shot = false`);
|
|
847
|
+
else lines.push(`${varPrefix}_particles.one_shot = true`);
|
|
848
|
+
for (const m of ps.modules) {
|
|
849
|
+
lines.push(`# Module: ${m.type} \u2014 ${JSON.stringify(m.properties)}`);
|
|
850
|
+
}
|
|
851
|
+
return lines.join("\n");
|
|
852
|
+
}
|
|
853
|
+
function postProcessingToGodot(pp) {
|
|
854
|
+
const lines = [];
|
|
855
|
+
lines.push(`# Post-Processing: ${pp.keyword} (use WorldEnvironment)`);
|
|
856
|
+
lines.push("var env = WorldEnvironment.new()");
|
|
857
|
+
lines.push("var environment = Environment.new()");
|
|
858
|
+
for (const e of pp.effects) {
|
|
859
|
+
if (e.type === "bloom" || e.type === "glow") {
|
|
860
|
+
lines.push("environment.glow_enabled = true");
|
|
861
|
+
if (e.properties.intensity)
|
|
862
|
+
lines.push(`environment.glow_intensity = ${e.properties.intensity}`);
|
|
863
|
+
if (e.properties.threshold) lines.push(`environment.glow_bloom = ${e.properties.threshold}`);
|
|
864
|
+
} else if (e.type === "fog") {
|
|
865
|
+
lines.push("environment.fog_enabled = true");
|
|
866
|
+
if (e.properties.density) lines.push(`environment.fog_density = ${e.properties.density}`);
|
|
867
|
+
} else {
|
|
868
|
+
lines.push(`# Effect: ${e.type} \u2014 ${JSON.stringify(e.properties)}`);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
lines.push("env.environment = environment");
|
|
872
|
+
return lines.join("\n");
|
|
873
|
+
}
|
|
874
|
+
function audioSourceToGodot(audio, varPrefix) {
|
|
875
|
+
const lines = [];
|
|
876
|
+
lines.push(`# Audio: ${audio.name} (${audio.keyword})`);
|
|
877
|
+
const isSpatial = audio.traits.includes("spatial") || typeof audio.properties.spatial_blend === "number" && audio.properties.spatial_blend > 0;
|
|
878
|
+
const nodeType = isSpatial ? "AudioStreamPlayer3D" : "AudioStreamPlayer";
|
|
879
|
+
lines.push(`var ${varPrefix}_audio = ${nodeType}.new()`);
|
|
880
|
+
lines.push(`${varPrefix}_audio.name = "${audio.name}"`);
|
|
881
|
+
if (audio.properties.clip)
|
|
882
|
+
lines.push(`${varPrefix}_audio.stream = load("res://${audio.properties.clip}")`);
|
|
883
|
+
if (audio.properties.volume !== void 0)
|
|
884
|
+
lines.push(`${varPrefix}_audio.volume_db = linear_to_db(${audio.properties.volume})`);
|
|
885
|
+
if (isSpatial && audio.properties.max_distance) {
|
|
886
|
+
lines.push(`${varPrefix}_audio.max_distance = ${audio.properties.max_distance}`);
|
|
887
|
+
}
|
|
888
|
+
if (audio.properties.play_on_awake) lines.push(`${varPrefix}_audio.autoplay = true`);
|
|
889
|
+
return lines.join("\n");
|
|
890
|
+
}
|
|
891
|
+
function weatherToGodot(weather) {
|
|
892
|
+
const lines = [];
|
|
893
|
+
lines.push(`# Weather: ${weather.keyword} "${weather.name || ""}"`);
|
|
894
|
+
for (const layer of weather.layers) {
|
|
895
|
+
lines.push(`# Layer: ${layer.type} \u2014 ${JSON.stringify(layer.properties)}`);
|
|
896
|
+
}
|
|
897
|
+
return lines.join("\n");
|
|
898
|
+
}
|
|
899
|
+
function materialToVisionOS(mat, varPrefix) {
|
|
900
|
+
const lines = [];
|
|
901
|
+
lines.push(`// Material: ${mat.name}`);
|
|
902
|
+
if (mat.type === "unlit") {
|
|
903
|
+
lines.push(`var ${varPrefix}Mat = UnlitMaterial()`);
|
|
904
|
+
if (mat.baseColor)
|
|
905
|
+
lines.push(`${varPrefix}Mat.color = .init(tint: ${hexToSwiftColor(mat.baseColor)})`);
|
|
906
|
+
} else {
|
|
907
|
+
lines.push(`var ${varPrefix}Mat = PhysicallyBasedMaterial()`);
|
|
908
|
+
if (mat.baseColor)
|
|
909
|
+
lines.push(`${varPrefix}Mat.baseColor = .init(tint: ${hexToSwiftColor(mat.baseColor)})`);
|
|
910
|
+
if (mat.roughness !== void 0)
|
|
911
|
+
lines.push(`${varPrefix}Mat.roughness = .init(floatLiteral: ${mat.roughness})`);
|
|
912
|
+
if (mat.metallic !== void 0)
|
|
913
|
+
lines.push(`${varPrefix}Mat.metallic = .init(floatLiteral: ${mat.metallic})`);
|
|
914
|
+
if (mat.opacity !== void 0 && mat.opacity < 1)
|
|
915
|
+
lines.push(
|
|
916
|
+
`${varPrefix}Mat.blending = .transparent(opacity: .init(floatLiteral: ${mat.opacity}))`
|
|
917
|
+
);
|
|
918
|
+
if (mat.emissiveColor) {
|
|
919
|
+
lines.push(
|
|
920
|
+
`${varPrefix}Mat.emissiveColor = .init(color: ${hexToSwiftColor(mat.emissiveColor)})`
|
|
921
|
+
);
|
|
922
|
+
if (mat.emissiveIntensity)
|
|
923
|
+
lines.push(`${varPrefix}Mat.emissiveIntensity = ${mat.emissiveIntensity}`);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
for (const [mapType, path] of Object.entries(mat.textureMaps)) {
|
|
927
|
+
const prop = mapType === "albedo_map" ? "baseColor" : mapType === "normal_map" ? "normal" : mapType === "metallic_map" ? "metallic" : mapType === "roughness_map" ? "roughness" : mapType;
|
|
928
|
+
lines.push(`${varPrefix}Mat.${prop} = .init(texture: .init(try! .load(named: "${path}")))`);
|
|
929
|
+
}
|
|
930
|
+
return lines.join("\n");
|
|
931
|
+
}
|
|
932
|
+
function physicsToVisionOS(physics, varPrefix) {
|
|
933
|
+
const lines = [];
|
|
934
|
+
lines.push(`// Physics: ${physics.keyword} "${physics.name || ""}"`);
|
|
935
|
+
if (physics.colliders) {
|
|
936
|
+
for (const c of physics.colliders) {
|
|
937
|
+
const shape = c.shape || "box";
|
|
938
|
+
if (shape === "sphere") {
|
|
939
|
+
lines.push(
|
|
940
|
+
`${varPrefix}Entity.components.set(CollisionComponent(shapes: [.generateSphere(radius: ${c.properties.radius || 0.5})]))`
|
|
941
|
+
);
|
|
942
|
+
} else if (shape === "capsule") {
|
|
943
|
+
lines.push(
|
|
944
|
+
`${varPrefix}Entity.components.set(CollisionComponent(shapes: [.generateCapsule(height: ${c.properties.height || 1}, radius: ${c.properties.radius || 0.25})]))`
|
|
945
|
+
);
|
|
946
|
+
} else {
|
|
947
|
+
const size = c.properties.size && Array.isArray(c.properties.size) ? c.properties.size : [1, 1, 1];
|
|
948
|
+
lines.push(
|
|
949
|
+
`${varPrefix}Entity.components.set(CollisionComponent(shapes: [.generateBox(size: [${size.join(", ")}])]))`
|
|
950
|
+
);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
if (physics.rigidbody) {
|
|
955
|
+
const rb = physics.rigidbody.properties;
|
|
956
|
+
lines.push(
|
|
957
|
+
`var ${varPrefix}Physics = PhysicsBodyComponent(massProperties: .init(mass: ${rb.mass ?? 1}), mode: .dynamic)`
|
|
958
|
+
);
|
|
959
|
+
if (rb.drag !== void 0) lines.push(`${varPrefix}Physics.linearDamping = ${rb.drag}`);
|
|
960
|
+
if (rb.angular_damping !== void 0)
|
|
961
|
+
lines.push(`${varPrefix}Physics.angularDamping = ${rb.angular_damping}`);
|
|
962
|
+
lines.push(`${varPrefix}Entity.components.set(${varPrefix}Physics)`);
|
|
963
|
+
}
|
|
964
|
+
if (physics.joints) {
|
|
965
|
+
for (const j of physics.joints) {
|
|
966
|
+
lines.push(`// Joint: ${j.keyword} "${j.name || ""}" \u2014 use PhysicsJoint`);
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
return lines.join("\n");
|
|
970
|
+
}
|
|
971
|
+
function particlesToVisionOS(ps, varPrefix) {
|
|
972
|
+
const lines = [];
|
|
973
|
+
lines.push(`// Particles: ${ps.name}`);
|
|
974
|
+
lines.push(`var ${varPrefix}Particles = ParticleEmitterComponent()`);
|
|
975
|
+
if (ps.properties.rate) lines.push(`${varPrefix}Particles.birthRate = ${ps.properties.rate}`);
|
|
976
|
+
if (ps.properties.start_lifetime) {
|
|
977
|
+
const lt = Array.isArray(ps.properties.start_lifetime) ? ps.properties.start_lifetime[0] : ps.properties.start_lifetime;
|
|
978
|
+
lines.push(`${varPrefix}Particles.lifeSpan = ${lt}`);
|
|
979
|
+
}
|
|
980
|
+
if (ps.traits.includes("looping")) lines.push(`${varPrefix}Particles.isEmitting = true`);
|
|
981
|
+
lines.push(`${varPrefix}Entity.components.set(${varPrefix}Particles)`);
|
|
982
|
+
return lines.join("\n");
|
|
983
|
+
}
|
|
984
|
+
function audioSourceToVisionOS(audio, varPrefix) {
|
|
985
|
+
const lines = [];
|
|
986
|
+
lines.push(`// Audio: ${audio.name} (${audio.keyword})`);
|
|
987
|
+
const isSpatial = audio.traits.includes("spatial") || typeof audio.properties.spatial_blend === "number" && audio.properties.spatial_blend > 0;
|
|
988
|
+
if (isSpatial) {
|
|
989
|
+
lines.push(`let ${varPrefix}Audio = Entity()`);
|
|
990
|
+
lines.push(`${varPrefix}Audio.spatialAudio = SpatialAudioComponent()`);
|
|
991
|
+
if (audio.properties.max_distance)
|
|
992
|
+
lines.push(
|
|
993
|
+
`${varPrefix}Audio.spatialAudio?.distanceAttenuation = .rolloff(factor: .custom(${audio.properties.max_distance}))`
|
|
994
|
+
);
|
|
995
|
+
}
|
|
996
|
+
lines.push(
|
|
997
|
+
`let ${varPrefix}Resource = try! AudioFileResource.load(named: "${audio.properties.clip || audio.name}")`
|
|
998
|
+
);
|
|
999
|
+
lines.push(`let ${varPrefix}Controller = ${varPrefix}Entity.prepareAudio(${varPrefix}Resource)`);
|
|
1000
|
+
if (audio.properties.volume !== void 0)
|
|
1001
|
+
lines.push(
|
|
1002
|
+
`${varPrefix}Controller.gain = AudioPlaybackController.Decibel(${audio.properties.volume})`
|
|
1003
|
+
);
|
|
1004
|
+
if (audio.properties.play_on_awake) lines.push(`${varPrefix}Controller.play()`);
|
|
1005
|
+
return lines.join("\n");
|
|
1006
|
+
}
|
|
1007
|
+
function materialToAndroidXR(mat, varPrefix) {
|
|
1008
|
+
const lines = [];
|
|
1009
|
+
lines.push(`// Material: ${mat.name}`);
|
|
1010
|
+
if (mat.type === "unlit") {
|
|
1011
|
+
lines.push(`val ${varPrefix}MatBuilder = MaterialInstance.Builder()`);
|
|
1012
|
+
lines.push(
|
|
1013
|
+
` .setParameter("baseColor", ${mat.baseColor ? hexToFilamentColor(mat.baseColor) : "Float4(1f, 1f, 1f, 1f)"})`
|
|
1014
|
+
);
|
|
1015
|
+
if (mat.opacity !== void 0) lines.push(` .setParameter("alpha", ${mat.opacity}f)`);
|
|
1016
|
+
lines.push(`val ${varPrefix}Mat = ${varPrefix}MatBuilder.build(engine)`);
|
|
1017
|
+
} else {
|
|
1018
|
+
lines.push(`val ${varPrefix}MatBuilder = MaterialInstance.Builder()`);
|
|
1019
|
+
if (mat.baseColor) {
|
|
1020
|
+
lines.push(` .setParameter("baseColor", ${hexToFilamentColor(mat.baseColor)})`);
|
|
1021
|
+
}
|
|
1022
|
+
if (mat.roughness !== void 0)
|
|
1023
|
+
lines.push(` .setParameter("roughness", ${mat.roughness}f)`);
|
|
1024
|
+
if (mat.metallic !== void 0) lines.push(` .setParameter("metallic", ${mat.metallic}f)`);
|
|
1025
|
+
if (mat.opacity !== void 0 && mat.opacity < 1) {
|
|
1026
|
+
lines.push(` .setParameter("alpha", ${mat.opacity}f)`);
|
|
1027
|
+
}
|
|
1028
|
+
if (mat.emissiveColor) {
|
|
1029
|
+
const [er, eg, eb] = hexToRGBTuple(mat.emissiveColor);
|
|
1030
|
+
const intensity = mat.emissiveIntensity ?? 1;
|
|
1031
|
+
lines.push(
|
|
1032
|
+
` .setParameter("emissive", Float4(${er * intensity}f, ${eg * intensity}f, ${eb * intensity}f, 1f))`
|
|
1033
|
+
);
|
|
1034
|
+
}
|
|
1035
|
+
lines.push(`val ${varPrefix}Mat = ${varPrefix}MatBuilder.build(engine)`);
|
|
1036
|
+
}
|
|
1037
|
+
for (const [mapType, path] of Object.entries(mat.textureMaps)) {
|
|
1038
|
+
const paramName = mapType === "albedo_map" ? "baseColorMap" : mapType === "normal_map" ? "normalMap" : mapType === "metallic_map" ? "metallicMap" : mapType === "roughness_map" ? "roughnessMap" : mapType === "emission_map" ? "emissiveMap" : mapType === "occlusion_map" ? "aoMap" : mapType.replace(/_map$/, "Map");
|
|
1039
|
+
lines.push(`// Texture: ${paramName} -> "${path}"`);
|
|
1040
|
+
lines.push(
|
|
1041
|
+
`val ${varPrefix}Tex_${paramName} = Texture.Builder().build(engine) // load from "${path}"`
|
|
1042
|
+
);
|
|
1043
|
+
lines.push(
|
|
1044
|
+
`${varPrefix}Mat.setParameter("${paramName}", ${varPrefix}Tex_${paramName}, TextureSampler())`
|
|
1045
|
+
);
|
|
1046
|
+
}
|
|
1047
|
+
return lines.join("\n");
|
|
1048
|
+
}
|
|
1049
|
+
function physicsToAndroidXR(physics, varPrefix) {
|
|
1050
|
+
const lines = [];
|
|
1051
|
+
lines.push(`// Physics: ${physics.keyword} "${physics.name || ""}"`);
|
|
1052
|
+
if (physics.colliders) {
|
|
1053
|
+
for (let i = 0; i < physics.colliders.length; i++) {
|
|
1054
|
+
const c = physics.colliders[i];
|
|
1055
|
+
const shape = c.shape || "box";
|
|
1056
|
+
const colVar = `${varPrefix}Col${i}`;
|
|
1057
|
+
if (shape === "sphere") {
|
|
1058
|
+
lines.push(`val ${colVar} = SphereCollider(engine, ${c.properties.radius || 0.5}f)`);
|
|
1059
|
+
} else if (shape === "capsule") {
|
|
1060
|
+
lines.push(
|
|
1061
|
+
`val ${colVar} = CapsuleCollider(engine, ${c.properties.radius || 0.25}f, ${c.properties.height || 1}f)`
|
|
1062
|
+
);
|
|
1063
|
+
} else {
|
|
1064
|
+
const size = c.properties.size && Array.isArray(c.properties.size) ? c.properties.size : [1, 1, 1];
|
|
1065
|
+
lines.push(
|
|
1066
|
+
`val ${colVar} = BoxCollider(engine, Float3(${size[0]}f, ${size[1]}f, ${size[2]}f))`
|
|
1067
|
+
);
|
|
1068
|
+
}
|
|
1069
|
+
if (c.type === "trigger") lines.push(`${colVar}.isTrigger = true`);
|
|
1070
|
+
lines.push(`${varPrefix}Entity.addComponent(${colVar})`);
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
if (physics.rigidbody) {
|
|
1074
|
+
const rb = physics.rigidbody.properties;
|
|
1075
|
+
lines.push(`val ${varPrefix}RB = RigidBodyComponent()`);
|
|
1076
|
+
if (rb.mass !== void 0) lines.push(`${varPrefix}RB.mass = ${rb.mass}f`);
|
|
1077
|
+
if (rb.drag !== void 0) lines.push(`${varPrefix}RB.linearDamping = ${rb.drag}f`);
|
|
1078
|
+
if (rb.angular_damping !== void 0)
|
|
1079
|
+
lines.push(`${varPrefix}RB.angularDamping = ${rb.angular_damping}f`);
|
|
1080
|
+
if (rb.use_gravity === false) lines.push(`${varPrefix}RB.isGravityEnabled = false`);
|
|
1081
|
+
lines.push(`${varPrefix}Entity.addComponent(${varPrefix}RB)`);
|
|
1082
|
+
}
|
|
1083
|
+
if (physics.forceFields) {
|
|
1084
|
+
for (const ff of physics.forceFields) {
|
|
1085
|
+
if (ff.keyword === "wind_zone") {
|
|
1086
|
+
lines.push(`// Wind zone: "${ff.name || ""}" strength=${ff.properties.strength || 0}`);
|
|
1087
|
+
lines.push(`// Implement via custom force application in physics update loop`);
|
|
1088
|
+
} else {
|
|
1089
|
+
lines.push(
|
|
1090
|
+
`// Force field: ${ff.keyword} "${ff.name || ""}" \u2014 ${JSON.stringify(ff.properties)}`
|
|
1091
|
+
);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
if (physics.joints) {
|
|
1096
|
+
for (const j of physics.joints) {
|
|
1097
|
+
lines.push(`// Joint: ${j.keyword} "${j.name || ""}" \u2014 configure via PhysicsConstraint`);
|
|
1098
|
+
if (j.properties.axis) {
|
|
1099
|
+
const axis = Array.isArray(j.properties.axis) ? j.properties.axis : [0, 0, 1];
|
|
1100
|
+
lines.push(`// Axis: Float3(${axis[0]}f, ${axis[1]}f, ${axis[2]}f)`);
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
return lines.join("\n");
|
|
1105
|
+
}
|
|
1106
|
+
function particlesToAndroidXR(ps, varPrefix) {
|
|
1107
|
+
const lines = [];
|
|
1108
|
+
lines.push(`// Particles: ${ps.name}`);
|
|
1109
|
+
lines.push(`val ${varPrefix}ParticleEntity = xrSession.scene.createEntity("${ps.name}")`);
|
|
1110
|
+
lines.push(`// Configure particle system via Filament ParticleSystem or custom emitter`);
|
|
1111
|
+
if (ps.properties.rate) lines.push(`val ${varPrefix}EmitRate = ${ps.properties.rate}f`);
|
|
1112
|
+
if (ps.properties.max_particles)
|
|
1113
|
+
lines.push(`val ${varPrefix}MaxParticles = ${ps.properties.max_particles}`);
|
|
1114
|
+
if (ps.properties.start_lifetime) {
|
|
1115
|
+
const lt = Array.isArray(ps.properties.start_lifetime) ? ps.properties.start_lifetime[0] : ps.properties.start_lifetime;
|
|
1116
|
+
lines.push(`val ${varPrefix}Lifetime = ${lt}f`);
|
|
1117
|
+
}
|
|
1118
|
+
if (ps.properties.start_speed) {
|
|
1119
|
+
const sp = Array.isArray(ps.properties.start_speed) ? ps.properties.start_speed[0] : ps.properties.start_speed;
|
|
1120
|
+
lines.push(`val ${varPrefix}Speed = ${sp}f`);
|
|
1121
|
+
}
|
|
1122
|
+
if (ps.properties.gravity_modifier !== void 0) {
|
|
1123
|
+
lines.push(`val ${varPrefix}GravityMod = ${ps.properties.gravity_modifier}f`);
|
|
1124
|
+
}
|
|
1125
|
+
if (ps.traits.includes("looping")) lines.push(`val ${varPrefix}Looping = true`);
|
|
1126
|
+
if (ps.traits.includes("gpu")) lines.push(`// GPU particles: use compute shader pipeline`);
|
|
1127
|
+
for (const m of ps.modules) {
|
|
1128
|
+
lines.push(`// Module: ${m.type} \u2014 ${JSON.stringify(m.properties)}`);
|
|
1129
|
+
}
|
|
1130
|
+
return lines.join("\n");
|
|
1131
|
+
}
|
|
1132
|
+
function audioSourceToAndroidXR(audio, varPrefix) {
|
|
1133
|
+
const lines = [];
|
|
1134
|
+
lines.push(`// Audio: ${audio.name} (${audio.keyword})`);
|
|
1135
|
+
const isSpatial = audio.traits.includes("spatial") || audio.traits.includes("hrtf") || typeof audio.properties.spatial_blend === "number" && audio.properties.spatial_blend > 0;
|
|
1136
|
+
if (audio.keyword === "reverb_zone") {
|
|
1137
|
+
lines.push(`// Reverb zone: "${audio.name}" \u2014 implement via AudioEffect.EFFECT_TYPE_REVERB`);
|
|
1138
|
+
if (audio.properties.min_distance)
|
|
1139
|
+
lines.push(`// minDistance = ${audio.properties.min_distance}`);
|
|
1140
|
+
if (audio.properties.max_distance)
|
|
1141
|
+
lines.push(`// maxDistance = ${audio.properties.max_distance}`);
|
|
1142
|
+
return lines.join("\n");
|
|
1143
|
+
}
|
|
1144
|
+
lines.push(`val ${varPrefix}AudioEntity = xrSession.scene.createEntity("${audio.name}")`);
|
|
1145
|
+
if (isSpatial) {
|
|
1146
|
+
lines.push(
|
|
1147
|
+
`val ${varPrefix}SpatialTrack = SpatialAudioTrack(xrSession, ${varPrefix}AudioEntity)`
|
|
1148
|
+
);
|
|
1149
|
+
if (audio.properties.max_distance) {
|
|
1150
|
+
lines.push(`// Spatial falloff distance: ${audio.properties.max_distance}`);
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
if (audio.properties.clip) {
|
|
1154
|
+
lines.push(
|
|
1155
|
+
`val ${varPrefix}SoundId = soundPool.load(context, R.raw.${audio.properties.clip.toString().replace(/[^a-zA-Z0-9_]/g, "_")}, 1)`
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
if (audio.properties.volume !== void 0)
|
|
1159
|
+
lines.push(`val ${varPrefix}Volume = ${audio.properties.volume}f`);
|
|
1160
|
+
if (audio.properties.loop !== void 0)
|
|
1161
|
+
lines.push(
|
|
1162
|
+
`val ${varPrefix}Loop = ${audio.properties.loop ? "1" : "0"} // -1 = loop, 0 = once`
|
|
1163
|
+
);
|
|
1164
|
+
if (audio.properties.play_on_awake || audio.properties.clip) {
|
|
1165
|
+
lines.push(`soundPool.setOnLoadCompleteListener { pool, id, _ ->`);
|
|
1166
|
+
lines.push(
|
|
1167
|
+
` if (id == ${varPrefix}SoundId) pool.play(id, ${audio.properties.volume ?? 1}f, ${audio.properties.volume ?? 1}f, 1, ${audio.properties.loop ? "-1" : "0"}, 1.0f)`
|
|
1168
|
+
);
|
|
1169
|
+
lines.push(`}`);
|
|
1170
|
+
}
|
|
1171
|
+
return lines.join("\n");
|
|
1172
|
+
}
|
|
1173
|
+
function weatherToAndroidXR(weather) {
|
|
1174
|
+
const lines = [];
|
|
1175
|
+
lines.push(`// Weather: ${weather.keyword} "${weather.name || ""}"`);
|
|
1176
|
+
lines.push("// Implement weather via Filament IndirectLight + custom particle emitters");
|
|
1177
|
+
for (const [key, value] of Object.entries(weather.properties)) {
|
|
1178
|
+
lines.push(`// ${key} = ${JSON.stringify(value)}`);
|
|
1179
|
+
}
|
|
1180
|
+
for (const layer of weather.layers) {
|
|
1181
|
+
lines.push(`// Layer: ${layer.type}`);
|
|
1182
|
+
if (layer.type === "rain" || layer.type === "snow") {
|
|
1183
|
+
lines.push(
|
|
1184
|
+
`// Use GPU particle emitter for ${layer.type} \u2014 rate=${layer.properties.rate || "default"}, intensity=${layer.properties.intensity || "default"}`
|
|
1185
|
+
);
|
|
1186
|
+
} else if (layer.type === "wind") {
|
|
1187
|
+
lines.push(
|
|
1188
|
+
`// Apply force to particle systems: strength=${layer.properties.strength || "default"}, direction=${JSON.stringify(layer.properties.direction) || "default"}`
|
|
1189
|
+
);
|
|
1190
|
+
} else if (layer.type === "fog" || layer.type === "fog_layer") {
|
|
1191
|
+
lines.push(
|
|
1192
|
+
`// Configure Filament fog: density=${layer.properties.density || "default"}, color=${layer.properties.color || "default"}`
|
|
1193
|
+
);
|
|
1194
|
+
} else if (layer.type === "lightning") {
|
|
1195
|
+
lines.push(`// Lightning flash: frequency=${layer.properties.frequency || "default"}`);
|
|
1196
|
+
} else if (layer.type === "clouds") {
|
|
1197
|
+
lines.push(`// Volumetric clouds: coverage=${layer.properties.coverage || "default"}`);
|
|
1198
|
+
} else {
|
|
1199
|
+
for (const [k, v] of Object.entries(layer.properties)) {
|
|
1200
|
+
lines.push(`// ${k} = ${JSON.stringify(v)}`);
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
return lines.join("\n");
|
|
1205
|
+
}
|
|
1206
|
+
function hexToFilamentColor(hex) {
|
|
1207
|
+
const [r, g, b] = hexToRGBTuple(hex);
|
|
1208
|
+
return `Float4(${r}f, ${g}f, ${b}f, 1f)`;
|
|
1209
|
+
}
|
|
1210
|
+
function materialToBabylon(mat, varPrefix) {
|
|
1211
|
+
const lines = [];
|
|
1212
|
+
lines.push(`// Material: ${mat.name}`);
|
|
1213
|
+
if (mat.type === "unlit") {
|
|
1214
|
+
lines.push(`const ${varPrefix}Mat = new BABYLON.StandardMaterial("${mat.name}", scene);`);
|
|
1215
|
+
lines.push(`${varPrefix}Mat.disableLighting = true;`);
|
|
1216
|
+
if (mat.emissiveColor)
|
|
1217
|
+
lines.push(
|
|
1218
|
+
`${varPrefix}Mat.emissiveColor = BABYLON.Color3.FromHexString("${mat.emissiveColor}");`
|
|
1219
|
+
);
|
|
1220
|
+
} else {
|
|
1221
|
+
lines.push(`const ${varPrefix}Mat = new BABYLON.PBRMaterial("${mat.name}", scene);`);
|
|
1222
|
+
if (mat.baseColor)
|
|
1223
|
+
lines.push(`${varPrefix}Mat.albedoColor = BABYLON.Color3.FromHexString("${mat.baseColor}");`);
|
|
1224
|
+
if (mat.roughness !== void 0) lines.push(`${varPrefix}Mat.roughness = ${mat.roughness};`);
|
|
1225
|
+
if (mat.metallic !== void 0) lines.push(`${varPrefix}Mat.metallic = ${mat.metallic};`);
|
|
1226
|
+
if (mat.opacity !== void 0 && mat.opacity < 1) {
|
|
1227
|
+
lines.push(`${varPrefix}Mat.alpha = ${mat.opacity};`);
|
|
1228
|
+
}
|
|
1229
|
+
if (mat.emissiveColor) {
|
|
1230
|
+
lines.push(
|
|
1231
|
+
`${varPrefix}Mat.emissiveColor = BABYLON.Color3.FromHexString("${mat.emissiveColor}");`
|
|
1232
|
+
);
|
|
1233
|
+
if (mat.emissiveIntensity)
|
|
1234
|
+
lines.push(`${varPrefix}Mat.emissiveIntensity = ${mat.emissiveIntensity};`);
|
|
1235
|
+
}
|
|
1236
|
+
if (mat.ior !== void 0) lines.push(`${varPrefix}Mat.indexOfRefraction = ${mat.ior};`);
|
|
1237
|
+
}
|
|
1238
|
+
for (const [mapType, path] of Object.entries(mat.textureMaps)) {
|
|
1239
|
+
const prop = mapType === "albedo_map" ? "albedoTexture" : mapType === "normal_map" ? "bumpTexture" : mapType === "metallic_map" ? "metallicTexture" : mapType === "roughness_map" ? "microSurfaceTexture" : mapType === "emission_map" ? "emissiveTexture" : mapType === "occlusion_map" ? "ambientTexture" : `${mapType.replace(/_map$/, "Texture")}`;
|
|
1240
|
+
lines.push(`${varPrefix}Mat.${prop} = new BABYLON.Texture("${path}", scene);`);
|
|
1241
|
+
}
|
|
1242
|
+
return lines.join("\n");
|
|
1243
|
+
}
|
|
1244
|
+
function physicsToBabylon(physics, varPrefix) {
|
|
1245
|
+
const lines = [];
|
|
1246
|
+
lines.push(`// Physics: ${physics.keyword} "${physics.name || ""}"`);
|
|
1247
|
+
if (physics.rigidbody) {
|
|
1248
|
+
const rb = physics.rigidbody.properties;
|
|
1249
|
+
lines.push(
|
|
1250
|
+
`const ${varPrefix}Aggregate = new BABYLON.PhysicsAggregate(${varPrefix}Mesh, BABYLON.PhysicsShapeType.BOX, {`
|
|
1251
|
+
);
|
|
1252
|
+
if (rb.mass !== void 0) lines.push(` mass: ${rb.mass},`);
|
|
1253
|
+
if (rb.drag !== void 0) lines.push(` linearDamping: ${rb.drag},`);
|
|
1254
|
+
if (rb.angular_damping !== void 0) lines.push(` angularDamping: ${rb.angular_damping},`);
|
|
1255
|
+
lines.push("}, scene);");
|
|
1256
|
+
}
|
|
1257
|
+
if (physics.colliders) {
|
|
1258
|
+
for (const c of physics.colliders) {
|
|
1259
|
+
const shape = c.shape || "box";
|
|
1260
|
+
const shapeType = shape === "sphere" ? "SPHERE" : shape === "capsule" ? "CAPSULE" : "BOX";
|
|
1261
|
+
lines.push(`// Collider: ${shape} \u2014 PhysicsShapeType.${shapeType}`);
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
if (physics.joints) {
|
|
1265
|
+
for (const j of physics.joints) {
|
|
1266
|
+
const jointType = j.keyword === "hinge" ? "HingeConstraint" : j.keyword === "slider" ? "SliderConstraint" : j.keyword === "ball_socket" ? "BallAndSocketConstraint" : "Physics6DoFConstraint";
|
|
1267
|
+
lines.push(`// Joint: ${j.keyword} \u2014 BABYLON.${jointType}`);
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
return lines.join("\n");
|
|
1271
|
+
}
|
|
1272
|
+
function particlesToBabylon(ps, varPrefix) {
|
|
1273
|
+
const lines = [];
|
|
1274
|
+
lines.push(`// Particles: ${ps.name}`);
|
|
1275
|
+
const useGPU = ps.traits.includes("gpu");
|
|
1276
|
+
if (useGPU) {
|
|
1277
|
+
lines.push(
|
|
1278
|
+
`const ${varPrefix}PS = new BABYLON.GPUParticleSystem("${ps.name}", { capacity: ${ps.properties.max_particles || 1e3} }, scene);`
|
|
1279
|
+
);
|
|
1280
|
+
} else {
|
|
1281
|
+
lines.push(
|
|
1282
|
+
`const ${varPrefix}PS = new BABYLON.ParticleSystem("${ps.name}", ${ps.properties.max_particles || 1e3}, scene);`
|
|
1283
|
+
);
|
|
1284
|
+
}
|
|
1285
|
+
if (ps.properties.rate) lines.push(`${varPrefix}PS.emitRate = ${ps.properties.rate};`);
|
|
1286
|
+
if (ps.properties.start_lifetime) {
|
|
1287
|
+
const lt = ps.properties.start_lifetime;
|
|
1288
|
+
if (Array.isArray(lt)) {
|
|
1289
|
+
lines.push(`${varPrefix}PS.minLifeTime = ${lt[0]};`);
|
|
1290
|
+
lines.push(`${varPrefix}PS.maxLifeTime = ${lt[1] || lt[0]};`);
|
|
1291
|
+
} else {
|
|
1292
|
+
lines.push(`${varPrefix}PS.minLifeTime = ${lt};`);
|
|
1293
|
+
lines.push(`${varPrefix}PS.maxLifeTime = ${lt};`);
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
if (ps.properties.start_speed) {
|
|
1297
|
+
const sp = ps.properties.start_speed;
|
|
1298
|
+
if (Array.isArray(sp)) {
|
|
1299
|
+
lines.push(`${varPrefix}PS.minEmitPower = ${sp[0]};`);
|
|
1300
|
+
lines.push(`${varPrefix}PS.maxEmitPower = ${sp[1] || sp[0]};`);
|
|
1301
|
+
} else {
|
|
1302
|
+
lines.push(`${varPrefix}PS.minEmitPower = ${sp};`);
|
|
1303
|
+
lines.push(`${varPrefix}PS.maxEmitPower = ${sp};`);
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
if (ps.properties.gravity_modifier !== void 0) {
|
|
1307
|
+
const gravMod = typeof ps.properties.gravity_modifier === "number" ? ps.properties.gravity_modifier : 1;
|
|
1308
|
+
lines.push(`${varPrefix}PS.gravity = new BABYLON.Vector3(0, ${ -9.81 * gravMod}, 0);`);
|
|
1309
|
+
}
|
|
1310
|
+
lines.push(`${varPrefix}PS.start();`);
|
|
1311
|
+
return lines.join("\n");
|
|
1312
|
+
}
|
|
1313
|
+
function postProcessingToBabylon(pp) {
|
|
1314
|
+
const lines = [];
|
|
1315
|
+
lines.push(`// Post-Processing: ${pp.keyword}`);
|
|
1316
|
+
lines.push(
|
|
1317
|
+
'const pipeline = new BABYLON.DefaultRenderingPipeline("default", true, scene, [camera]);'
|
|
1318
|
+
);
|
|
1319
|
+
for (const e of pp.effects) {
|
|
1320
|
+
if (e.type === "bloom") {
|
|
1321
|
+
lines.push("pipeline.bloomEnabled = true;");
|
|
1322
|
+
if (e.properties.intensity) lines.push(`pipeline.bloomWeight = ${e.properties.intensity};`);
|
|
1323
|
+
if (e.properties.threshold)
|
|
1324
|
+
lines.push(`pipeline.bloomThreshold = ${e.properties.threshold};`);
|
|
1325
|
+
} else if (e.type === "depth_of_field") {
|
|
1326
|
+
lines.push("pipeline.depthOfFieldEnabled = true;");
|
|
1327
|
+
if (e.properties.focal_length)
|
|
1328
|
+
lines.push(`pipeline.depthOfField.focalLength = ${e.properties.focal_length};`);
|
|
1329
|
+
} else if (e.type === "chromatic_aberration") {
|
|
1330
|
+
lines.push("pipeline.chromaticAberrationEnabled = true;");
|
|
1331
|
+
if (e.properties.amount)
|
|
1332
|
+
lines.push(`pipeline.chromaticAberration.aberrationAmount = ${e.properties.amount};`);
|
|
1333
|
+
} else if (e.type === "vignette") {
|
|
1334
|
+
lines.push("pipeline.imageProcessing.vignetteEnabled = true;");
|
|
1335
|
+
if (e.properties.weight)
|
|
1336
|
+
lines.push(`pipeline.imageProcessing.vignetteWeight = ${e.properties.weight};`);
|
|
1337
|
+
} else {
|
|
1338
|
+
lines.push(`// Effect: ${e.type} \u2014 ${JSON.stringify(e.properties)}`);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
return lines.join("\n");
|
|
1342
|
+
}
|
|
1343
|
+
function audioSourceToBabylon(audio, varPrefix) {
|
|
1344
|
+
const lines = [];
|
|
1345
|
+
lines.push(`// Audio: ${audio.name} (${audio.keyword})`);
|
|
1346
|
+
const isSpatial = audio.traits.includes("spatial") || typeof audio.properties.spatial_blend === "number" && audio.properties.spatial_blend > 0;
|
|
1347
|
+
lines.push(
|
|
1348
|
+
`const ${varPrefix}Sound = new BABYLON.Sound("${audio.name}", "${audio.properties.clip || ""}", scene, null, {`
|
|
1349
|
+
);
|
|
1350
|
+
if (audio.properties.loop !== void 0) lines.push(` loop: ${audio.properties.loop},`);
|
|
1351
|
+
if (audio.properties.volume !== void 0) lines.push(` volume: ${audio.properties.volume},`);
|
|
1352
|
+
if (isSpatial) lines.push(" spatialSound: true,");
|
|
1353
|
+
if (audio.properties.play_on_awake) lines.push(" autoplay: true,");
|
|
1354
|
+
if (isSpatial && audio.properties.max_distance)
|
|
1355
|
+
lines.push(` maxDistance: ${audio.properties.max_distance},`);
|
|
1356
|
+
lines.push("});");
|
|
1357
|
+
return lines.join("\n");
|
|
1358
|
+
}
|
|
1359
|
+
function materialToPlayCanvas(mat, varPrefix) {
|
|
1360
|
+
const lines = [];
|
|
1361
|
+
lines.push(`// Material: ${mat.name}`);
|
|
1362
|
+
lines.push(`const ${varPrefix}Mat = new pc.StandardMaterial();`);
|
|
1363
|
+
lines.push(`${varPrefix}Mat.name = "${mat.name}";`);
|
|
1364
|
+
if (mat.baseColor)
|
|
1365
|
+
lines.push(`${varPrefix}Mat.diffuse = new pc.Color().fromString("${mat.baseColor}");`);
|
|
1366
|
+
if (mat.roughness !== void 0)
|
|
1367
|
+
lines.push(`${varPrefix}Mat.gloss = ${1 - mat.roughness}; // roughness inverted`);
|
|
1368
|
+
if (mat.metallic !== void 0) lines.push(`${varPrefix}Mat.metalness = ${mat.metallic};`);
|
|
1369
|
+
if (mat.metallic !== void 0) lines.push(`${varPrefix}Mat.useMetalness = true;`);
|
|
1370
|
+
if (mat.opacity !== void 0 && mat.opacity < 1) {
|
|
1371
|
+
lines.push(`${varPrefix}Mat.opacity = ${mat.opacity};`);
|
|
1372
|
+
lines.push(`${varPrefix}Mat.blendType = pc.BLEND_NORMAL;`);
|
|
1373
|
+
}
|
|
1374
|
+
if (mat.emissiveColor) {
|
|
1375
|
+
lines.push(`${varPrefix}Mat.emissive = new pc.Color().fromString("${mat.emissiveColor}");`);
|
|
1376
|
+
if (mat.emissiveIntensity)
|
|
1377
|
+
lines.push(`${varPrefix}Mat.emissiveIntensity = ${mat.emissiveIntensity};`);
|
|
1378
|
+
}
|
|
1379
|
+
lines.push(`${varPrefix}Mat.update();`);
|
|
1380
|
+
return lines.join("\n");
|
|
1381
|
+
}
|
|
1382
|
+
function physicsToPlayCanvas(physics, varPrefix) {
|
|
1383
|
+
const lines = [];
|
|
1384
|
+
lines.push(`// Physics: ${physics.keyword} "${physics.name || ""}"`);
|
|
1385
|
+
if (physics.rigidbody) {
|
|
1386
|
+
const rb = physics.rigidbody.properties;
|
|
1387
|
+
lines.push(`${varPrefix}Entity.addComponent("rigidbody", {`);
|
|
1388
|
+
lines.push(` type: "dynamic",`);
|
|
1389
|
+
if (rb.mass !== void 0) lines.push(` mass: ${rb.mass},`);
|
|
1390
|
+
if (rb.drag !== void 0) lines.push(` linearDamping: ${rb.drag},`);
|
|
1391
|
+
if (rb.angular_damping !== void 0) lines.push(` angularDamping: ${rb.angular_damping},`);
|
|
1392
|
+
lines.push("});");
|
|
1393
|
+
}
|
|
1394
|
+
if (physics.colliders) {
|
|
1395
|
+
for (const c of physics.colliders) {
|
|
1396
|
+
const shape = c.shape || "box";
|
|
1397
|
+
lines.push(`${varPrefix}Entity.addComponent("collision", {`);
|
|
1398
|
+
lines.push(` type: "${shape}",`);
|
|
1399
|
+
if (c.properties.radius) lines.push(` radius: ${c.properties.radius},`);
|
|
1400
|
+
if (c.properties.height) lines.push(` height: ${c.properties.height},`);
|
|
1401
|
+
if (c.properties.size && Array.isArray(c.properties.size)) {
|
|
1402
|
+
lines.push(
|
|
1403
|
+
` halfExtents: new pc.Vec3(${c.properties.size.map((s) => s / 2).join(", ")}),`
|
|
1404
|
+
);
|
|
1405
|
+
}
|
|
1406
|
+
lines.push("});");
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
return lines.join("\n");
|
|
1410
|
+
}
|
|
1411
|
+
function particlesToPlayCanvas(ps, varPrefix) {
|
|
1412
|
+
const lines = [];
|
|
1413
|
+
lines.push(`// Particles: ${ps.name}`);
|
|
1414
|
+
lines.push(`${varPrefix}Entity.addComponent("particlesystem", {`);
|
|
1415
|
+
if (ps.properties.max_particles) lines.push(` numParticles: ${ps.properties.max_particles},`);
|
|
1416
|
+
if (ps.properties.rate) lines.push(` rate: ${ps.properties.rate},`);
|
|
1417
|
+
if (ps.properties.start_lifetime)
|
|
1418
|
+
lines.push(
|
|
1419
|
+
` lifetime: ${Array.isArray(ps.properties.start_lifetime) ? ps.properties.start_lifetime[0] : ps.properties.start_lifetime},`
|
|
1420
|
+
);
|
|
1421
|
+
if (ps.properties.start_speed)
|
|
1422
|
+
lines.push(
|
|
1423
|
+
` emitterExtents: new pc.Vec3(${Array.isArray(ps.properties.start_speed) ? ps.properties.start_speed[0] : ps.properties.start_speed}, 0, 0),`
|
|
1424
|
+
);
|
|
1425
|
+
lines.push(` loop: ${ps.traits.includes("looping")},`);
|
|
1426
|
+
lines.push("});");
|
|
1427
|
+
return lines.join("\n");
|
|
1428
|
+
}
|
|
1429
|
+
function audioSourceToPlayCanvas(audio, varPrefix) {
|
|
1430
|
+
const lines = [];
|
|
1431
|
+
lines.push(`// Audio: ${audio.name} (${audio.keyword})`);
|
|
1432
|
+
lines.push(`${varPrefix}Entity.addComponent("sound", {`);
|
|
1433
|
+
lines.push(
|
|
1434
|
+
` positional: ${audio.traits.includes("spatial") || typeof audio.properties.spatial_blend === "number" && audio.properties.spatial_blend > 0},`
|
|
1435
|
+
);
|
|
1436
|
+
if (audio.properties.volume !== void 0) lines.push(` volume: ${audio.properties.volume},`);
|
|
1437
|
+
if (audio.properties.max_distance) lines.push(` maxDistance: ${audio.properties.max_distance},`);
|
|
1438
|
+
lines.push("});");
|
|
1439
|
+
if (audio.properties.clip) {
|
|
1440
|
+
lines.push(
|
|
1441
|
+
`${varPrefix}Entity.sound.addSlot("${audio.name}", { asset: app.assets.find("${audio.properties.clip}"),`
|
|
1442
|
+
);
|
|
1443
|
+
if (audio.properties.loop !== void 0) lines.push(` loop: ${audio.properties.loop},`);
|
|
1444
|
+
if (audio.properties.play_on_awake) lines.push(" autoPlay: true,");
|
|
1445
|
+
lines.push("});");
|
|
1446
|
+
}
|
|
1447
|
+
return lines.join("\n");
|
|
1448
|
+
}
|
|
1449
|
+
function materialToSDF(mat) {
|
|
1450
|
+
const lines = [];
|
|
1451
|
+
lines.push(`<material>`);
|
|
1452
|
+
lines.push(` <script><name>${mat.name}</name></script>`);
|
|
1453
|
+
if (mat.baseColor) {
|
|
1454
|
+
const [r, g, b] = hexToRGBTuple(mat.baseColor);
|
|
1455
|
+
lines.push(` <ambient>${r} ${g} ${b} 1</ambient>`);
|
|
1456
|
+
lines.push(` <diffuse>${r} ${g} ${b} ${mat.opacity ?? 1}</diffuse>`);
|
|
1457
|
+
}
|
|
1458
|
+
if (mat.metallic !== void 0 && mat.metallic > 0.5) {
|
|
1459
|
+
lines.push(` <specular>0.8 0.8 0.8 1</specular>`);
|
|
1460
|
+
}
|
|
1461
|
+
if (mat.emissiveColor) {
|
|
1462
|
+
const [r, g, b] = hexToRGBTuple(mat.emissiveColor);
|
|
1463
|
+
lines.push(` <emissive>${r} ${g} ${b} 1</emissive>`);
|
|
1464
|
+
}
|
|
1465
|
+
lines.push(`</material>`);
|
|
1466
|
+
return lines.join("\n");
|
|
1467
|
+
}
|
|
1468
|
+
function physicsToSDF(physics) {
|
|
1469
|
+
const lines = [];
|
|
1470
|
+
if (physics.rigidbody) {
|
|
1471
|
+
const rb = physics.rigidbody.properties;
|
|
1472
|
+
lines.push("<inertial>");
|
|
1473
|
+
lines.push(` <mass>${rb.mass ?? 1}</mass>`);
|
|
1474
|
+
lines.push("</inertial>");
|
|
1475
|
+
}
|
|
1476
|
+
if (physics.colliders) {
|
|
1477
|
+
for (const c of physics.colliders) {
|
|
1478
|
+
const shape = c.shape || "box";
|
|
1479
|
+
lines.push('<collision name="collision">');
|
|
1480
|
+
lines.push(" <geometry>");
|
|
1481
|
+
if (shape === "sphere") {
|
|
1482
|
+
lines.push(` <sphere><radius>${c.properties.radius || 0.5}</radius></sphere>`);
|
|
1483
|
+
} else if (shape === "capsule" || shape === "cylinder") {
|
|
1484
|
+
lines.push(
|
|
1485
|
+
` <cylinder><radius>${c.properties.radius || 0.5}</radius><length>${c.properties.height || 1}</length></cylinder>`
|
|
1486
|
+
);
|
|
1487
|
+
} else {
|
|
1488
|
+
const size = c.properties.size && Array.isArray(c.properties.size) ? c.properties.size : [1, 1, 1];
|
|
1489
|
+
lines.push(` <box><size>${size.join(" ")}</size></box>`);
|
|
1490
|
+
}
|
|
1491
|
+
lines.push(" </geometry>");
|
|
1492
|
+
lines.push("</collision>");
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
if (physics.joints) {
|
|
1496
|
+
for (const j of physics.joints) {
|
|
1497
|
+
const sdfType = j.keyword === "hinge" ? "revolute" : j.keyword === "slider" ? "prismatic" : j.keyword === "ball_socket" ? "ball" : j.keyword === "fixed_joint" ? "fixed" : "revolute";
|
|
1498
|
+
lines.push(`<joint name="${j.name || "joint"}" type="${sdfType}">`);
|
|
1499
|
+
if (j.properties.axis) {
|
|
1500
|
+
const axis = Array.isArray(j.properties.axis) ? j.properties.axis : [0, 0, 1];
|
|
1501
|
+
lines.push(` <axis><xyz>${axis.join(" ")}</xyz></axis>`);
|
|
1502
|
+
}
|
|
1503
|
+
if (j.properties.limits) {
|
|
1504
|
+
const limVals = Array.isArray(j.properties.limits) ? j.properties.limits : void 0;
|
|
1505
|
+
if (limVals)
|
|
1506
|
+
lines.push(
|
|
1507
|
+
` <axis><limit><lower>${limVals[0]}</lower><upper>${limVals[1]}</upper></limit></axis>`
|
|
1508
|
+
);
|
|
1509
|
+
}
|
|
1510
|
+
lines.push("</joint>");
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
return lines.join("\n");
|
|
1514
|
+
}
|
|
1515
|
+
function materialToVRChat(mat, varPrefix) {
|
|
1516
|
+
const lines = [];
|
|
1517
|
+
lines.push(`// VRChat Material: ${mat.name}`);
|
|
1518
|
+
lines.push(`var ${varPrefix}Mat = new Material(Shader.Find("VRChat/Mobile/Standard Lite"));`);
|
|
1519
|
+
if (mat.baseColor)
|
|
1520
|
+
lines.push(`${varPrefix}Mat.SetColor("_Color", ${hexToUnityColor(mat.baseColor)});`);
|
|
1521
|
+
if (mat.roughness !== void 0)
|
|
1522
|
+
lines.push(`${varPrefix}Mat.SetFloat("_Glossiness", ${(1 - mat.roughness).toFixed(3)}f);`);
|
|
1523
|
+
if (mat.metallic !== void 0)
|
|
1524
|
+
lines.push(`${varPrefix}Mat.SetFloat("_Metallic", ${mat.metallic}f);`);
|
|
1525
|
+
if (mat.emissiveColor) {
|
|
1526
|
+
lines.push(`${varPrefix}Mat.EnableKeyword("_EMISSION");`);
|
|
1527
|
+
lines.push(
|
|
1528
|
+
`${varPrefix}Mat.SetColor("_EmissionColor", ${hexToUnityColor(mat.emissiveColor)});`
|
|
1529
|
+
);
|
|
1530
|
+
}
|
|
1531
|
+
return lines.join("\n");
|
|
1532
|
+
}
|
|
1533
|
+
function particlesToUSD(ps) {
|
|
1534
|
+
const lines = [];
|
|
1535
|
+
lines.push(`def Scope "Particles_${ps.name.replace(/[^a-zA-Z0-9_]/g, "_")}" {`);
|
|
1536
|
+
lines.push(` custom string holoscript:type = "particle_system"`);
|
|
1537
|
+
if (ps.properties.rate) lines.push(` custom float holoscript:rate = ${ps.properties.rate}`);
|
|
1538
|
+
if (ps.properties.max_particles)
|
|
1539
|
+
lines.push(` custom int holoscript:maxParticles = ${ps.properties.max_particles}`);
|
|
1540
|
+
if (ps.properties.start_lifetime)
|
|
1541
|
+
lines.push(
|
|
1542
|
+
` custom float holoscript:lifetime = ${Array.isArray(ps.properties.start_lifetime) ? ps.properties.start_lifetime[0] : ps.properties.start_lifetime}`
|
|
1543
|
+
);
|
|
1544
|
+
for (const m of ps.modules) {
|
|
1545
|
+
lines.push(` def Scope "${m.type}" {`);
|
|
1546
|
+
for (const [k, v] of Object.entries(m.properties)) {
|
|
1547
|
+
const usdType = typeof v === "number" ? "float" : typeof v === "boolean" ? "bool" : "string";
|
|
1548
|
+
lines.push(` custom ${usdType} ${k} = ${JSON.stringify(v)}`);
|
|
1549
|
+
}
|
|
1550
|
+
lines.push(" }");
|
|
1551
|
+
}
|
|
1552
|
+
lines.push("}");
|
|
1553
|
+
return lines.join("\n");
|
|
1554
|
+
}
|
|
1555
|
+
function postProcessingToUSD(pp) {
|
|
1556
|
+
const lines = [];
|
|
1557
|
+
lines.push(`def Scope "PostProcessing" {`);
|
|
1558
|
+
for (const e of pp.effects) {
|
|
1559
|
+
lines.push(` def Scope "${e.type}" {`);
|
|
1560
|
+
for (const [k, v] of Object.entries(e.properties)) {
|
|
1561
|
+
const usdType = typeof v === "number" ? "float" : typeof v === "boolean" ? "bool" : "string";
|
|
1562
|
+
lines.push(` custom ${usdType} ${k} = ${JSON.stringify(v)}`);
|
|
1563
|
+
}
|
|
1564
|
+
lines.push(" }");
|
|
1565
|
+
}
|
|
1566
|
+
lines.push("}");
|
|
1567
|
+
return lines.join("\n");
|
|
1568
|
+
}
|
|
1569
|
+
function audioSourceToUSD(audio) {
|
|
1570
|
+
const lines = [];
|
|
1571
|
+
lines.push(`def Scope "Audio_${audio.name.replace(/[^a-zA-Z0-9_]/g, "_")}" {`);
|
|
1572
|
+
lines.push(` custom string holoscript:type = "${audio.keyword}"`);
|
|
1573
|
+
if (audio.properties.clip) lines.push(` asset holoscript:clip = @${audio.properties.clip}@`);
|
|
1574
|
+
if (audio.properties.volume !== void 0)
|
|
1575
|
+
lines.push(` custom float holoscript:volume = ${audio.properties.volume}`);
|
|
1576
|
+
if (audio.properties.loop !== void 0)
|
|
1577
|
+
lines.push(` custom bool holoscript:loop = ${audio.properties.loop}`);
|
|
1578
|
+
if (audio.properties.spatial_blend !== void 0)
|
|
1579
|
+
lines.push(` custom float holoscript:spatialBlend = ${audio.properties.spatial_blend}`);
|
|
1580
|
+
lines.push("}");
|
|
1581
|
+
return lines.join("\n");
|
|
1582
|
+
}
|
|
1583
|
+
function physicsToR3F(physics) {
|
|
1584
|
+
const lines = [];
|
|
1585
|
+
if (physics.rigidbody) {
|
|
1586
|
+
const rb = physics.rigidbody.properties;
|
|
1587
|
+
const bodyType = rb.use_gravity === false ? "kinematicPosition" : "dynamic";
|
|
1588
|
+
lines.push(
|
|
1589
|
+
`<RigidBody type="${bodyType}"${rb.mass ? ` mass={${rb.mass}}` : ""}${rb.drag ? ` linearDamping={${rb.drag}}` : ""}${rb.angular_damping ? ` angularDamping={${rb.angular_damping}}` : ""}>`
|
|
1590
|
+
);
|
|
1591
|
+
}
|
|
1592
|
+
if (physics.colliders) {
|
|
1593
|
+
for (const c of physics.colliders) {
|
|
1594
|
+
const shape = c.shape || "cuboid";
|
|
1595
|
+
const r3fShape = shape === "box" ? "cuboid" : shape === "sphere" ? "ball" : shape;
|
|
1596
|
+
const args = shape === "sphere" && c.properties.radius ? ` args={[${c.properties.radius}]}` : "";
|
|
1597
|
+
lines.push(
|
|
1598
|
+
` <${c.type === "trigger" ? "CuboidCollider sensor" : `${capitalizeFirst(r3fShape)}Collider`}${args} />`
|
|
1599
|
+
);
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
if (physics.rigidbody) {
|
|
1603
|
+
lines.push("</RigidBody>");
|
|
1604
|
+
}
|
|
1605
|
+
if (physics.joints) {
|
|
1606
|
+
for (const j of physics.joints) {
|
|
1607
|
+
lines.push(
|
|
1608
|
+
`{/* Joint: ${j.keyword} "${j.name || ""}" \u2014 use useRevoluteJoint/useSphericalJoint */}`
|
|
1609
|
+
);
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
if (physics.forceFields) {
|
|
1613
|
+
for (const ff of physics.forceFields) {
|
|
1614
|
+
lines.push(
|
|
1615
|
+
`{/* Force field: ${ff.keyword} "${ff.name || ""}" \u2014 ${JSON.stringify(ff.properties)} */}`
|
|
1616
|
+
);
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
return lines.join("\n");
|
|
1620
|
+
}
|
|
1621
|
+
function weatherToR3F(weather) {
|
|
1622
|
+
const lines = [];
|
|
1623
|
+
lines.push(`{/* Weather: ${weather.keyword} "${weather.name || ""}" */}`);
|
|
1624
|
+
for (const layer of weather.layers) {
|
|
1625
|
+
const componentName = capitalizeFirst(layer.type);
|
|
1626
|
+
const props = Object.entries(layer.properties).map(([k, v]) => {
|
|
1627
|
+
const camel = k.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
1628
|
+
return typeof v === "string" ? `${camel}="${v}"` : `${camel}={${JSON.stringify(v)}}`;
|
|
1629
|
+
}).join(" ");
|
|
1630
|
+
lines.push(`<${componentName} ${props} />`);
|
|
1631
|
+
}
|
|
1632
|
+
return lines.join("\n");
|
|
1633
|
+
}
|
|
1634
|
+
function materialToWebGPU(mat, varPrefix) {
|
|
1635
|
+
const lines = [];
|
|
1636
|
+
lines.push(`// Material: ${mat.name}`);
|
|
1637
|
+
lines.push(`const ${varPrefix}MaterialData = new Float32Array([`);
|
|
1638
|
+
if (mat.baseColor) {
|
|
1639
|
+
const [r, g, b] = hexToRGBTuple(mat.baseColor);
|
|
1640
|
+
lines.push(` ${r}, ${g}, ${b}, ${mat.opacity ?? 1}, // baseColor + opacity`);
|
|
1641
|
+
} else {
|
|
1642
|
+
lines.push(" 1.0, 1.0, 1.0, 1.0, // baseColor + opacity");
|
|
1643
|
+
}
|
|
1644
|
+
lines.push(
|
|
1645
|
+
` ${mat.roughness ?? 0.5}, ${mat.metallic ?? 0}, ${mat.ior ?? 1.5}, 0.0, // roughness, metallic, ior, pad`
|
|
1646
|
+
);
|
|
1647
|
+
if (mat.emissiveColor) {
|
|
1648
|
+
const [r, g, b] = hexToRGBTuple(mat.emissiveColor);
|
|
1649
|
+
lines.push(` ${r}, ${g}, ${b}, ${mat.emissiveIntensity ?? 1}, // emissive + intensity`);
|
|
1650
|
+
} else {
|
|
1651
|
+
lines.push(" 0.0, 0.0, 0.0, 0.0, // emissive + intensity");
|
|
1652
|
+
}
|
|
1653
|
+
lines.push("]);");
|
|
1654
|
+
lines.push(`const ${varPrefix}MaterialBuffer = device.createBuffer({`);
|
|
1655
|
+
lines.push(` size: ${varPrefix}MaterialData.byteLength,`);
|
|
1656
|
+
lines.push(" usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,");
|
|
1657
|
+
lines.push("});");
|
|
1658
|
+
lines.push(`device.queue.writeBuffer(${varPrefix}MaterialBuffer, 0, ${varPrefix}MaterialData);`);
|
|
1659
|
+
return lines.join("\n");
|
|
1660
|
+
}
|
|
1661
|
+
function hexToRGBTuple(hex) {
|
|
1662
|
+
const h = hex.replace("#", "");
|
|
1663
|
+
return [
|
|
1664
|
+
parseFloat((parseInt(h.substring(0, 2), 16) / 255).toFixed(3)),
|
|
1665
|
+
parseFloat((parseInt(h.substring(2, 4), 16) / 255).toFixed(3)),
|
|
1666
|
+
parseFloat((parseInt(h.substring(4, 6), 16) / 255).toFixed(3))
|
|
1667
|
+
];
|
|
1668
|
+
}
|
|
1669
|
+
function hexToUnityColor(hex) {
|
|
1670
|
+
const [r, g, b] = hexToRGBTuple(hex);
|
|
1671
|
+
return `new Color(${r}f, ${g}f, ${b}f)`;
|
|
1672
|
+
}
|
|
1673
|
+
function hexToSwiftColor(hex) {
|
|
1674
|
+
return `.init(red: 0x${hex.slice(1, 3)}, green: 0x${hex.slice(3, 5)}, blue: 0x${hex.slice(5, 7)})`;
|
|
1675
|
+
}
|
|
1676
|
+
function capitalizeFirst(s) {
|
|
1677
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
1678
|
+
}
|
|
1679
|
+
function compileNarrativeBlock(block) {
|
|
1680
|
+
const chapters = [];
|
|
1681
|
+
let hasChoices = false;
|
|
1682
|
+
for (const child of block.children || []) {
|
|
1683
|
+
const c = child;
|
|
1684
|
+
if (c.type !== "DomainBlock") continue;
|
|
1685
|
+
const kw = c.keyword;
|
|
1686
|
+
if (kw === "chapter" || kw === "act" || kw === "scene") {
|
|
1687
|
+
const chapter = compileChapterBlock(c);
|
|
1688
|
+
if (chapter.choices && chapter.choices.length > 0) hasChoices = true;
|
|
1689
|
+
chapters.push(chapter);
|
|
1690
|
+
} else if (kw === "dialogue_tree") {
|
|
1691
|
+
const dialogueLines = [];
|
|
1692
|
+
const choices = [];
|
|
1693
|
+
for (const dc of c.children || []) {
|
|
1694
|
+
const dck = dc.keyword;
|
|
1695
|
+
if (dck === "line" || dck === "dialogue") {
|
|
1696
|
+
dialogueLines.push(compileDialogueLine(dc));
|
|
1697
|
+
} else if (dck === "choice") {
|
|
1698
|
+
choices.push(compileChoiceNode(dc));
|
|
1699
|
+
hasChoices = true;
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
chapters.push({
|
|
1703
|
+
name: c.name || "dialogue",
|
|
1704
|
+
dialogueLines: dialogueLines.length > 0 ? dialogueLines : void 0,
|
|
1705
|
+
choices: choices.length > 0 ? choices : void 0
|
|
1706
|
+
});
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
const props = block.properties || {};
|
|
1710
|
+
const narrativeType = hasChoices ? "branching" : props.type === "open_world" ? "open_world" : "linear";
|
|
1711
|
+
return {
|
|
1712
|
+
name: block.name || "unnamed",
|
|
1713
|
+
type: narrativeType,
|
|
1714
|
+
chapters,
|
|
1715
|
+
startChapter: props.start_chapter || props.startChapter,
|
|
1716
|
+
variables: props.variables
|
|
1717
|
+
};
|
|
1718
|
+
}
|
|
1719
|
+
function compileChapterBlock(block) {
|
|
1720
|
+
const props = block.properties || {};
|
|
1721
|
+
const dialogueLines = [];
|
|
1722
|
+
const choices = [];
|
|
1723
|
+
const cutsceneActions = [];
|
|
1724
|
+
for (const child of block.children || []) {
|
|
1725
|
+
const c = child;
|
|
1726
|
+
const kw = c.keyword;
|
|
1727
|
+
if (kw === "line" || kw === "dialogue") {
|
|
1728
|
+
dialogueLines.push(compileDialogueLine(c));
|
|
1729
|
+
} else if (kw === "choice") {
|
|
1730
|
+
choices.push(compileChoiceNode(c));
|
|
1731
|
+
} else if (kw === "cutscene" || kw === "camera" || kw === "action" || kw === "wait" || kw === "effect" || kw === "audio") {
|
|
1732
|
+
cutsceneActions.push(compileCutsceneAction(c));
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
return {
|
|
1736
|
+
name: block.name || "unnamed",
|
|
1737
|
+
trigger: props.trigger || props.on_enter,
|
|
1738
|
+
dialogueLines: dialogueLines.length > 0 ? dialogueLines : void 0,
|
|
1739
|
+
choices: choices.length > 0 ? choices : void 0,
|
|
1740
|
+
onComplete: props.on_complete || props.next,
|
|
1741
|
+
cutsceneActions: cutsceneActions.length > 0 ? cutsceneActions : void 0
|
|
1742
|
+
};
|
|
1743
|
+
}
|
|
1744
|
+
function compileDialogueLine(block) {
|
|
1745
|
+
const props = block.properties || {};
|
|
1746
|
+
return {
|
|
1747
|
+
speaker: props.speaker || props.character,
|
|
1748
|
+
text: props.text || props.content || block.name || "",
|
|
1749
|
+
emotion: props.emotion,
|
|
1750
|
+
duration: props.duration,
|
|
1751
|
+
voiceClip: props.voice_clip || props.voiceClip || props.audio
|
|
1752
|
+
};
|
|
1753
|
+
}
|
|
1754
|
+
function compileChoiceNode(block) {
|
|
1755
|
+
const props = block.properties || {};
|
|
1756
|
+
return {
|
|
1757
|
+
text: props.text || block.name || "",
|
|
1758
|
+
condition: props.condition,
|
|
1759
|
+
nextChapter: props.next || props.next_chapter || props.goto,
|
|
1760
|
+
action: props.action
|
|
1761
|
+
};
|
|
1762
|
+
}
|
|
1763
|
+
function compileCutsceneAction(block) {
|
|
1764
|
+
const props = block.properties || {};
|
|
1765
|
+
const kw = block.keyword;
|
|
1766
|
+
const type = kw === "camera" || kw === "camera_move" ? "camera_move" : kw === "action" || kw === "character_action" ? "character_action" : kw === "wait" ? "wait" : kw === "audio" ? "audio" : "effect";
|
|
1767
|
+
return {
|
|
1768
|
+
type,
|
|
1769
|
+
target: props.target || block.name,
|
|
1770
|
+
params: { ...props },
|
|
1771
|
+
duration: props.duration
|
|
1772
|
+
};
|
|
1773
|
+
}
|
|
1774
|
+
function narrativeToUnity(narrative) {
|
|
1775
|
+
const lines = [];
|
|
1776
|
+
const safeName = narrative.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
1777
|
+
lines.push(`// StoryWeaver Narrative: ${narrative.name}`);
|
|
1778
|
+
lines.push(`[CreateAssetMenu(menuName = "StoryWeaver/${safeName}")]`);
|
|
1779
|
+
lines.push(`public class ${safeName}Narrative : ScriptableObject {`);
|
|
1780
|
+
lines.push(` public NarrativeType type = NarrativeType.${capitalizeFirst(narrative.type)};`);
|
|
1781
|
+
if (narrative.startChapter) {
|
|
1782
|
+
lines.push(` public string startChapter = "${narrative.startChapter}";`);
|
|
1783
|
+
}
|
|
1784
|
+
lines.push("");
|
|
1785
|
+
for (const chapter of narrative.chapters) {
|
|
1786
|
+
lines.push(` [Header("${chapter.name}")]`);
|
|
1787
|
+
lines.push(` public Chapter ${chapter.name.replace(/[^a-zA-Z0-9_]/g, "_")} = new Chapter {`);
|
|
1788
|
+
if (chapter.trigger) lines.push(` trigger = "${chapter.trigger}",`);
|
|
1789
|
+
if (chapter.onComplete) lines.push(` onComplete = "${chapter.onComplete}",`);
|
|
1790
|
+
if (chapter.dialogueLines && chapter.dialogueLines.length > 0) {
|
|
1791
|
+
lines.push(" dialogueLines = new DialogueLine[] {");
|
|
1792
|
+
for (const dl of chapter.dialogueLines) {
|
|
1793
|
+
const parts = [`text = "${dl.text}"`];
|
|
1794
|
+
if (dl.speaker) parts.push(`speaker = "${dl.speaker}"`);
|
|
1795
|
+
if (dl.emotion) parts.push(`emotion = "${dl.emotion}"`);
|
|
1796
|
+
if (dl.duration) parts.push(`duration = ${dl.duration}f`);
|
|
1797
|
+
if (dl.voiceClip) parts.push(`voiceClip = "${dl.voiceClip}"`);
|
|
1798
|
+
lines.push(` new DialogueLine { ${parts.join(", ")} },`);
|
|
1799
|
+
}
|
|
1800
|
+
lines.push(" },");
|
|
1801
|
+
}
|
|
1802
|
+
if (chapter.choices && chapter.choices.length > 0) {
|
|
1803
|
+
lines.push(" choices = new Choice[] {");
|
|
1804
|
+
for (const ch of chapter.choices) {
|
|
1805
|
+
const parts = [`text = "${ch.text}"`];
|
|
1806
|
+
if (ch.nextChapter) parts.push(`nextChapter = "${ch.nextChapter}"`);
|
|
1807
|
+
if (ch.condition) parts.push(`condition = "${ch.condition}"`);
|
|
1808
|
+
if (ch.action) parts.push(`action = "${ch.action}"`);
|
|
1809
|
+
lines.push(` new Choice { ${parts.join(", ")} },`);
|
|
1810
|
+
}
|
|
1811
|
+
lines.push(" },");
|
|
1812
|
+
}
|
|
1813
|
+
lines.push(" };");
|
|
1814
|
+
}
|
|
1815
|
+
lines.push("}");
|
|
1816
|
+
return lines.join("\n");
|
|
1817
|
+
}
|
|
1818
|
+
function narrativeToGodot(narrative) {
|
|
1819
|
+
const lines = [];
|
|
1820
|
+
const safeName = narrative.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
1821
|
+
lines.push(`# StoryWeaver Narrative: ${narrative.name}`);
|
|
1822
|
+
lines.push("extends Node");
|
|
1823
|
+
lines.push(`class_name ${safeName}Narrative`);
|
|
1824
|
+
lines.push("");
|
|
1825
|
+
lines.push("signal chapter_started(chapter_name: String)");
|
|
1826
|
+
lines.push("signal chapter_complete(chapter_name: String)");
|
|
1827
|
+
lines.push("signal dialogue_line(speaker: String, text: String, emotion: String)");
|
|
1828
|
+
lines.push("signal choice_presented(choices: Array)");
|
|
1829
|
+
lines.push("");
|
|
1830
|
+
lines.push(`var narrative_type: String = "${narrative.type}"`);
|
|
1831
|
+
lines.push(
|
|
1832
|
+
`var current_chapter: String = "${narrative.startChapter || narrative.chapters[0]?.name || ""}"`
|
|
1833
|
+
);
|
|
1834
|
+
lines.push("");
|
|
1835
|
+
lines.push("var chapters: Dictionary = {");
|
|
1836
|
+
for (const chapter of narrative.chapters) {
|
|
1837
|
+
const chKey = chapter.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
1838
|
+
lines.push(` "${chKey}": {`);
|
|
1839
|
+
if (chapter.trigger) lines.push(` "trigger": "${chapter.trigger}",`);
|
|
1840
|
+
if (chapter.onComplete) lines.push(` "on_complete": "${chapter.onComplete}",`);
|
|
1841
|
+
if (chapter.dialogueLines && chapter.dialogueLines.length > 0) {
|
|
1842
|
+
lines.push(' "dialogue": [');
|
|
1843
|
+
for (const dl of chapter.dialogueLines) {
|
|
1844
|
+
lines.push(
|
|
1845
|
+
` {"speaker": "${dl.speaker || ""}", "text": "${dl.text}", "emotion": "${dl.emotion || "neutral"}"},`
|
|
1846
|
+
);
|
|
1847
|
+
}
|
|
1848
|
+
lines.push(" ],");
|
|
1849
|
+
}
|
|
1850
|
+
if (chapter.choices && chapter.choices.length > 0) {
|
|
1851
|
+
lines.push(' "choices": [');
|
|
1852
|
+
for (const ch of chapter.choices) {
|
|
1853
|
+
lines.push(` {"text": "${ch.text}", "next": "${ch.nextChapter || ""}"},`);
|
|
1854
|
+
}
|
|
1855
|
+
lines.push(" ],");
|
|
1856
|
+
}
|
|
1857
|
+
lines.push(" },");
|
|
1858
|
+
}
|
|
1859
|
+
lines.push("}");
|
|
1860
|
+
lines.push("");
|
|
1861
|
+
lines.push("func advance_chapter(chapter_name: String) -> void:");
|
|
1862
|
+
lines.push(" current_chapter = chapter_name");
|
|
1863
|
+
lines.push(" chapter_started.emit(chapter_name)");
|
|
1864
|
+
lines.push(" if chapters.has(chapter_name):");
|
|
1865
|
+
lines.push(" var ch = chapters[chapter_name]");
|
|
1866
|
+
lines.push(' if ch.has("dialogue"):');
|
|
1867
|
+
lines.push(' for line in ch["dialogue"]:');
|
|
1868
|
+
lines.push(' dialogue_line.emit(line["speaker"], line["text"], line["emotion"])');
|
|
1869
|
+
lines.push(' if ch.has("choices"):');
|
|
1870
|
+
lines.push(' choice_presented.emit(ch["choices"])');
|
|
1871
|
+
lines.push(' elif ch.has("on_complete"):');
|
|
1872
|
+
lines.push(" chapter_complete.emit(chapter_name)");
|
|
1873
|
+
lines.push(' advance_chapter(ch["on_complete"])');
|
|
1874
|
+
return lines.join("\n");
|
|
1875
|
+
}
|
|
1876
|
+
function narrativeToVRChat(narrative) {
|
|
1877
|
+
const lines = [];
|
|
1878
|
+
const safeName = narrative.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
1879
|
+
lines.push(`// StoryWeaver Narrative: ${narrative.name} (VRChat UdonSharp)`);
|
|
1880
|
+
lines.push("[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]");
|
|
1881
|
+
lines.push(`public class ${safeName}Narrative : UdonSharpBehaviour {`);
|
|
1882
|
+
lines.push(" [UdonSynced] public int currentChapter = 0;");
|
|
1883
|
+
lines.push(
|
|
1884
|
+
` private string[] chapterNames = new string[] { ${narrative.chapters.map((c) => `"${esc(c.name, "CSharp")}"`).join(", ")} };`
|
|
1885
|
+
);
|
|
1886
|
+
lines.push("");
|
|
1887
|
+
for (let i = 0; i < narrative.chapters.length; i++) {
|
|
1888
|
+
const chapter = narrative.chapters[i];
|
|
1889
|
+
if (chapter.trigger) {
|
|
1890
|
+
lines.push(` // Trigger for chapter "${chapter.name}": ${chapter.trigger}`);
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
lines.push("");
|
|
1894
|
+
lines.push(" public void AdvanceChapter() {");
|
|
1895
|
+
lines.push(" if (!Networking.IsOwner(gameObject)) {");
|
|
1896
|
+
lines.push(" Networking.SetOwner(Networking.LocalPlayer, gameObject);");
|
|
1897
|
+
lines.push(" }");
|
|
1898
|
+
lines.push(" currentChapter++;");
|
|
1899
|
+
lines.push(
|
|
1900
|
+
" if (currentChapter >= chapterNames.Length) currentChapter = chapterNames.Length - 1;"
|
|
1901
|
+
);
|
|
1902
|
+
lines.push(" RequestSerialization();");
|
|
1903
|
+
lines.push(" }");
|
|
1904
|
+
lines.push("");
|
|
1905
|
+
lines.push(" public override void OnDeserialization() {");
|
|
1906
|
+
lines.push(" // Sync chapter state across all players");
|
|
1907
|
+
lines.push(" UpdateNarrativeUI();");
|
|
1908
|
+
lines.push(" }");
|
|
1909
|
+
lines.push("");
|
|
1910
|
+
lines.push(" private void UpdateNarrativeUI() {");
|
|
1911
|
+
for (let i = 0; i < narrative.chapters.length; i++) {
|
|
1912
|
+
const chapter = narrative.chapters[i];
|
|
1913
|
+
if (chapter.dialogueLines && chapter.dialogueLines.length > 0) {
|
|
1914
|
+
const dl = chapter.dialogueLines[0];
|
|
1915
|
+
lines.push(` if (currentChapter == ${i}) {`);
|
|
1916
|
+
lines.push(` // ${dl.speaker || "Narrator"}: "${dl.text}"`);
|
|
1917
|
+
lines.push(" }");
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
lines.push(" }");
|
|
1921
|
+
lines.push("}");
|
|
1922
|
+
return lines.join("\n");
|
|
1923
|
+
}
|
|
1924
|
+
function narrativeToR3F(narrative) {
|
|
1925
|
+
const lines = [];
|
|
1926
|
+
const safeName = narrative.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
1927
|
+
lines.push(`// StoryWeaver Narrative: ${narrative.name} (R3F/React)`);
|
|
1928
|
+
lines.push(`export const ${safeName}NarrativeData = {`);
|
|
1929
|
+
lines.push(` name: "${narrative.name}",`);
|
|
1930
|
+
lines.push(` type: "${narrative.type}",`);
|
|
1931
|
+
if (narrative.startChapter) lines.push(` startChapter: "${narrative.startChapter}",`);
|
|
1932
|
+
lines.push(" chapters: [");
|
|
1933
|
+
for (const chapter of narrative.chapters) {
|
|
1934
|
+
lines.push(" {");
|
|
1935
|
+
lines.push(` name: "${chapter.name}",`);
|
|
1936
|
+
if (chapter.trigger) lines.push(` trigger: "${chapter.trigger}",`);
|
|
1937
|
+
if (chapter.onComplete) lines.push(` onComplete: "${chapter.onComplete}",`);
|
|
1938
|
+
if (chapter.dialogueLines && chapter.dialogueLines.length > 0) {
|
|
1939
|
+
lines.push(" dialogueLines: [");
|
|
1940
|
+
for (const dl of chapter.dialogueLines) {
|
|
1941
|
+
const parts = [`text: "${dl.text}"`];
|
|
1942
|
+
if (dl.speaker) parts.push(`speaker: "${dl.speaker}"`);
|
|
1943
|
+
if (dl.emotion) parts.push(`emotion: "${dl.emotion}"`);
|
|
1944
|
+
if (dl.duration) parts.push(`duration: ${dl.duration}`);
|
|
1945
|
+
lines.push(` { ${parts.join(", ")} },`);
|
|
1946
|
+
}
|
|
1947
|
+
lines.push(" ],");
|
|
1948
|
+
}
|
|
1949
|
+
if (chapter.choices && chapter.choices.length > 0) {
|
|
1950
|
+
lines.push(" choices: [");
|
|
1951
|
+
for (const ch of chapter.choices) {
|
|
1952
|
+
const parts = [`text: "${ch.text}"`];
|
|
1953
|
+
if (ch.nextChapter) parts.push(`nextChapter: "${ch.nextChapter}"`);
|
|
1954
|
+
if (ch.condition) parts.push(`condition: "${ch.condition}"`);
|
|
1955
|
+
lines.push(` { ${parts.join(", ")} },`);
|
|
1956
|
+
}
|
|
1957
|
+
lines.push(" ],");
|
|
1958
|
+
}
|
|
1959
|
+
lines.push(" },");
|
|
1960
|
+
}
|
|
1961
|
+
lines.push(" ],");
|
|
1962
|
+
lines.push("};");
|
|
1963
|
+
return lines.join("\n");
|
|
1964
|
+
}
|
|
1965
|
+
function narrativeToUSDA(narrative) {
|
|
1966
|
+
const lines = [];
|
|
1967
|
+
const safeName = narrative.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
1968
|
+
lines.push(`def Scope "Narrative_${safeName}" {`);
|
|
1969
|
+
lines.push(` custom string holoscript:narrativeType = "${narrative.type}"`);
|
|
1970
|
+
if (narrative.startChapter) {
|
|
1971
|
+
lines.push(` custom string holoscript:startChapter = "${narrative.startChapter}"`);
|
|
1972
|
+
}
|
|
1973
|
+
for (const chapter of narrative.chapters) {
|
|
1974
|
+
const chName = chapter.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
1975
|
+
lines.push(` def Scope "Chapter_${chName}" {`);
|
|
1976
|
+
lines.push(` custom string holoscript:chapterName = "${chapter.name}"`);
|
|
1977
|
+
if (chapter.trigger)
|
|
1978
|
+
lines.push(` custom string holoscript:trigger = "${chapter.trigger}"`);
|
|
1979
|
+
if (chapter.onComplete)
|
|
1980
|
+
lines.push(` custom string holoscript:onComplete = "${chapter.onComplete}"`);
|
|
1981
|
+
if (chapter.dialogueLines) {
|
|
1982
|
+
for (let i = 0; i < chapter.dialogueLines.length; i++) {
|
|
1983
|
+
const dl = chapter.dialogueLines[i];
|
|
1984
|
+
lines.push(` def Scope "Dialogue_${i}" {`);
|
|
1985
|
+
lines.push(` custom string holoscript:text = "${dl.text}"`);
|
|
1986
|
+
if (dl.speaker)
|
|
1987
|
+
lines.push(` custom string holoscript:speaker = "${dl.speaker}"`);
|
|
1988
|
+
if (dl.emotion)
|
|
1989
|
+
lines.push(` custom string holoscript:emotion = "${dl.emotion}"`);
|
|
1990
|
+
if (dl.duration)
|
|
1991
|
+
lines.push(` custom float holoscript:duration = ${dl.duration}`);
|
|
1992
|
+
lines.push(" }");
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
if (chapter.choices) {
|
|
1996
|
+
for (let i = 0; i < chapter.choices.length; i++) {
|
|
1997
|
+
const ch = chapter.choices[i];
|
|
1998
|
+
lines.push(` def Scope "Choice_${i}" {`);
|
|
1999
|
+
lines.push(` custom string holoscript:text = "${ch.text}"`);
|
|
2000
|
+
if (ch.nextChapter)
|
|
2001
|
+
lines.push(` custom string holoscript:nextChapter = "${ch.nextChapter}"`);
|
|
2002
|
+
if (ch.condition)
|
|
2003
|
+
lines.push(` custom string holoscript:condition = "${ch.condition}"`);
|
|
2004
|
+
lines.push(" }");
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
if (chapter.cutsceneActions) {
|
|
2008
|
+
for (let i = 0; i < chapter.cutsceneActions.length; i++) {
|
|
2009
|
+
const ca = chapter.cutsceneActions[i];
|
|
2010
|
+
lines.push(` def Scope "CutsceneAction_${i}" {`);
|
|
2011
|
+
lines.push(` custom string holoscript:actionType = "${ca.type}"`);
|
|
2012
|
+
if (ca.target) lines.push(` custom string holoscript:target = "${ca.target}"`);
|
|
2013
|
+
if (ca.duration)
|
|
2014
|
+
lines.push(` custom float holoscript:duration = ${ca.duration}`);
|
|
2015
|
+
lines.push(" }");
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
lines.push(" }");
|
|
2019
|
+
}
|
|
2020
|
+
lines.push("}");
|
|
2021
|
+
return lines.join("\n");
|
|
2022
|
+
}
|
|
2023
|
+
function compilePaymentBlock(block) {
|
|
2024
|
+
const props = block.properties || {};
|
|
2025
|
+
const paywallType = block.keyword === "subscription" ? "subscription" : block.keyword === "tip_jar" ? "tip" : block.keyword === "per_use" || props.per_use ? "per_use" : "one_time";
|
|
2026
|
+
const gatedContent = [];
|
|
2027
|
+
if (props.gated_content && Array.isArray(props.gated_content)) {
|
|
2028
|
+
gatedContent.push(...props.gated_content);
|
|
2029
|
+
} else if (typeof props.gated_content === "string") {
|
|
2030
|
+
gatedContent.push(props.gated_content);
|
|
2031
|
+
}
|
|
2032
|
+
for (const child of block.children || []) {
|
|
2033
|
+
const c = child;
|
|
2034
|
+
if (c.name) gatedContent.push(c.name);
|
|
2035
|
+
}
|
|
2036
|
+
let revenueSplit;
|
|
2037
|
+
if (props.revenue_split && typeof props.revenue_split === "object") {
|
|
2038
|
+
const rs = props.revenue_split;
|
|
2039
|
+
revenueSplit = {
|
|
2040
|
+
creator: rs.creator ?? 80,
|
|
2041
|
+
platform: rs.platform ?? 10,
|
|
2042
|
+
agent: rs.agent ?? 10
|
|
2043
|
+
};
|
|
2044
|
+
}
|
|
2045
|
+
return {
|
|
2046
|
+
name: block.name || "unnamed",
|
|
2047
|
+
price: props.price ?? 0,
|
|
2048
|
+
asset: props.asset ?? "USDC",
|
|
2049
|
+
network: props.network ?? "base",
|
|
2050
|
+
recipient: props.recipient || props.wallet || "",
|
|
2051
|
+
description: props.description || props.message,
|
|
2052
|
+
type: paywallType,
|
|
2053
|
+
gatedContent: gatedContent.length > 0 ? gatedContent : void 0,
|
|
2054
|
+
revenueSplit
|
|
2055
|
+
};
|
|
2056
|
+
}
|
|
2057
|
+
function paymentToUnity(paywall) {
|
|
2058
|
+
const lines = [];
|
|
2059
|
+
const safeName = paywall.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2060
|
+
lines.push(`// x402 Paywall: ${paywall.name}`);
|
|
2061
|
+
lines.push(`[CreateAssetMenu(menuName = "x402/${safeName}")]`);
|
|
2062
|
+
lines.push(`public class ${safeName}Paywall : ScriptableObject {`);
|
|
2063
|
+
lines.push(` public decimal price = ${paywall.price}m;`);
|
|
2064
|
+
lines.push(` public string asset = "${paywall.asset}";`);
|
|
2065
|
+
lines.push(` public string network = "${paywall.network}";`);
|
|
2066
|
+
lines.push(` public string recipientWallet = "${paywall.recipient}";`);
|
|
2067
|
+
lines.push(` public string paywallType = "${paywall.type}";`);
|
|
2068
|
+
if (paywall.description) {
|
|
2069
|
+
lines.push(` public string description = "${paywall.description}";`);
|
|
2070
|
+
}
|
|
2071
|
+
if (paywall.gatedContent && paywall.gatedContent.length > 0) {
|
|
2072
|
+
lines.push(
|
|
2073
|
+
` public string[] gatedObjects = new string[] { ${paywall.gatedContent.map((g) => `"${esc(g, "CSharp")}"`).join(", ")} };`
|
|
2074
|
+
);
|
|
2075
|
+
}
|
|
2076
|
+
if (paywall.revenueSplit) {
|
|
2077
|
+
lines.push(
|
|
2078
|
+
` // Revenue split: ${paywall.revenueSplit.creator}% Creator, ${paywall.revenueSplit.platform}% Platform, ${paywall.revenueSplit.agent}% Agent`
|
|
2079
|
+
);
|
|
2080
|
+
}
|
|
2081
|
+
lines.push("");
|
|
2082
|
+
lines.push(" public bool IsUnlocked { get; private set; }");
|
|
2083
|
+
lines.push("");
|
|
2084
|
+
lines.push(" public async Task<bool> RequestPayment() {");
|
|
2085
|
+
lines.push(" // HTTP 402 payment flow via x402 protocol");
|
|
2086
|
+
lines.push(" var response = await Http.Get(paymentEndpoint);");
|
|
2087
|
+
lines.push(" if (response.StatusCode == 402) {");
|
|
2088
|
+
lines.push(" var challenge = JsonUtility.FromJson<PaymentChallenge>(response.Body);");
|
|
2089
|
+
lines.push(" return await ProcessPayment(challenge);");
|
|
2090
|
+
lines.push(" }");
|
|
2091
|
+
lines.push(" return false;");
|
|
2092
|
+
lines.push(" }");
|
|
2093
|
+
lines.push("}");
|
|
2094
|
+
return lines.join("\n");
|
|
2095
|
+
}
|
|
2096
|
+
function paymentToGodot(paywall) {
|
|
2097
|
+
const lines = [];
|
|
2098
|
+
const safeName = paywall.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2099
|
+
lines.push(`# x402 Paywall: ${paywall.name}`);
|
|
2100
|
+
lines.push("extends Node");
|
|
2101
|
+
lines.push(`class_name ${safeName}Paywall`);
|
|
2102
|
+
lines.push("");
|
|
2103
|
+
lines.push("signal payment_required(price: float, asset: String)");
|
|
2104
|
+
lines.push("signal payment_verified(tx_hash: String)");
|
|
2105
|
+
lines.push("signal access_granted");
|
|
2106
|
+
lines.push("");
|
|
2107
|
+
lines.push(`var price: float = ${paywall.price}`);
|
|
2108
|
+
lines.push(`var asset: String = "${paywall.asset}"`);
|
|
2109
|
+
lines.push(`var network: String = "${paywall.network}"`);
|
|
2110
|
+
lines.push(`var recipient: String = "${paywall.recipient}"`);
|
|
2111
|
+
lines.push(`var paywall_type: String = "${paywall.type}"`);
|
|
2112
|
+
lines.push("var is_unlocked: bool = false");
|
|
2113
|
+
if (paywall.gatedContent && paywall.gatedContent.length > 0) {
|
|
2114
|
+
lines.push(
|
|
2115
|
+
`var gated_objects: Array = [${paywall.gatedContent.map((g) => `"${esc(g, "GDScript")}"`).join(", ")}]`
|
|
2116
|
+
);
|
|
2117
|
+
}
|
|
2118
|
+
lines.push("");
|
|
2119
|
+
lines.push("func request_payment() -> void:");
|
|
2120
|
+
lines.push(" payment_required.emit(price, asset)");
|
|
2121
|
+
lines.push("");
|
|
2122
|
+
lines.push("func verify_payment(tx_hash: String) -> void:");
|
|
2123
|
+
lines.push(" payment_verified.emit(tx_hash)");
|
|
2124
|
+
lines.push(" is_unlocked = true");
|
|
2125
|
+
lines.push(" access_granted.emit()");
|
|
2126
|
+
if (paywall.gatedContent && paywall.gatedContent.length > 0) {
|
|
2127
|
+
lines.push(" for obj_name in gated_objects:");
|
|
2128
|
+
lines.push(" var node = get_node_or_null(obj_name)");
|
|
2129
|
+
lines.push(" if node: node.visible = true");
|
|
2130
|
+
}
|
|
2131
|
+
return lines.join("\n");
|
|
2132
|
+
}
|
|
2133
|
+
function paymentToVRChat(paywall) {
|
|
2134
|
+
const lines = [];
|
|
2135
|
+
const safeName = paywall.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2136
|
+
lines.push(`// x402 Paywall: ${paywall.name} (VRChat UdonSharp)`);
|
|
2137
|
+
lines.push("[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]");
|
|
2138
|
+
lines.push(`public class ${safeName}Paywall : UdonSharpBehaviour {`);
|
|
2139
|
+
lines.push(" [UdonSynced] public bool isUnlocked = false;");
|
|
2140
|
+
lines.push(` public float price = ${paywall.price}f;`);
|
|
2141
|
+
lines.push(` public string asset = "${paywall.asset}";`);
|
|
2142
|
+
lines.push(` public string network = "${paywall.network}";`);
|
|
2143
|
+
lines.push(` public string paymentUrl = "https://hololand.app/pay/${safeName}";`);
|
|
2144
|
+
if (paywall.gatedContent && paywall.gatedContent.length > 0) {
|
|
2145
|
+
lines.push(" public GameObject[] gatedObjects;");
|
|
2146
|
+
}
|
|
2147
|
+
lines.push("");
|
|
2148
|
+
lines.push(" public override void Interact() {");
|
|
2149
|
+
lines.push(" if (!isUnlocked) {");
|
|
2150
|
+
lines.push(" VRCUrl url = new VRCUrl(paymentUrl);");
|
|
2151
|
+
lines.push(" }");
|
|
2152
|
+
lines.push(" }");
|
|
2153
|
+
lines.push("");
|
|
2154
|
+
lines.push(" public void OnPaymentVerified() {");
|
|
2155
|
+
lines.push(" if (!Networking.IsOwner(gameObject)) {");
|
|
2156
|
+
lines.push(" Networking.SetOwner(Networking.LocalPlayer, gameObject);");
|
|
2157
|
+
lines.push(" }");
|
|
2158
|
+
lines.push(" isUnlocked = true;");
|
|
2159
|
+
lines.push(" RequestSerialization();");
|
|
2160
|
+
lines.push(" }");
|
|
2161
|
+
lines.push("");
|
|
2162
|
+
lines.push(" public override void OnDeserialization() {");
|
|
2163
|
+
if (paywall.gatedContent && paywall.gatedContent.length > 0) {
|
|
2164
|
+
lines.push(" foreach (var obj in gatedObjects) {");
|
|
2165
|
+
lines.push(" if (obj != null) obj.SetActive(isUnlocked);");
|
|
2166
|
+
lines.push(" }");
|
|
2167
|
+
}
|
|
2168
|
+
lines.push(" }");
|
|
2169
|
+
lines.push("}");
|
|
2170
|
+
return lines.join("\n");
|
|
2171
|
+
}
|
|
2172
|
+
function paymentToR3F(paywall) {
|
|
2173
|
+
const lines = [];
|
|
2174
|
+
const safeName = paywall.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2175
|
+
lines.push(`// x402 Paywall: ${paywall.name} (R3F/React)`);
|
|
2176
|
+
lines.push(`export const ${safeName}PaywallConfig = {`);
|
|
2177
|
+
lines.push(` name: "${paywall.name}",`);
|
|
2178
|
+
lines.push(` price: ${paywall.price},`);
|
|
2179
|
+
lines.push(` asset: "${paywall.asset}",`);
|
|
2180
|
+
lines.push(` network: "${paywall.network}",`);
|
|
2181
|
+
lines.push(` recipient: "${paywall.recipient}",`);
|
|
2182
|
+
lines.push(` type: "${paywall.type}",`);
|
|
2183
|
+
if (paywall.description) {
|
|
2184
|
+
lines.push(` description: "${paywall.description}",`);
|
|
2185
|
+
}
|
|
2186
|
+
if (paywall.gatedContent && paywall.gatedContent.length > 0) {
|
|
2187
|
+
lines.push(
|
|
2188
|
+
` gatedContent: [${paywall.gatedContent.map((g) => `"${esc(g, "TypeScript")}"`).join(", ")}],`
|
|
2189
|
+
);
|
|
2190
|
+
}
|
|
2191
|
+
if (paywall.revenueSplit) {
|
|
2192
|
+
lines.push(
|
|
2193
|
+
` revenueSplit: { creator: ${paywall.revenueSplit.creator}, platform: ${paywall.revenueSplit.platform}, agent: ${paywall.revenueSplit.agent} },`
|
|
2194
|
+
);
|
|
2195
|
+
}
|
|
2196
|
+
lines.push("};");
|
|
2197
|
+
return lines.join("\n");
|
|
2198
|
+
}
|
|
2199
|
+
function paymentToUSDA(paywall) {
|
|
2200
|
+
const lines = [];
|
|
2201
|
+
const safeName = paywall.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2202
|
+
lines.push(`def Scope "Paywall_${safeName}" {`);
|
|
2203
|
+
lines.push(` custom string holoscript:paywallType = "${paywall.type}"`);
|
|
2204
|
+
lines.push(` custom float holoscript:price = ${paywall.price}`);
|
|
2205
|
+
lines.push(` custom string holoscript:asset = "${paywall.asset}"`);
|
|
2206
|
+
lines.push(` custom string holoscript:network = "${paywall.network}"`);
|
|
2207
|
+
if (paywall.recipient) {
|
|
2208
|
+
lines.push(` custom string holoscript:recipient = "${paywall.recipient}"`);
|
|
2209
|
+
}
|
|
2210
|
+
if (paywall.description) {
|
|
2211
|
+
lines.push(` custom string holoscript:description = "${paywall.description}"`);
|
|
2212
|
+
}
|
|
2213
|
+
if (paywall.gatedContent && paywall.gatedContent.length > 0) {
|
|
2214
|
+
lines.push(
|
|
2215
|
+
` custom string[] holoscript:gatedContent = [${paywall.gatedContent.map((g) => `"${esc(g, "USD")}"`).join(", ")}]`
|
|
2216
|
+
);
|
|
2217
|
+
}
|
|
2218
|
+
if (paywall.revenueSplit) {
|
|
2219
|
+
lines.push(` custom float holoscript:revenueSplitCreator = ${paywall.revenueSplit.creator}`);
|
|
2220
|
+
lines.push(
|
|
2221
|
+
` custom float holoscript:revenueSplitPlatform = ${paywall.revenueSplit.platform}`
|
|
2222
|
+
);
|
|
2223
|
+
lines.push(` custom float holoscript:revenueSplitAgent = ${paywall.revenueSplit.agent}`);
|
|
2224
|
+
}
|
|
2225
|
+
lines.push("}");
|
|
2226
|
+
return lines.join("\n");
|
|
2227
|
+
}
|
|
2228
|
+
function compileHealthcareBlock(block) {
|
|
2229
|
+
const props = block.properties || {};
|
|
2230
|
+
let dicomWindow;
|
|
2231
|
+
if (props.window_center != null || props.window_width != null) {
|
|
2232
|
+
dicomWindow = {
|
|
2233
|
+
center: props.window_center ?? 40,
|
|
2234
|
+
width: props.window_width ?? 400
|
|
2235
|
+
};
|
|
2236
|
+
}
|
|
2237
|
+
let vitalSigns;
|
|
2238
|
+
if (Array.isArray(props.vital_signs)) {
|
|
2239
|
+
vitalSigns = props.vital_signs;
|
|
2240
|
+
} else if (typeof props.vital_signs === "string") {
|
|
2241
|
+
vitalSigns = [props.vital_signs];
|
|
2242
|
+
}
|
|
2243
|
+
let alertThresholds;
|
|
2244
|
+
if (props.alert_thresholds && typeof props.alert_thresholds === "object") {
|
|
2245
|
+
alertThresholds = props.alert_thresholds;
|
|
2246
|
+
}
|
|
2247
|
+
const procedureSteps = [];
|
|
2248
|
+
if (Array.isArray(props.steps)) {
|
|
2249
|
+
procedureSteps.push(...props.steps);
|
|
2250
|
+
}
|
|
2251
|
+
for (const child of block.children || []) {
|
|
2252
|
+
const c = child;
|
|
2253
|
+
if (c.keyword === "step" && c.name) procedureSteps.push(c.name);
|
|
2254
|
+
}
|
|
2255
|
+
let displayFields;
|
|
2256
|
+
if (Array.isArray(props.display_fields)) {
|
|
2257
|
+
displayFields = props.display_fields;
|
|
2258
|
+
}
|
|
2259
|
+
return {
|
|
2260
|
+
name: block.name || "unnamed",
|
|
2261
|
+
keyword: block.keyword,
|
|
2262
|
+
modality: props.modality,
|
|
2263
|
+
bodySystem: props.body_system || props.bodySystem,
|
|
2264
|
+
dicomWindow,
|
|
2265
|
+
vitalSigns,
|
|
2266
|
+
alertThresholds,
|
|
2267
|
+
procedureSteps: procedureSteps.length > 0 ? procedureSteps : void 0,
|
|
2268
|
+
displayFields,
|
|
2269
|
+
traits: block.traits || [],
|
|
2270
|
+
properties: props
|
|
2271
|
+
};
|
|
2272
|
+
}
|
|
2273
|
+
function healthcareToR3F(healthcare) {
|
|
2274
|
+
const safeName = healthcare.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2275
|
+
const lines = [];
|
|
2276
|
+
lines.push(`// Medical: ${healthcare.name} (${healthcare.keyword})`);
|
|
2277
|
+
lines.push(`export const ${safeName}Config = {`);
|
|
2278
|
+
lines.push(` name: "${healthcare.name}",`);
|
|
2279
|
+
lines.push(` type: "${healthcare.keyword}",`);
|
|
2280
|
+
if (healthcare.modality) {
|
|
2281
|
+
lines.push(` modality: "${healthcare.modality}",`);
|
|
2282
|
+
}
|
|
2283
|
+
if (healthcare.bodySystem) {
|
|
2284
|
+
lines.push(` bodySystem: "${healthcare.bodySystem}",`);
|
|
2285
|
+
}
|
|
2286
|
+
if (healthcare.dicomWindow) {
|
|
2287
|
+
lines.push(
|
|
2288
|
+
` dicomWindow: { center: ${healthcare.dicomWindow.center}, width: ${healthcare.dicomWindow.width} },`
|
|
2289
|
+
);
|
|
2290
|
+
}
|
|
2291
|
+
if (healthcare.vitalSigns) {
|
|
2292
|
+
lines.push(
|
|
2293
|
+
` vitalSigns: [${healthcare.vitalSigns.map((v) => `"${esc(v, "TypeScript")}"`).join(", ")}],`
|
|
2294
|
+
);
|
|
2295
|
+
}
|
|
2296
|
+
if (healthcare.alertThresholds) {
|
|
2297
|
+
lines.push(` alertThresholds: ${JSON.stringify(healthcare.alertThresholds)},`);
|
|
2298
|
+
}
|
|
2299
|
+
if (healthcare.procedureSteps) {
|
|
2300
|
+
lines.push(
|
|
2301
|
+
` steps: [${healthcare.procedureSteps.map((s) => `"${esc(s, "TypeScript")}"`).join(", ")}],`
|
|
2302
|
+
);
|
|
2303
|
+
}
|
|
2304
|
+
lines.push("};");
|
|
2305
|
+
return lines.join("\n");
|
|
2306
|
+
}
|
|
2307
|
+
function healthcareToUnity(healthcare) {
|
|
2308
|
+
const safeName = healthcare.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2309
|
+
const lines = [];
|
|
2310
|
+
lines.push(`// Medical: ${healthcare.name}`);
|
|
2311
|
+
lines.push(`public class ${safeName}Medical : MonoBehaviour {`);
|
|
2312
|
+
lines.push(` public string medicalType = "${healthcare.keyword}";`);
|
|
2313
|
+
if (healthcare.modality) {
|
|
2314
|
+
lines.push(` public string modality = "${healthcare.modality}";`);
|
|
2315
|
+
}
|
|
2316
|
+
if (healthcare.bodySystem) {
|
|
2317
|
+
lines.push(` public string bodySystem = "${healthcare.bodySystem}";`);
|
|
2318
|
+
}
|
|
2319
|
+
if (healthcare.dicomWindow) {
|
|
2320
|
+
lines.push(` public float windowCenter = ${healthcare.dicomWindow.center}f;`);
|
|
2321
|
+
lines.push(` public float windowWidth = ${healthcare.dicomWindow.width}f;`);
|
|
2322
|
+
}
|
|
2323
|
+
if (healthcare.vitalSigns) {
|
|
2324
|
+
lines.push(
|
|
2325
|
+
` public string[] vitalSigns = new string[] { ${healthcare.vitalSigns.map((v) => `"${esc(v, "CSharp")}"`).join(", ")} };`
|
|
2326
|
+
);
|
|
2327
|
+
}
|
|
2328
|
+
if (healthcare.procedureSteps) {
|
|
2329
|
+
lines.push(
|
|
2330
|
+
` public string[] procedureSteps = new string[] { ${healthcare.procedureSteps.map((s) => `"${esc(s, "CSharp")}"`).join(", ")} };`
|
|
2331
|
+
);
|
|
2332
|
+
}
|
|
2333
|
+
lines.push("");
|
|
2334
|
+
if (healthcare.dicomWindow) {
|
|
2335
|
+
lines.push(" // DICOM window-leveling shader uniforms");
|
|
2336
|
+
lines.push(" void Start() {");
|
|
2337
|
+
lines.push(" var renderer = GetComponent<Renderer>();");
|
|
2338
|
+
lines.push(" if (renderer != null) {");
|
|
2339
|
+
lines.push(
|
|
2340
|
+
` renderer.material.SetFloat("_WindowCenter", ${healthcare.dicomWindow.center}f);`
|
|
2341
|
+
);
|
|
2342
|
+
lines.push(
|
|
2343
|
+
` renderer.material.SetFloat("_WindowWidth", ${healthcare.dicomWindow.width}f);`
|
|
2344
|
+
);
|
|
2345
|
+
lines.push(" }");
|
|
2346
|
+
lines.push(" }");
|
|
2347
|
+
}
|
|
2348
|
+
lines.push("}");
|
|
2349
|
+
return lines.join("\n");
|
|
2350
|
+
}
|
|
2351
|
+
function healthcareToGodot(healthcare) {
|
|
2352
|
+
const lines = [];
|
|
2353
|
+
lines.push(`# Medical: ${healthcare.name}`);
|
|
2354
|
+
lines.push("extends Node3D");
|
|
2355
|
+
lines.push("");
|
|
2356
|
+
lines.push(`@export var medical_type: String = "${healthcare.keyword}"`);
|
|
2357
|
+
if (healthcare.modality) {
|
|
2358
|
+
lines.push(`@export var modality: String = "${healthcare.modality}"`);
|
|
2359
|
+
}
|
|
2360
|
+
if (healthcare.bodySystem) {
|
|
2361
|
+
lines.push(`@export var body_system: String = "${healthcare.bodySystem}"`);
|
|
2362
|
+
}
|
|
2363
|
+
if (healthcare.dicomWindow) {
|
|
2364
|
+
lines.push(`@export var window_center: float = ${healthcare.dicomWindow.center}`);
|
|
2365
|
+
lines.push(`@export var window_width: float = ${healthcare.dicomWindow.width}`);
|
|
2366
|
+
}
|
|
2367
|
+
if (healthcare.vitalSigns) {
|
|
2368
|
+
lines.push(
|
|
2369
|
+
`@export var vital_signs: PackedStringArray = [${healthcare.vitalSigns.map((v) => `"${esc(v, "GDScript")}"`).join(", ")}]`
|
|
2370
|
+
);
|
|
2371
|
+
}
|
|
2372
|
+
if (healthcare.dicomWindow) {
|
|
2373
|
+
lines.push("");
|
|
2374
|
+
lines.push("signal window_level_changed(center: float, width: float)");
|
|
2375
|
+
lines.push("");
|
|
2376
|
+
lines.push("func set_window_level(center: float, width: float) -> void:");
|
|
2377
|
+
lines.push(" window_center = center");
|
|
2378
|
+
lines.push(" window_width = width");
|
|
2379
|
+
lines.push(' var mat = get_node("MeshInstance3D").get_surface_override_material(0)');
|
|
2380
|
+
lines.push(" if mat:");
|
|
2381
|
+
lines.push(' mat.set_shader_parameter("window_center", center)');
|
|
2382
|
+
lines.push(' mat.set_shader_parameter("window_width", width)');
|
|
2383
|
+
lines.push(" window_level_changed.emit(center, width)");
|
|
2384
|
+
}
|
|
2385
|
+
return lines.join("\n");
|
|
2386
|
+
}
|
|
2387
|
+
function healthcareToVRChat(healthcare) {
|
|
2388
|
+
const safeName = healthcare.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2389
|
+
const lines = [];
|
|
2390
|
+
lines.push(`// Medical: ${healthcare.name}`);
|
|
2391
|
+
lines.push(`[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]`);
|
|
2392
|
+
lines.push(`public class ${safeName}Medical : UdonSharpBehaviour {`);
|
|
2393
|
+
lines.push(` public string medicalType = "${healthcare.keyword}";`);
|
|
2394
|
+
if (healthcare.vitalSigns) {
|
|
2395
|
+
lines.push(` [UdonSynced] public string vitalData = "";`);
|
|
2396
|
+
}
|
|
2397
|
+
if (healthcare.dicomWindow) {
|
|
2398
|
+
lines.push(` [UdonSynced] public float windowCenter = ${healthcare.dicomWindow.center}f;`);
|
|
2399
|
+
lines.push(` [UdonSynced] public float windowWidth = ${healthcare.dicomWindow.width}f;`);
|
|
2400
|
+
}
|
|
2401
|
+
lines.push("}");
|
|
2402
|
+
return lines.join("\n");
|
|
2403
|
+
}
|
|
2404
|
+
function healthcareToUSDA(healthcare) {
|
|
2405
|
+
const safeName = healthcare.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2406
|
+
const lines = [];
|
|
2407
|
+
lines.push(`def Scope "Medical_${safeName}" {`);
|
|
2408
|
+
lines.push(` custom string holoscript:medicalType = "${healthcare.keyword}"`);
|
|
2409
|
+
if (healthcare.modality) {
|
|
2410
|
+
lines.push(` custom string holoscript:modality = "${healthcare.modality}"`);
|
|
2411
|
+
}
|
|
2412
|
+
if (healthcare.bodySystem) {
|
|
2413
|
+
lines.push(` custom string holoscript:bodySystem = "${healthcare.bodySystem}"`);
|
|
2414
|
+
}
|
|
2415
|
+
if (healthcare.dicomWindow) {
|
|
2416
|
+
lines.push(` custom float holoscript:dicomWindowCenter = ${healthcare.dicomWindow.center}`);
|
|
2417
|
+
lines.push(` custom float holoscript:dicomWindowWidth = ${healthcare.dicomWindow.width}`);
|
|
2418
|
+
}
|
|
2419
|
+
lines.push("}");
|
|
2420
|
+
return lines.join("\n");
|
|
2421
|
+
}
|
|
2422
|
+
function compileRoboticsBlock(block) {
|
|
2423
|
+
const props = block.properties || {};
|
|
2424
|
+
let jointLimits;
|
|
2425
|
+
if (props.lower != null || props.upper != null || props.effort != null || props.velocity != null) {
|
|
2426
|
+
jointLimits = {
|
|
2427
|
+
lower: props.lower ?? -3.14159,
|
|
2428
|
+
upper: props.upper ?? 3.14159,
|
|
2429
|
+
effort: props.effort ?? 100,
|
|
2430
|
+
velocity: props.velocity ?? 1
|
|
2431
|
+
};
|
|
2432
|
+
} else if (props.limits && typeof props.limits === "object") {
|
|
2433
|
+
const lim = props.limits;
|
|
2434
|
+
jointLimits = {
|
|
2435
|
+
lower: lim.lower ?? -3.14159,
|
|
2436
|
+
upper: lim.upper ?? 3.14159,
|
|
2437
|
+
effort: lim.effort ?? 100,
|
|
2438
|
+
velocity: lim.velocity ?? 1
|
|
2439
|
+
};
|
|
2440
|
+
}
|
|
2441
|
+
let ros2;
|
|
2442
|
+
if (props.ros2_package || props.ros2_node || props.ros2_topic) {
|
|
2443
|
+
ros2 = {
|
|
2444
|
+
packageName: props.ros2_package,
|
|
2445
|
+
nodeType: props.ros2_node,
|
|
2446
|
+
topicName: props.ros2_topic
|
|
2447
|
+
};
|
|
2448
|
+
}
|
|
2449
|
+
return {
|
|
2450
|
+
name: block.name || "unnamed",
|
|
2451
|
+
keyword: block.keyword,
|
|
2452
|
+
jointType: props.joint_type || props.type,
|
|
2453
|
+
jointLimits,
|
|
2454
|
+
driveType: props.drive_type || props.drive,
|
|
2455
|
+
controllerType: props.controller_type || props.controller,
|
|
2456
|
+
effectorType: props.effector_type || props.effector,
|
|
2457
|
+
sensorType: props.sensor_type || props.sensor,
|
|
2458
|
+
ros2,
|
|
2459
|
+
safetyRating: props.safety_rating || props.safety,
|
|
2460
|
+
traits: block.traits || [],
|
|
2461
|
+
properties: props
|
|
2462
|
+
};
|
|
2463
|
+
}
|
|
2464
|
+
function roboticsToR3F(robotics) {
|
|
2465
|
+
const safeName = robotics.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2466
|
+
const lines = [];
|
|
2467
|
+
lines.push(`// Robotics: ${robotics.name} (${robotics.keyword})`);
|
|
2468
|
+
lines.push(`export const ${safeName}Config = {`);
|
|
2469
|
+
lines.push(` name: "${robotics.name}",`);
|
|
2470
|
+
lines.push(` type: "${robotics.keyword}",`);
|
|
2471
|
+
if (robotics.jointType) {
|
|
2472
|
+
lines.push(` jointType: "${robotics.jointType}",`);
|
|
2473
|
+
}
|
|
2474
|
+
if (robotics.jointLimits) {
|
|
2475
|
+
lines.push(
|
|
2476
|
+
` jointLimits: { lower: ${robotics.jointLimits.lower}, upper: ${robotics.jointLimits.upper}, effort: ${robotics.jointLimits.effort}, velocity: ${robotics.jointLimits.velocity} },`
|
|
2477
|
+
);
|
|
2478
|
+
}
|
|
2479
|
+
if (robotics.driveType) {
|
|
2480
|
+
lines.push(` driveType: "${robotics.driveType}",`);
|
|
2481
|
+
}
|
|
2482
|
+
if (robotics.controllerType) {
|
|
2483
|
+
lines.push(` controllerType: "${robotics.controllerType}",`);
|
|
2484
|
+
}
|
|
2485
|
+
if (robotics.effectorType) {
|
|
2486
|
+
lines.push(` effectorType: "${robotics.effectorType}",`);
|
|
2487
|
+
}
|
|
2488
|
+
if (robotics.sensorType) {
|
|
2489
|
+
lines.push(` sensorType: "${robotics.sensorType}",`);
|
|
2490
|
+
}
|
|
2491
|
+
if (robotics.safetyRating) {
|
|
2492
|
+
lines.push(` safetyRating: "${robotics.safetyRating}",`);
|
|
2493
|
+
}
|
|
2494
|
+
lines.push("};");
|
|
2495
|
+
return lines.join("\n");
|
|
2496
|
+
}
|
|
2497
|
+
function roboticsToUnity(robotics) {
|
|
2498
|
+
const safeName = robotics.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2499
|
+
const lines = [];
|
|
2500
|
+
lines.push(`// Robotics: ${robotics.name}`);
|
|
2501
|
+
lines.push(`public class ${safeName}Robotics : MonoBehaviour {`);
|
|
2502
|
+
lines.push(` public string roboticsType = "${robotics.keyword}";`);
|
|
2503
|
+
if (robotics.jointType) {
|
|
2504
|
+
lines.push(
|
|
2505
|
+
` public ArticulationJointType jointType = ArticulationJointType.${capitalizeFirst(robotics.jointType)};`
|
|
2506
|
+
);
|
|
2507
|
+
}
|
|
2508
|
+
if (robotics.jointLimits) {
|
|
2509
|
+
lines.push(` public float lowerLimit = ${robotics.jointLimits.lower}f;`);
|
|
2510
|
+
lines.push(` public float upperLimit = ${robotics.jointLimits.upper}f;`);
|
|
2511
|
+
lines.push(` public float effortLimit = ${robotics.jointLimits.effort}f;`);
|
|
2512
|
+
lines.push(` public float velocityLimit = ${robotics.jointLimits.velocity}f;`);
|
|
2513
|
+
}
|
|
2514
|
+
if (robotics.driveType) {
|
|
2515
|
+
lines.push(` public string driveType = "${robotics.driveType}";`);
|
|
2516
|
+
}
|
|
2517
|
+
if (robotics.controllerType) {
|
|
2518
|
+
lines.push(` public string controllerType = "${robotics.controllerType}";`);
|
|
2519
|
+
}
|
|
2520
|
+
if (robotics.safetyRating) {
|
|
2521
|
+
lines.push(` public string safetyRating = "${robotics.safetyRating}";`);
|
|
2522
|
+
}
|
|
2523
|
+
lines.push("");
|
|
2524
|
+
if (robotics.jointLimits) {
|
|
2525
|
+
lines.push(" void Start() {");
|
|
2526
|
+
lines.push(" var body = GetComponent<ArticulationBody>();");
|
|
2527
|
+
lines.push(" if (body != null) {");
|
|
2528
|
+
lines.push(" var drive = body.xDrive;");
|
|
2529
|
+
lines.push(` drive.lowerLimit = ${robotics.jointLimits.lower}f * Mathf.Rad2Deg;`);
|
|
2530
|
+
lines.push(` drive.upperLimit = ${robotics.jointLimits.upper}f * Mathf.Rad2Deg;`);
|
|
2531
|
+
lines.push(` drive.forceLimit = ${robotics.jointLimits.effort}f;`);
|
|
2532
|
+
lines.push(" body.xDrive = drive;");
|
|
2533
|
+
lines.push(" }");
|
|
2534
|
+
lines.push(" }");
|
|
2535
|
+
}
|
|
2536
|
+
lines.push("}");
|
|
2537
|
+
return lines.join("\n");
|
|
2538
|
+
}
|
|
2539
|
+
function roboticsToGodot(robotics) {
|
|
2540
|
+
const lines = [];
|
|
2541
|
+
lines.push(`# Robotics: ${robotics.name}`);
|
|
2542
|
+
lines.push("extends Node3D");
|
|
2543
|
+
lines.push("");
|
|
2544
|
+
lines.push(`@export var robotics_type: String = "${robotics.keyword}"`);
|
|
2545
|
+
if (robotics.jointType) {
|
|
2546
|
+
lines.push(`@export var joint_type: String = "${robotics.jointType}"`);
|
|
2547
|
+
}
|
|
2548
|
+
if (robotics.jointLimits) {
|
|
2549
|
+
lines.push(`@export var lower_limit: float = ${robotics.jointLimits.lower}`);
|
|
2550
|
+
lines.push(`@export var upper_limit: float = ${robotics.jointLimits.upper}`);
|
|
2551
|
+
lines.push(`@export var effort_limit: float = ${robotics.jointLimits.effort}`);
|
|
2552
|
+
lines.push(`@export var velocity_limit: float = ${robotics.jointLimits.velocity}`);
|
|
2553
|
+
}
|
|
2554
|
+
if (robotics.driveType) {
|
|
2555
|
+
lines.push(`@export var drive_type: String = "${robotics.driveType}"`);
|
|
2556
|
+
}
|
|
2557
|
+
if (robotics.controllerType) {
|
|
2558
|
+
lines.push(`@export var controller_type: String = "${robotics.controllerType}"`);
|
|
2559
|
+
}
|
|
2560
|
+
if (robotics.safetyRating) {
|
|
2561
|
+
lines.push(`@export var safety_rating: String = "${robotics.safetyRating}"`);
|
|
2562
|
+
}
|
|
2563
|
+
if (robotics.jointType === "revolute" || robotics.jointType === "continuous") {
|
|
2564
|
+
lines.push("");
|
|
2565
|
+
lines.push("signal joint_position_changed(angle_rad: float)");
|
|
2566
|
+
lines.push("");
|
|
2567
|
+
lines.push("var current_angle: float = 0.0");
|
|
2568
|
+
lines.push("");
|
|
2569
|
+
lines.push("func set_joint_angle(angle: float) -> void:");
|
|
2570
|
+
if (robotics.jointLimits) {
|
|
2571
|
+
lines.push(
|
|
2572
|
+
` angle = clampf(angle, ${robotics.jointLimits.lower}, ${robotics.jointLimits.upper})`
|
|
2573
|
+
);
|
|
2574
|
+
}
|
|
2575
|
+
lines.push(" current_angle = angle");
|
|
2576
|
+
lines.push(" rotation[0] = angle");
|
|
2577
|
+
lines.push(" joint_position_changed.emit(angle)");
|
|
2578
|
+
}
|
|
2579
|
+
return lines.join("\n");
|
|
2580
|
+
}
|
|
2581
|
+
function roboticsToVRChat(robotics) {
|
|
2582
|
+
const safeName = robotics.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2583
|
+
const lines = [];
|
|
2584
|
+
lines.push(`// Robotics: ${robotics.name}`);
|
|
2585
|
+
lines.push(`[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]`);
|
|
2586
|
+
lines.push(`public class ${safeName}Robotics : UdonSharpBehaviour {`);
|
|
2587
|
+
lines.push(` public string roboticsType = "${robotics.keyword}";`);
|
|
2588
|
+
if (robotics.jointType) {
|
|
2589
|
+
lines.push(` public string jointType = "${robotics.jointType}";`);
|
|
2590
|
+
}
|
|
2591
|
+
if (robotics.jointLimits) {
|
|
2592
|
+
lines.push(` [UdonSynced] public float jointAngle = 0f;`);
|
|
2593
|
+
lines.push(` public float lowerLimit = ${robotics.jointLimits.lower}f;`);
|
|
2594
|
+
lines.push(` public float upperLimit = ${robotics.jointLimits.upper}f;`);
|
|
2595
|
+
}
|
|
2596
|
+
if (robotics.safetyRating) {
|
|
2597
|
+
lines.push(` public string safetyRating = "${robotics.safetyRating}";`);
|
|
2598
|
+
}
|
|
2599
|
+
lines.push("}");
|
|
2600
|
+
return lines.join("\n");
|
|
2601
|
+
}
|
|
2602
|
+
function roboticsToUSDA(robotics) {
|
|
2603
|
+
const safeName = robotics.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2604
|
+
const lines = [];
|
|
2605
|
+
lines.push(`def Scope "Robotics_${safeName}" {`);
|
|
2606
|
+
lines.push(` custom string holoscript:roboticsType = "${robotics.keyword}"`);
|
|
2607
|
+
if (robotics.jointType) {
|
|
2608
|
+
lines.push(` custom string holoscript:jointType = "${robotics.jointType}"`);
|
|
2609
|
+
}
|
|
2610
|
+
if (robotics.jointLimits) {
|
|
2611
|
+
lines.push(` custom float holoscript:jointLower = ${robotics.jointLimits.lower}`);
|
|
2612
|
+
lines.push(` custom float holoscript:jointUpper = ${robotics.jointLimits.upper}`);
|
|
2613
|
+
lines.push(` custom float holoscript:jointEffort = ${robotics.jointLimits.effort}`);
|
|
2614
|
+
lines.push(` custom float holoscript:jointVelocity = ${robotics.jointLimits.velocity}`);
|
|
2615
|
+
}
|
|
2616
|
+
if (robotics.driveType) {
|
|
2617
|
+
lines.push(` custom string holoscript:driveType = "${robotics.driveType}"`);
|
|
2618
|
+
}
|
|
2619
|
+
if (robotics.safetyRating) {
|
|
2620
|
+
lines.push(` custom string holoscript:safetyRating = "${robotics.safetyRating}"`);
|
|
2621
|
+
}
|
|
2622
|
+
lines.push("}");
|
|
2623
|
+
return lines.join("\n");
|
|
2624
|
+
}
|
|
2625
|
+
function compileIoTBlock(block) {
|
|
2626
|
+
const props = block.properties || {};
|
|
2627
|
+
let telemetryFields;
|
|
2628
|
+
if (Array.isArray(props.telemetry_fields)) {
|
|
2629
|
+
telemetryFields = props.telemetry_fields;
|
|
2630
|
+
} else if (typeof props.telemetry_fields === "string") {
|
|
2631
|
+
telemetryFields = [props.telemetry_fields];
|
|
2632
|
+
}
|
|
2633
|
+
let bindings;
|
|
2634
|
+
if (props.bindings && typeof props.bindings === "object") {
|
|
2635
|
+
bindings = props.bindings;
|
|
2636
|
+
}
|
|
2637
|
+
return {
|
|
2638
|
+
name: block.name || "unnamed",
|
|
2639
|
+
keyword: block.keyword,
|
|
2640
|
+
deviceType: props.device_type || props.type,
|
|
2641
|
+
protocol: props.protocol,
|
|
2642
|
+
telemetryFields,
|
|
2643
|
+
updateInterval: props.update_interval,
|
|
2644
|
+
twinModel: props.twin_model || props.model,
|
|
2645
|
+
bindings,
|
|
2646
|
+
traits: block.traits || [],
|
|
2647
|
+
properties: props
|
|
2648
|
+
};
|
|
2649
|
+
}
|
|
2650
|
+
function iotToR3F(iot) {
|
|
2651
|
+
const safeName = iot.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2652
|
+
const lines = [];
|
|
2653
|
+
lines.push(`// IoT: ${iot.name} (${iot.keyword})`);
|
|
2654
|
+
lines.push(`export const ${safeName}Config = {`);
|
|
2655
|
+
lines.push(` name: "${iot.name}",`);
|
|
2656
|
+
lines.push(` type: "${iot.keyword}",`);
|
|
2657
|
+
if (iot.deviceType) lines.push(` deviceType: "${iot.deviceType}",`);
|
|
2658
|
+
if (iot.protocol) lines.push(` protocol: "${esc(iot.protocol, "TypeScript")}",`);
|
|
2659
|
+
if (iot.telemetryFields)
|
|
2660
|
+
lines.push(
|
|
2661
|
+
` telemetryFields: [${iot.telemetryFields.map((f) => `"${esc(f, "TypeScript")}"`).join(", ")}],`
|
|
2662
|
+
);
|
|
2663
|
+
if (iot.updateInterval) lines.push(` updateInterval: ${iot.updateInterval},`);
|
|
2664
|
+
if (iot.twinModel) lines.push(` twinModel: "${esc(iot.twinModel, "TypeScript")}",`);
|
|
2665
|
+
lines.push("};");
|
|
2666
|
+
return lines.join("\n");
|
|
2667
|
+
}
|
|
2668
|
+
function iotToUnity(iot) {
|
|
2669
|
+
const safeName = iot.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2670
|
+
const lines = [];
|
|
2671
|
+
lines.push(`// IoT: ${iot.name}`);
|
|
2672
|
+
lines.push(`public class ${safeName}IoT : MonoBehaviour {`);
|
|
2673
|
+
lines.push(` public string deviceType = "${esc(iot.keyword, "CSharp")}";`);
|
|
2674
|
+
if (iot.protocol) lines.push(` public string protocol = "${esc(iot.protocol, "CSharp")}";`);
|
|
2675
|
+
if (iot.updateInterval)
|
|
2676
|
+
lines.push(` public float updateInterval = ${iot.updateInterval / 1e3}f;`);
|
|
2677
|
+
if (iot.telemetryFields)
|
|
2678
|
+
lines.push(
|
|
2679
|
+
` public string[] telemetryFields = new string[] { ${iot.telemetryFields.map((f) => `"${esc(f, "CSharp")}"`).join(", ")} };`
|
|
2680
|
+
);
|
|
2681
|
+
if (iot.twinModel) lines.push(` public string twinModel = "${esc(iot.twinModel, "CSharp")}";`);
|
|
2682
|
+
lines.push("}");
|
|
2683
|
+
return lines.join("\n");
|
|
2684
|
+
}
|
|
2685
|
+
function iotToGodot(iot) {
|
|
2686
|
+
const lines = [];
|
|
2687
|
+
lines.push(`# IoT: ${iot.name}`);
|
|
2688
|
+
lines.push("extends Node");
|
|
2689
|
+
lines.push("");
|
|
2690
|
+
lines.push(`@export var device_type: String = "${esc(iot.keyword, "GDScript")}"`);
|
|
2691
|
+
if (iot.protocol) lines.push(`@export var protocol: String = "${esc(iot.protocol, "GDScript")}"`);
|
|
2692
|
+
if (iot.updateInterval)
|
|
2693
|
+
lines.push(`@export var update_interval: float = ${iot.updateInterval / 1e3}`);
|
|
2694
|
+
if (iot.telemetryFields)
|
|
2695
|
+
lines.push(
|
|
2696
|
+
`@export var telemetry_fields: PackedStringArray = [${iot.telemetryFields.map((f) => `"${esc(f, "GDScript")}"`).join(", ")}]`
|
|
2697
|
+
);
|
|
2698
|
+
if (iot.twinModel)
|
|
2699
|
+
lines.push(`@export var twin_model: String = "${esc(iot.twinModel, "GDScript")}"`);
|
|
2700
|
+
lines.push("");
|
|
2701
|
+
lines.push("signal telemetry_received(field: String, value: float)");
|
|
2702
|
+
lines.push("signal connection_changed(connected: bool)");
|
|
2703
|
+
return lines.join("\n");
|
|
2704
|
+
}
|
|
2705
|
+
function iotToVRChat(iot) {
|
|
2706
|
+
const safeName = iot.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2707
|
+
const lines = [];
|
|
2708
|
+
lines.push(`// IoT: ${iot.name}`);
|
|
2709
|
+
lines.push("[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]");
|
|
2710
|
+
lines.push(`public class ${safeName}IoT : UdonSharpBehaviour {`);
|
|
2711
|
+
lines.push(` public string deviceType = "${iot.keyword}";`);
|
|
2712
|
+
if (iot.telemetryFields) lines.push(` [UdonSynced] public string telemetryData = "";`);
|
|
2713
|
+
if (iot.updateInterval)
|
|
2714
|
+
lines.push(` public float updateInterval = ${iot.updateInterval / 1e3}f;`);
|
|
2715
|
+
lines.push("}");
|
|
2716
|
+
return lines.join("\n");
|
|
2717
|
+
}
|
|
2718
|
+
function iotToUSDA(iot) {
|
|
2719
|
+
const safeName = iot.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2720
|
+
const lines = [];
|
|
2721
|
+
lines.push(`def Scope "IoT_${safeName}" {`);
|
|
2722
|
+
lines.push(` custom string holoscript:deviceType = "${iot.keyword}"`);
|
|
2723
|
+
if (iot.protocol) lines.push(` custom string holoscript:protocol = "${iot.protocol}"`);
|
|
2724
|
+
if (iot.updateInterval)
|
|
2725
|
+
lines.push(` custom float holoscript:updateInterval = ${iot.updateInterval}`);
|
|
2726
|
+
if (iot.twinModel) lines.push(` custom string holoscript:twinModel = "${iot.twinModel}"`);
|
|
2727
|
+
lines.push("}");
|
|
2728
|
+
return lines.join("\n");
|
|
2729
|
+
}
|
|
2730
|
+
function compileDataVizBlock(block) {
|
|
2731
|
+
const props = block.properties || {};
|
|
2732
|
+
let axes;
|
|
2733
|
+
if (props.x_axis || props.y_axis || props.z_axis) {
|
|
2734
|
+
axes = [
|
|
2735
|
+
String(props.x_axis ?? ""),
|
|
2736
|
+
String(props.y_axis ?? ""),
|
|
2737
|
+
String(props.z_axis ?? "")
|
|
2738
|
+
];
|
|
2739
|
+
} else if (props.axes && typeof props.axes === "object") {
|
|
2740
|
+
const a = props.axes;
|
|
2741
|
+
axes = [
|
|
2742
|
+
String(a[0] ?? ""),
|
|
2743
|
+
String(a[1] ?? ""),
|
|
2744
|
+
String(a[2] ?? "")
|
|
2745
|
+
];
|
|
2746
|
+
}
|
|
2747
|
+
let dimensions;
|
|
2748
|
+
if (props.width != null || props.height != null) {
|
|
2749
|
+
dimensions = { width: props.width ?? 400, height: props.height ?? 300 };
|
|
2750
|
+
}
|
|
2751
|
+
return {
|
|
2752
|
+
name: block.name || "unnamed",
|
|
2753
|
+
keyword: block.keyword,
|
|
2754
|
+
chartType: props.chart_type || props.type,
|
|
2755
|
+
dataSource: props.data_source || props.source,
|
|
2756
|
+
axes,
|
|
2757
|
+
aggregation: props.aggregation,
|
|
2758
|
+
refreshInterval: props.refresh_interval,
|
|
2759
|
+
dimensions,
|
|
2760
|
+
traits: block.traits || [],
|
|
2761
|
+
properties: props
|
|
2762
|
+
};
|
|
2763
|
+
}
|
|
2764
|
+
function datavizToR3F(dv) {
|
|
2765
|
+
const safeName = dv.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2766
|
+
const lines = [];
|
|
2767
|
+
lines.push(`// DataViz: ${dv.name} (${dv.keyword})`);
|
|
2768
|
+
lines.push(`export const ${safeName}Config = {`);
|
|
2769
|
+
lines.push(` name: "${dv.name}",`);
|
|
2770
|
+
lines.push(` type: "${dv.keyword}",`);
|
|
2771
|
+
if (dv.chartType) lines.push(` chartType: "${dv.chartType}",`);
|
|
2772
|
+
if (dv.dataSource) lines.push(` dataSource: "${dv.dataSource}",`);
|
|
2773
|
+
if (dv.axes) lines.push(` axes: ${JSON.stringify(dv.axes)},`);
|
|
2774
|
+
if (dv.aggregation) lines.push(` aggregation: "${dv.aggregation}",`);
|
|
2775
|
+
if (dv.refreshInterval) lines.push(` refreshInterval: ${dv.refreshInterval},`);
|
|
2776
|
+
if (dv.dimensions)
|
|
2777
|
+
lines.push(` dimensions: { width: ${dv.dimensions.width}, height: ${dv.dimensions.height} },`);
|
|
2778
|
+
lines.push("};");
|
|
2779
|
+
return lines.join("\n");
|
|
2780
|
+
}
|
|
2781
|
+
function datavizToUnity(dv) {
|
|
2782
|
+
const safeName = dv.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2783
|
+
const lines = [];
|
|
2784
|
+
lines.push(`// DataViz: ${dv.name}`);
|
|
2785
|
+
lines.push(`public class ${safeName}DataViz : MonoBehaviour {`);
|
|
2786
|
+
lines.push(` public string vizType = "${dv.keyword}";`);
|
|
2787
|
+
if (dv.chartType) lines.push(` public string chartType = "${dv.chartType}";`);
|
|
2788
|
+
if (dv.dataSource) lines.push(` public string dataSource = "${dv.dataSource}";`);
|
|
2789
|
+
if (dv.refreshInterval)
|
|
2790
|
+
lines.push(` public float refreshInterval = ${dv.refreshInterval / 1e3}f;`);
|
|
2791
|
+
if (dv.dimensions) {
|
|
2792
|
+
lines.push(` public float width = ${dv.dimensions.width}f;`);
|
|
2793
|
+
lines.push(` public float height = ${dv.dimensions.height}f;`);
|
|
2794
|
+
}
|
|
2795
|
+
lines.push("}");
|
|
2796
|
+
return lines.join("\n");
|
|
2797
|
+
}
|
|
2798
|
+
function datavizToGodot(dv) {
|
|
2799
|
+
const lines = [];
|
|
2800
|
+
lines.push(`# DataViz: ${dv.name}`);
|
|
2801
|
+
lines.push("extends Control");
|
|
2802
|
+
lines.push("");
|
|
2803
|
+
lines.push(`@export var viz_type: String = "${dv.keyword}"`);
|
|
2804
|
+
if (dv.chartType) lines.push(`@export var chart_type: String = "${dv.chartType}"`);
|
|
2805
|
+
if (dv.dataSource) lines.push(`@export var data_source: String = "${dv.dataSource}"`);
|
|
2806
|
+
if (dv.refreshInterval)
|
|
2807
|
+
lines.push(`@export var refresh_interval: float = ${dv.refreshInterval / 1e3}`);
|
|
2808
|
+
if (dv.dimensions) {
|
|
2809
|
+
lines.push(`@export var chart_width: float = ${dv.dimensions.width}`);
|
|
2810
|
+
lines.push(`@export var chart_height: float = ${dv.dimensions.height}`);
|
|
2811
|
+
}
|
|
2812
|
+
lines.push("");
|
|
2813
|
+
lines.push("signal data_updated(values: Array)");
|
|
2814
|
+
return lines.join("\n");
|
|
2815
|
+
}
|
|
2816
|
+
function datavizToVRChat(dv) {
|
|
2817
|
+
const safeName = dv.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2818
|
+
const lines = [];
|
|
2819
|
+
lines.push(`// DataViz: ${dv.name}`);
|
|
2820
|
+
lines.push("[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]");
|
|
2821
|
+
lines.push(`public class ${safeName}DataViz : UdonSharpBehaviour {`);
|
|
2822
|
+
lines.push(` public string vizType = "${dv.keyword}";`);
|
|
2823
|
+
if (dv.chartType) lines.push(` public string chartType = "${dv.chartType}";`);
|
|
2824
|
+
if (dv.dataSource) lines.push(` [UdonSynced] public string dataJson = "";`);
|
|
2825
|
+
lines.push("}");
|
|
2826
|
+
return lines.join("\n");
|
|
2827
|
+
}
|
|
2828
|
+
function datavizToUSDA(dv) {
|
|
2829
|
+
const safeName = dv.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2830
|
+
const lines = [];
|
|
2831
|
+
lines.push(`def Scope "DataViz_${safeName}" {`);
|
|
2832
|
+
lines.push(` custom string holoscript:vizType = "${dv.keyword}"`);
|
|
2833
|
+
if (dv.chartType) lines.push(` custom string holoscript:chartType = "${dv.chartType}"`);
|
|
2834
|
+
if (dv.dataSource) lines.push(` custom string holoscript:dataSource = "${dv.dataSource}"`);
|
|
2835
|
+
lines.push("}");
|
|
2836
|
+
return lines.join("\n");
|
|
2837
|
+
}
|
|
2838
|
+
function compileEducationBlock(block) {
|
|
2839
|
+
const props = block.properties || {};
|
|
2840
|
+
let objectives;
|
|
2841
|
+
if (Array.isArray(props.objectives)) objectives = props.objectives;
|
|
2842
|
+
let prerequisites;
|
|
2843
|
+
if (Array.isArray(props.prerequisites)) prerequisites = props.prerequisites;
|
|
2844
|
+
let questions;
|
|
2845
|
+
if (Array.isArray(props.questions)) {
|
|
2846
|
+
questions = props.questions.map(
|
|
2847
|
+
(q) => typeof q === "string" ? { question: q } : q
|
|
2848
|
+
);
|
|
2849
|
+
}
|
|
2850
|
+
for (const child of block.children || []) {
|
|
2851
|
+
const c = child;
|
|
2852
|
+
if (c.keyword === "question" && c.name) {
|
|
2853
|
+
if (!questions) questions = [];
|
|
2854
|
+
questions.push({
|
|
2855
|
+
question: c.name,
|
|
2856
|
+
options: c.properties?.options,
|
|
2857
|
+
answer: c.properties?.answer
|
|
2858
|
+
});
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
return {
|
|
2862
|
+
name: block.name || "unnamed",
|
|
2863
|
+
keyword: block.keyword,
|
|
2864
|
+
contentType: props.content_type || block.keyword,
|
|
2865
|
+
difficulty: props.difficulty,
|
|
2866
|
+
objectives,
|
|
2867
|
+
questions,
|
|
2868
|
+
prerequisites,
|
|
2869
|
+
duration: props.duration,
|
|
2870
|
+
traits: block.traits || [],
|
|
2871
|
+
properties: props
|
|
2872
|
+
};
|
|
2873
|
+
}
|
|
2874
|
+
function educationToR3F(edu) {
|
|
2875
|
+
const safeName = edu.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2876
|
+
const lines = [];
|
|
2877
|
+
lines.push(`// Education: ${edu.name} (${edu.keyword})`);
|
|
2878
|
+
lines.push(`export const ${safeName}Config = {`);
|
|
2879
|
+
lines.push(` name: "${edu.name}",`);
|
|
2880
|
+
lines.push(` type: "${edu.keyword}",`);
|
|
2881
|
+
if (edu.difficulty) lines.push(` difficulty: "${esc(edu.difficulty, "TypeScript")}",`);
|
|
2882
|
+
if (edu.objectives)
|
|
2883
|
+
lines.push(
|
|
2884
|
+
` objectives: [${edu.objectives.map((o) => `"${esc(o, "TypeScript")}"`).join(", ")}],`
|
|
2885
|
+
);
|
|
2886
|
+
if (edu.duration) lines.push(` duration: ${edu.duration},`);
|
|
2887
|
+
if (edu.questions) lines.push(` questions: ${JSON.stringify(edu.questions)},`);
|
|
2888
|
+
if (edu.prerequisites)
|
|
2889
|
+
lines.push(
|
|
2890
|
+
` prerequisites: [${edu.prerequisites.map((p) => `"${esc(p, "TypeScript")}"`).join(", ")}],`
|
|
2891
|
+
);
|
|
2892
|
+
lines.push("};");
|
|
2893
|
+
return lines.join("\n");
|
|
2894
|
+
}
|
|
2895
|
+
function educationToUnity(edu) {
|
|
2896
|
+
const safeName = edu.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2897
|
+
const lines = [];
|
|
2898
|
+
lines.push(`// Education: ${edu.name}`);
|
|
2899
|
+
lines.push(`public class ${safeName}Education : MonoBehaviour {`);
|
|
2900
|
+
lines.push(` public string contentType = "${esc(edu.keyword, "CSharp")}";`);
|
|
2901
|
+
if (edu.difficulty)
|
|
2902
|
+
lines.push(` public string difficulty = "${esc(edu.difficulty, "CSharp")}";`);
|
|
2903
|
+
if (edu.duration) lines.push(` public int durationMinutes = ${edu.duration};`);
|
|
2904
|
+
if (edu.objectives)
|
|
2905
|
+
lines.push(
|
|
2906
|
+
` public string[] objectives = new string[] { ${edu.objectives.map((o) => `"${esc(o, "CSharp")}"`).join(", ")} };`
|
|
2907
|
+
);
|
|
2908
|
+
if (edu.questions) lines.push(` public int questionCount = ${edu.questions.length};`);
|
|
2909
|
+
lines.push("}");
|
|
2910
|
+
return lines.join("\n");
|
|
2911
|
+
}
|
|
2912
|
+
function educationToGodot(edu) {
|
|
2913
|
+
const lines = [];
|
|
2914
|
+
lines.push(`# Education: ${edu.name}`);
|
|
2915
|
+
lines.push("extends Node");
|
|
2916
|
+
lines.push("");
|
|
2917
|
+
lines.push(`@export var content_type: String = "${esc(edu.keyword, "GDScript")}"`);
|
|
2918
|
+
if (edu.difficulty)
|
|
2919
|
+
lines.push(`@export var difficulty: String = "${esc(edu.difficulty, "GDScript")}"`);
|
|
2920
|
+
if (edu.duration) lines.push(`@export var duration_minutes: int = ${edu.duration}`);
|
|
2921
|
+
if (edu.objectives)
|
|
2922
|
+
lines.push(
|
|
2923
|
+
`@export var objectives: PackedStringArray = [${edu.objectives.map((o) => `"${esc(o, "GDScript")}"`).join(", ")}]`
|
|
2924
|
+
);
|
|
2925
|
+
lines.push("");
|
|
2926
|
+
lines.push("signal lesson_completed(score: float)");
|
|
2927
|
+
lines.push("signal quiz_submitted(answers: Dictionary)");
|
|
2928
|
+
return lines.join("\n");
|
|
2929
|
+
}
|
|
2930
|
+
function educationToVRChat(edu) {
|
|
2931
|
+
const safeName = edu.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2932
|
+
const lines = [];
|
|
2933
|
+
lines.push(`// Education: ${edu.name}`);
|
|
2934
|
+
lines.push("[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]");
|
|
2935
|
+
lines.push(`public class ${safeName}Education : UdonSharpBehaviour {`);
|
|
2936
|
+
lines.push(` public string contentType = "${edu.keyword}";`);
|
|
2937
|
+
if (edu.difficulty) lines.push(` public string difficulty = "${edu.difficulty}";`);
|
|
2938
|
+
if (edu.questions) lines.push(` [UdonSynced] public int currentQuestion = 0;`);
|
|
2939
|
+
lines.push("}");
|
|
2940
|
+
return lines.join("\n");
|
|
2941
|
+
}
|
|
2942
|
+
function educationToUSDA(edu) {
|
|
2943
|
+
const safeName = edu.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2944
|
+
const lines = [];
|
|
2945
|
+
lines.push(`def Scope "Education_${safeName}" {`);
|
|
2946
|
+
lines.push(` custom string holoscript:contentType = "${edu.keyword}"`);
|
|
2947
|
+
if (edu.difficulty) lines.push(` custom string holoscript:difficulty = "${edu.difficulty}"`);
|
|
2948
|
+
if (edu.duration) lines.push(` custom int holoscript:durationMinutes = ${edu.duration}`);
|
|
2949
|
+
lines.push("}");
|
|
2950
|
+
return lines.join("\n");
|
|
2951
|
+
}
|
|
2952
|
+
function compileMusicBlock(block) {
|
|
2953
|
+
const props = block.properties || {};
|
|
2954
|
+
let timeSignature;
|
|
2955
|
+
if (Array.isArray(props.time_signature) && props.time_signature.length === 2) {
|
|
2956
|
+
timeSignature = props.time_signature;
|
|
2957
|
+
}
|
|
2958
|
+
let effects;
|
|
2959
|
+
if (Array.isArray(props.effects)) effects = props.effects;
|
|
2960
|
+
for (const child of block.children || []) {
|
|
2961
|
+
const c = child;
|
|
2962
|
+
if (c.keyword === "effect" && c.name) {
|
|
2963
|
+
if (!effects) effects = [];
|
|
2964
|
+
effects.push(c.name);
|
|
2965
|
+
}
|
|
2966
|
+
}
|
|
2967
|
+
return {
|
|
2968
|
+
name: block.name || "unnamed",
|
|
2969
|
+
keyword: block.keyword,
|
|
2970
|
+
instrumentType: props.instrument_type || props.type,
|
|
2971
|
+
bpm: props.bpm,
|
|
2972
|
+
timeSignature,
|
|
2973
|
+
key: props.key,
|
|
2974
|
+
effects,
|
|
2975
|
+
pattern: props.pattern,
|
|
2976
|
+
bars: props.bars,
|
|
2977
|
+
traits: block.traits || [],
|
|
2978
|
+
properties: props
|
|
2979
|
+
};
|
|
2980
|
+
}
|
|
2981
|
+
function musicToR3F(music) {
|
|
2982
|
+
const safeName = music.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2983
|
+
const lines = [];
|
|
2984
|
+
lines.push(`// Music: ${music.name} (${music.keyword})`);
|
|
2985
|
+
lines.push(`export const ${safeName}Config = {`);
|
|
2986
|
+
lines.push(` name: "${music.name}",`);
|
|
2987
|
+
lines.push(` type: "${music.keyword}",`);
|
|
2988
|
+
if (music.instrumentType) lines.push(` instrumentType: "${music.instrumentType}",`);
|
|
2989
|
+
if (music.bpm) lines.push(` bpm: ${music.bpm},`);
|
|
2990
|
+
if (music.timeSignature) lines.push(` timeSignature: [${music.timeSignature.join(", ")}],`);
|
|
2991
|
+
if (music.key) lines.push(` key: "${esc(music.key, "TypeScript")}",`);
|
|
2992
|
+
if (music.effects)
|
|
2993
|
+
lines.push(` effects: [${music.effects.map((e) => `"${esc(e, "TypeScript")}"`).join(", ")}],`);
|
|
2994
|
+
if (music.pattern) lines.push(` pattern: "${esc(music.pattern, "TypeScript")}",`);
|
|
2995
|
+
if (music.bars) lines.push(` bars: ${music.bars},`);
|
|
2996
|
+
lines.push("};");
|
|
2997
|
+
return lines.join("\n");
|
|
2998
|
+
}
|
|
2999
|
+
function musicToUnity(music) {
|
|
3000
|
+
const safeName = music.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3001
|
+
const lines = [];
|
|
3002
|
+
lines.push(`// Music: ${music.name}`);
|
|
3003
|
+
lines.push(`public class ${safeName}Music : MonoBehaviour {`);
|
|
3004
|
+
lines.push(` public string musicType = "${esc(music.keyword, "CSharp")}";`);
|
|
3005
|
+
if (music.instrumentType)
|
|
3006
|
+
lines.push(` public string instrumentType = "${esc(music.instrumentType, "CSharp")}";`);
|
|
3007
|
+
if (music.bpm) lines.push(` public float bpm = ${music.bpm}f;`);
|
|
3008
|
+
if (music.key) lines.push(` public string musicalKey = "${esc(music.key, "CSharp")}";`);
|
|
3009
|
+
if (music.effects)
|
|
3010
|
+
lines.push(
|
|
3011
|
+
` public string[] effects = new string[] { ${music.effects.map((e) => `"${esc(e, "CSharp")}"`).join(", ")} };`
|
|
3012
|
+
);
|
|
3013
|
+
lines.push("}");
|
|
3014
|
+
return lines.join("\n");
|
|
3015
|
+
}
|
|
3016
|
+
function musicToGodot(music) {
|
|
3017
|
+
const lines = [];
|
|
3018
|
+
lines.push(`# Music: ${music.name}`);
|
|
3019
|
+
lines.push("extends Node");
|
|
3020
|
+
lines.push("");
|
|
3021
|
+
lines.push(`@export var music_type: String = "${music.keyword}"`);
|
|
3022
|
+
if (music.instrumentType)
|
|
3023
|
+
lines.push(`@export var instrument_type: String = "${music.instrumentType}"`);
|
|
3024
|
+
if (music.bpm) lines.push(`@export var bpm: float = ${music.bpm}`);
|
|
3025
|
+
if (music.key) lines.push(`@export var musical_key: String = "${music.key}"`);
|
|
3026
|
+
if (music.bars) lines.push(`@export var bars: int = ${music.bars}`);
|
|
3027
|
+
lines.push("");
|
|
3028
|
+
lines.push("signal beat(beat_number: int)");
|
|
3029
|
+
lines.push("signal bar_changed(bar_number: int)");
|
|
3030
|
+
return lines.join("\n");
|
|
3031
|
+
}
|
|
3032
|
+
function musicToVRChat(music) {
|
|
3033
|
+
const safeName = music.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3034
|
+
const lines = [];
|
|
3035
|
+
lines.push(`// Music: ${music.name}`);
|
|
3036
|
+
lines.push("[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]");
|
|
3037
|
+
lines.push(`public class ${safeName}Music : UdonSharpBehaviour {`);
|
|
3038
|
+
lines.push(` public string musicType = "${music.keyword}";`);
|
|
3039
|
+
if (music.bpm) lines.push(` [UdonSynced] public float bpm = ${music.bpm}f;`);
|
|
3040
|
+
if (music.instrumentType)
|
|
3041
|
+
lines.push(` public string instrumentType = "${music.instrumentType}";`);
|
|
3042
|
+
lines.push("}");
|
|
3043
|
+
return lines.join("\n");
|
|
3044
|
+
}
|
|
3045
|
+
function musicToUSDA(music) {
|
|
3046
|
+
const safeName = music.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3047
|
+
const lines = [];
|
|
3048
|
+
lines.push(`def Scope "Music_${safeName}" {`);
|
|
3049
|
+
lines.push(` custom string holoscript:musicType = "${music.keyword}"`);
|
|
3050
|
+
if (music.instrumentType)
|
|
3051
|
+
lines.push(` custom string holoscript:instrumentType = "${music.instrumentType}"`);
|
|
3052
|
+
if (music.bpm) lines.push(` custom float holoscript:bpm = ${music.bpm}`);
|
|
3053
|
+
if (music.key) lines.push(` custom string holoscript:key = "${music.key}"`);
|
|
3054
|
+
lines.push("}");
|
|
3055
|
+
return lines.join("\n");
|
|
3056
|
+
}
|
|
3057
|
+
function compileArchitectureBlock(block) {
|
|
3058
|
+
const props = block.properties || {};
|
|
3059
|
+
return {
|
|
3060
|
+
name: block.name || "unnamed",
|
|
3061
|
+
keyword: block.keyword,
|
|
3062
|
+
structureType: props.structure_type || block.keyword,
|
|
3063
|
+
area: props.area,
|
|
3064
|
+
height: props.height,
|
|
3065
|
+
wallMaterial: props.wall_material || props.wall,
|
|
3066
|
+
floorMaterial: props.floor_material || props.floor,
|
|
3067
|
+
temperatureSetpoint: props.temperature_setpoint || props.temperature,
|
|
3068
|
+
capacity: props.capacity,
|
|
3069
|
+
buildingCode: props.building_code || props.code,
|
|
3070
|
+
traits: block.traits || [],
|
|
3071
|
+
properties: props
|
|
3072
|
+
};
|
|
3073
|
+
}
|
|
3074
|
+
function architectureToR3F(arch) {
|
|
3075
|
+
const safeName = arch.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3076
|
+
const lines = [];
|
|
3077
|
+
lines.push(`// Architecture: ${arch.name} (${arch.keyword})`);
|
|
3078
|
+
lines.push(`export const ${safeName}Config = {`);
|
|
3079
|
+
lines.push(` name: "${arch.name}",`);
|
|
3080
|
+
lines.push(` type: "${arch.keyword}",`);
|
|
3081
|
+
if (arch.area) lines.push(` area: ${arch.area},`);
|
|
3082
|
+
if (arch.height) lines.push(` height: ${arch.height},`);
|
|
3083
|
+
if (arch.wallMaterial) lines.push(` wallMaterial: "${arch.wallMaterial}",`);
|
|
3084
|
+
if (arch.floorMaterial) lines.push(` floorMaterial: "${arch.floorMaterial}",`);
|
|
3085
|
+
if (arch.capacity) lines.push(` capacity: ${arch.capacity},`);
|
|
3086
|
+
if (arch.temperatureSetpoint) lines.push(` temperatureSetpoint: ${arch.temperatureSetpoint},`);
|
|
3087
|
+
lines.push("};");
|
|
3088
|
+
return lines.join("\n");
|
|
3089
|
+
}
|
|
3090
|
+
function architectureToUnity(arch) {
|
|
3091
|
+
const safeName = arch.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3092
|
+
const lines = [];
|
|
3093
|
+
lines.push(`// Architecture: ${arch.name}`);
|
|
3094
|
+
lines.push(`public class ${safeName}Architecture : MonoBehaviour {`);
|
|
3095
|
+
lines.push(` public string structureType = "${arch.keyword}";`);
|
|
3096
|
+
if (arch.area) lines.push(` public float area = ${arch.area}f;`);
|
|
3097
|
+
if (arch.height) lines.push(` public float height = ${arch.height}f;`);
|
|
3098
|
+
if (arch.wallMaterial) lines.push(` public string wallMaterial = "${arch.wallMaterial}";`);
|
|
3099
|
+
if (arch.floorMaterial) lines.push(` public string floorMaterial = "${arch.floorMaterial}";`);
|
|
3100
|
+
if (arch.capacity) lines.push(` public int capacity = ${arch.capacity};`);
|
|
3101
|
+
if (arch.temperatureSetpoint)
|
|
3102
|
+
lines.push(` public float temperatureSetpoint = ${arch.temperatureSetpoint}f;`);
|
|
3103
|
+
lines.push("}");
|
|
3104
|
+
return lines.join("\n");
|
|
3105
|
+
}
|
|
3106
|
+
function architectureToGodot(arch) {
|
|
3107
|
+
const lines = [];
|
|
3108
|
+
lines.push(`# Architecture: ${arch.name}`);
|
|
3109
|
+
lines.push("extends Node3D");
|
|
3110
|
+
lines.push("");
|
|
3111
|
+
lines.push(`@export var structure_type: String = "${arch.keyword}"`);
|
|
3112
|
+
if (arch.area) lines.push(`@export var area: float = ${arch.area}`);
|
|
3113
|
+
if (arch.height) lines.push(`@export var height: float = ${arch.height}`);
|
|
3114
|
+
if (arch.wallMaterial) lines.push(`@export var wall_material: String = "${arch.wallMaterial}"`);
|
|
3115
|
+
if (arch.floorMaterial)
|
|
3116
|
+
lines.push(`@export var floor_material: String = "${arch.floorMaterial}"`);
|
|
3117
|
+
if (arch.capacity) lines.push(`@export var capacity: int = ${arch.capacity}`);
|
|
3118
|
+
if (arch.temperatureSetpoint) {
|
|
3119
|
+
lines.push(`@export var temperature_setpoint: float = ${arch.temperatureSetpoint}`);
|
|
3120
|
+
lines.push("");
|
|
3121
|
+
lines.push("signal temperature_changed(temp: float)");
|
|
3122
|
+
}
|
|
3123
|
+
return lines.join("\n");
|
|
3124
|
+
}
|
|
3125
|
+
function architectureToVRChat(arch) {
|
|
3126
|
+
const safeName = arch.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3127
|
+
const lines = [];
|
|
3128
|
+
lines.push(`// Architecture: ${arch.name}`);
|
|
3129
|
+
lines.push("[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]");
|
|
3130
|
+
lines.push(`public class ${safeName}Architecture : UdonSharpBehaviour {`);
|
|
3131
|
+
lines.push(` public string structureType = "${arch.keyword}";`);
|
|
3132
|
+
if (arch.area) lines.push(` public float area = ${arch.area}f;`);
|
|
3133
|
+
if (arch.height) lines.push(` public float height = ${arch.height}f;`);
|
|
3134
|
+
if (arch.capacity) lines.push(` public int capacity = ${arch.capacity};`);
|
|
3135
|
+
lines.push("}");
|
|
3136
|
+
return lines.join("\n");
|
|
3137
|
+
}
|
|
3138
|
+
function architectureToUSDA(arch) {
|
|
3139
|
+
const safeName = arch.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3140
|
+
const lines = [];
|
|
3141
|
+
lines.push(`def Scope "Architecture_${safeName}" {`);
|
|
3142
|
+
lines.push(` custom string holoscript:structureType = "${arch.keyword}"`);
|
|
3143
|
+
if (arch.area) lines.push(` custom float holoscript:area = ${arch.area}`);
|
|
3144
|
+
if (arch.height) lines.push(` custom float holoscript:height = ${arch.height}`);
|
|
3145
|
+
if (arch.wallMaterial)
|
|
3146
|
+
lines.push(` custom string holoscript:wallMaterial = "${arch.wallMaterial}"`);
|
|
3147
|
+
if (arch.capacity) lines.push(` custom int holoscript:capacity = ${arch.capacity}`);
|
|
3148
|
+
lines.push("}");
|
|
3149
|
+
return lines.join("\n");
|
|
3150
|
+
}
|
|
3151
|
+
function compileWeb3Block(block) {
|
|
3152
|
+
const props = block.properties || {};
|
|
3153
|
+
let functions;
|
|
3154
|
+
if (Array.isArray(props.functions)) functions = props.functions;
|
|
3155
|
+
for (const child of block.children || []) {
|
|
3156
|
+
const c = child;
|
|
3157
|
+
if (c.keyword === "function" && c.name) {
|
|
3158
|
+
if (!functions) functions = [];
|
|
3159
|
+
functions.push(c.name);
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3162
|
+
return {
|
|
3163
|
+
name: block.name || "unnamed",
|
|
3164
|
+
keyword: block.keyword,
|
|
3165
|
+
standard: props.standard || props.token_standard,
|
|
3166
|
+
network: props.network,
|
|
3167
|
+
contractAddress: props.contract_address || props.address,
|
|
3168
|
+
functions,
|
|
3169
|
+
supply: props.supply || props.total_supply,
|
|
3170
|
+
votingThreshold: props.voting_threshold || props.threshold,
|
|
3171
|
+
traits: block.traits || [],
|
|
3172
|
+
properties: props
|
|
3173
|
+
};
|
|
3174
|
+
}
|
|
3175
|
+
function web3ToR3F(web3) {
|
|
3176
|
+
const safeName = web3.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3177
|
+
const lines = [];
|
|
3178
|
+
lines.push(`// Web3: ${web3.name} (${web3.keyword})`);
|
|
3179
|
+
lines.push(`export const ${safeName}Config = {`);
|
|
3180
|
+
lines.push(` name: "${web3.name}",`);
|
|
3181
|
+
lines.push(` type: "${web3.keyword}",`);
|
|
3182
|
+
if (web3.standard) lines.push(` standard: "${web3.standard}",`);
|
|
3183
|
+
if (web3.network) lines.push(` network: "${web3.network}",`);
|
|
3184
|
+
if (web3.contractAddress)
|
|
3185
|
+
lines.push(` contractAddress: "${esc(web3.contractAddress, "TypeScript")}",`);
|
|
3186
|
+
if (web3.functions)
|
|
3187
|
+
lines.push(
|
|
3188
|
+
` functions: [${web3.functions.map((f) => `"${esc(f, "TypeScript")}"`).join(", ")}],`
|
|
3189
|
+
);
|
|
3190
|
+
if (web3.supply) lines.push(` supply: ${web3.supply},`);
|
|
3191
|
+
if (web3.votingThreshold) lines.push(` votingThreshold: ${web3.votingThreshold},`);
|
|
3192
|
+
lines.push("};");
|
|
3193
|
+
return lines.join("\n");
|
|
3194
|
+
}
|
|
3195
|
+
function web3ToUnity(web3) {
|
|
3196
|
+
const safeName = web3.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3197
|
+
const lines = [];
|
|
3198
|
+
lines.push(`// Web3: ${web3.name}`);
|
|
3199
|
+
lines.push(`public class ${safeName}Web3 : MonoBehaviour {`);
|
|
3200
|
+
lines.push(` public string web3Type = "${web3.keyword}";`);
|
|
3201
|
+
if (web3.standard) lines.push(` public string standard = "${web3.standard}";`);
|
|
3202
|
+
if (web3.network) lines.push(` public string network = "${web3.network}";`);
|
|
3203
|
+
if (web3.contractAddress)
|
|
3204
|
+
lines.push(` public string contractAddress = "${web3.contractAddress}";`);
|
|
3205
|
+
if (web3.supply) lines.push(` public long totalSupply = ${web3.supply};`);
|
|
3206
|
+
lines.push("}");
|
|
3207
|
+
return lines.join("\n");
|
|
3208
|
+
}
|
|
3209
|
+
function web3ToGodot(web3) {
|
|
3210
|
+
const lines = [];
|
|
3211
|
+
lines.push(`# Web3: ${web3.name}`);
|
|
3212
|
+
lines.push("extends Node");
|
|
3213
|
+
lines.push("");
|
|
3214
|
+
lines.push(`@export var web3_type: String = "${web3.keyword}"`);
|
|
3215
|
+
if (web3.standard) lines.push(`@export var standard: String = "${web3.standard}"`);
|
|
3216
|
+
if (web3.network) lines.push(`@export var network: String = "${web3.network}"`);
|
|
3217
|
+
if (web3.contractAddress)
|
|
3218
|
+
lines.push(`@export var contract_address: String = "${web3.contractAddress}"`);
|
|
3219
|
+
lines.push("");
|
|
3220
|
+
lines.push("signal transaction_confirmed(tx_hash: String)");
|
|
3221
|
+
lines.push("signal wallet_connected(address: String)");
|
|
3222
|
+
return lines.join("\n");
|
|
3223
|
+
}
|
|
3224
|
+
function web3ToVRChat(web3) {
|
|
3225
|
+
const safeName = web3.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3226
|
+
const lines = [];
|
|
3227
|
+
lines.push(`// Web3: ${web3.name}`);
|
|
3228
|
+
lines.push("[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]");
|
|
3229
|
+
lines.push(`public class ${safeName}Web3 : UdonSharpBehaviour {`);
|
|
3230
|
+
lines.push(` public string web3Type = "${web3.keyword}";`);
|
|
3231
|
+
if (web3.standard) lines.push(` public string standard = "${web3.standard}";`);
|
|
3232
|
+
if (web3.network) lines.push(` public string network = "${web3.network}";`);
|
|
3233
|
+
if (web3.contractAddress) lines.push(` [UdonSynced] public string walletState = "";`);
|
|
3234
|
+
lines.push("}");
|
|
3235
|
+
return lines.join("\n");
|
|
3236
|
+
}
|
|
3237
|
+
function web3ToUSDA(web3) {
|
|
3238
|
+
const safeName = web3.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3239
|
+
const lines = [];
|
|
3240
|
+
lines.push(`def Scope "Web3_${safeName}" {`);
|
|
3241
|
+
lines.push(` custom string holoscript:web3Type = "${web3.keyword}"`);
|
|
3242
|
+
if (web3.standard) lines.push(` custom string holoscript:standard = "${web3.standard}"`);
|
|
3243
|
+
if (web3.network) lines.push(` custom string holoscript:network = "${web3.network}"`);
|
|
3244
|
+
if (web3.contractAddress)
|
|
3245
|
+
lines.push(` custom string holoscript:contractAddress = "${web3.contractAddress}"`);
|
|
3246
|
+
lines.push("}");
|
|
3247
|
+
return lines.join("\n");
|
|
3248
|
+
}
|
|
3249
|
+
function compileProceduralBlock(block) {
|
|
3250
|
+
const props = block.properties || {};
|
|
3251
|
+
let scaleRange;
|
|
3252
|
+
if (Array.isArray(props.scale_range) && props.scale_range.length === 2) {
|
|
3253
|
+
scaleRange = props.scale_range;
|
|
3254
|
+
}
|
|
3255
|
+
let noise;
|
|
3256
|
+
if (props.noise_type || props.octaves || props.frequency) {
|
|
3257
|
+
noise = {
|
|
3258
|
+
type: props.noise_type ?? "perlin",
|
|
3259
|
+
octaves: props.octaves ?? 4,
|
|
3260
|
+
frequency: props.frequency ?? 1,
|
|
3261
|
+
amplitude: props.amplitude ?? 1
|
|
3262
|
+
};
|
|
3263
|
+
} else if (props.noise && typeof props.noise === "object") {
|
|
3264
|
+
const n = props.noise;
|
|
3265
|
+
noise = {
|
|
3266
|
+
type: n.type ?? "perlin",
|
|
3267
|
+
octaves: n.octaves ?? 4,
|
|
3268
|
+
frequency: n.frequency ?? 1,
|
|
3269
|
+
amplitude: n.amplitude ?? 1
|
|
3270
|
+
};
|
|
3271
|
+
}
|
|
3272
|
+
return {
|
|
3273
|
+
name: block.name || "unnamed",
|
|
3274
|
+
keyword: block.keyword,
|
|
3275
|
+
genType: props.gen_type || props.type || block.keyword,
|
|
3276
|
+
seed: props.seed,
|
|
3277
|
+
density: props.density,
|
|
3278
|
+
scaleRange,
|
|
3279
|
+
noise,
|
|
3280
|
+
sourceMesh: props.source_mesh || props.source || props.mesh,
|
|
3281
|
+
traits: block.traits || [],
|
|
3282
|
+
properties: props
|
|
3283
|
+
};
|
|
3284
|
+
}
|
|
3285
|
+
function proceduralToR3F(proc) {
|
|
3286
|
+
const safeName = proc.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3287
|
+
const lines = [];
|
|
3288
|
+
lines.push(`// Procedural: ${proc.name} (${proc.keyword})`);
|
|
3289
|
+
lines.push(`export const ${safeName}Config = {`);
|
|
3290
|
+
lines.push(` name: "${proc.name}",`);
|
|
3291
|
+
lines.push(` type: "${proc.keyword}",`);
|
|
3292
|
+
if (proc.genType) lines.push(` genType: "${proc.genType}",`);
|
|
3293
|
+
if (proc.seed != null) lines.push(` seed: ${proc.seed},`);
|
|
3294
|
+
if (proc.density) lines.push(` density: ${proc.density},`);
|
|
3295
|
+
if (proc.scaleRange) lines.push(` scaleRange: [${proc.scaleRange.join(", ")}],`);
|
|
3296
|
+
if (proc.noise) lines.push(` noise: ${JSON.stringify(proc.noise)},`);
|
|
3297
|
+
if (proc.sourceMesh) lines.push(` sourceMesh: "${proc.sourceMesh}",`);
|
|
3298
|
+
lines.push("};");
|
|
3299
|
+
return lines.join("\n");
|
|
3300
|
+
}
|
|
3301
|
+
function proceduralToUnity(proc) {
|
|
3302
|
+
const safeName = proc.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3303
|
+
const lines = [];
|
|
3304
|
+
lines.push(`// Procedural: ${proc.name}`);
|
|
3305
|
+
lines.push(`public class ${safeName}Procedural : MonoBehaviour {`);
|
|
3306
|
+
lines.push(` public string genType = "${proc.keyword}";`);
|
|
3307
|
+
if (proc.seed != null) lines.push(` public int seed = ${proc.seed};`);
|
|
3308
|
+
if (proc.density) lines.push(` public float density = ${proc.density}f;`);
|
|
3309
|
+
if (proc.scaleRange) {
|
|
3310
|
+
lines.push(` public float scaleMin = ${proc.scaleRange[0]}f;`);
|
|
3311
|
+
lines.push(` public float scaleMax = ${proc.scaleRange[1]}f;`);
|
|
3312
|
+
}
|
|
3313
|
+
if (proc.noise) {
|
|
3314
|
+
lines.push(` public int octaves = ${proc.noise.octaves};`);
|
|
3315
|
+
lines.push(` public float frequency = ${proc.noise.frequency}f;`);
|
|
3316
|
+
lines.push(` public float amplitude = ${proc.noise.amplitude}f;`);
|
|
3317
|
+
}
|
|
3318
|
+
if (proc.sourceMesh) lines.push(` public string sourceMesh = "${proc.sourceMesh}";`);
|
|
3319
|
+
lines.push("}");
|
|
3320
|
+
return lines.join("\n");
|
|
3321
|
+
}
|
|
3322
|
+
function proceduralToGodot(proc) {
|
|
3323
|
+
const lines = [];
|
|
3324
|
+
lines.push(`# Procedural: ${proc.name}`);
|
|
3325
|
+
lines.push("extends Node3D");
|
|
3326
|
+
lines.push("");
|
|
3327
|
+
lines.push(`@export var gen_type: String = "${proc.keyword}"`);
|
|
3328
|
+
if (proc.seed != null) lines.push(`@export var seed: int = ${proc.seed}`);
|
|
3329
|
+
if (proc.density) lines.push(`@export var density: float = ${proc.density}`);
|
|
3330
|
+
if (proc.scaleRange) {
|
|
3331
|
+
lines.push(`@export var scale_min: float = ${proc.scaleRange[0]}`);
|
|
3332
|
+
lines.push(`@export var scale_max: float = ${proc.scaleRange[1]}`);
|
|
3333
|
+
}
|
|
3334
|
+
if (proc.noise) {
|
|
3335
|
+
lines.push(`@export var octaves: int = ${proc.noise.octaves}`);
|
|
3336
|
+
lines.push(`@export var frequency: float = ${proc.noise.frequency}`);
|
|
3337
|
+
lines.push(`@export var amplitude: float = ${proc.noise.amplitude}`);
|
|
3338
|
+
}
|
|
3339
|
+
lines.push("");
|
|
3340
|
+
lines.push("signal generation_complete(instance_count: int)");
|
|
3341
|
+
return lines.join("\n");
|
|
3342
|
+
}
|
|
3343
|
+
function proceduralToVRChat(proc) {
|
|
3344
|
+
const safeName = proc.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3345
|
+
const lines = [];
|
|
3346
|
+
lines.push(`// Procedural: ${proc.name}`);
|
|
3347
|
+
lines.push("[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]");
|
|
3348
|
+
lines.push(`public class ${safeName}Procedural : UdonSharpBehaviour {`);
|
|
3349
|
+
lines.push(` public string genType = "${proc.keyword}";`);
|
|
3350
|
+
if (proc.seed != null) lines.push(` [UdonSynced] public int seed = ${proc.seed};`);
|
|
3351
|
+
if (proc.density) lines.push(` public float density = ${proc.density}f;`);
|
|
3352
|
+
lines.push("}");
|
|
3353
|
+
return lines.join("\n");
|
|
3354
|
+
}
|
|
3355
|
+
function proceduralToUSDA(proc) {
|
|
3356
|
+
const safeName = proc.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3357
|
+
const lines = [];
|
|
3358
|
+
lines.push(`def Scope "Procedural_${safeName}" {`);
|
|
3359
|
+
lines.push(` custom string holoscript:genType = "${proc.keyword}"`);
|
|
3360
|
+
if (proc.seed != null) lines.push(` custom int holoscript:seed = ${proc.seed}`);
|
|
3361
|
+
if (proc.density) lines.push(` custom float holoscript:density = ${proc.density}`);
|
|
3362
|
+
if (proc.sourceMesh) lines.push(` custom string holoscript:sourceMesh = "${proc.sourceMesh}"`);
|
|
3363
|
+
lines.push("}");
|
|
3364
|
+
return lines.join("\n");
|
|
3365
|
+
}
|
|
3366
|
+
function compileRenderingBlock(block) {
|
|
3367
|
+
const props = block.properties || {};
|
|
3368
|
+
let lodLevels;
|
|
3369
|
+
if (Array.isArray(props.levels)) {
|
|
3370
|
+
lodLevels = props.levels.map(
|
|
3371
|
+
(l) => typeof l === "object" && l !== null ? l : { distance: l }
|
|
3372
|
+
);
|
|
3373
|
+
}
|
|
3374
|
+
for (const child of block.children || []) {
|
|
3375
|
+
const c = child;
|
|
3376
|
+
if (c.keyword === "level" || c.keyword === "lod_level") {
|
|
3377
|
+
if (!lodLevels) lodLevels = [];
|
|
3378
|
+
lodLevels.push({
|
|
3379
|
+
distance: c.properties?.distance ?? 0,
|
|
3380
|
+
mesh: c.name || void 0,
|
|
3381
|
+
detail: c.properties?.detail
|
|
3382
|
+
});
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
3385
|
+
return {
|
|
3386
|
+
name: block.name || "unnamed",
|
|
3387
|
+
keyword: block.keyword,
|
|
3388
|
+
lodLevels,
|
|
3389
|
+
renderLayer: props.render_layer || props.layer,
|
|
3390
|
+
shadowMode: props.shadow_mode || props.shadow,
|
|
3391
|
+
cullingMode: props.culling_mode || props.culling,
|
|
3392
|
+
sortOrder: props.sort_order,
|
|
3393
|
+
traits: block.traits || [],
|
|
3394
|
+
properties: props
|
|
3395
|
+
};
|
|
3396
|
+
}
|
|
3397
|
+
function renderingToR3F(rendering) {
|
|
3398
|
+
const safeName = rendering.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3399
|
+
const lines = [];
|
|
3400
|
+
lines.push(`// Rendering: ${rendering.name} (${rendering.keyword})`);
|
|
3401
|
+
lines.push(`export const ${safeName}Config = {`);
|
|
3402
|
+
lines.push(` name: "${rendering.name}",`);
|
|
3403
|
+
lines.push(` type: "${rendering.keyword}",`);
|
|
3404
|
+
if (rendering.lodLevels) lines.push(` lodLevels: ${JSON.stringify(rendering.lodLevels)},`);
|
|
3405
|
+
if (rendering.renderLayer) lines.push(` renderLayer: "${rendering.renderLayer}",`);
|
|
3406
|
+
if (rendering.shadowMode) lines.push(` shadowMode: "${rendering.shadowMode}",`);
|
|
3407
|
+
if (rendering.cullingMode) lines.push(` cullingMode: "${rendering.cullingMode}",`);
|
|
3408
|
+
if (rendering.sortOrder != null) lines.push(` sortOrder: ${rendering.sortOrder},`);
|
|
3409
|
+
lines.push("};");
|
|
3410
|
+
return lines.join("\n");
|
|
3411
|
+
}
|
|
3412
|
+
function renderingToUnity(rendering) {
|
|
3413
|
+
const safeName = rendering.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3414
|
+
const lines = [];
|
|
3415
|
+
lines.push(`// Rendering: ${rendering.name}`);
|
|
3416
|
+
lines.push(`public class ${safeName}Rendering : MonoBehaviour {`);
|
|
3417
|
+
lines.push(` public string renderType = "${rendering.keyword}";`);
|
|
3418
|
+
if (rendering.lodLevels) {
|
|
3419
|
+
lines.push(" void Start() {");
|
|
3420
|
+
lines.push(" var lodGroup = gameObject.AddComponent<LODGroup>();");
|
|
3421
|
+
lines.push(` var lods = new LOD[${rendering.lodLevels.length}];`);
|
|
3422
|
+
rendering.lodLevels.forEach((l, i) => {
|
|
3423
|
+
const screenHeight = 1 / (1 + l.distance * 0.01);
|
|
3424
|
+
lines.push(
|
|
3425
|
+
` lods[${i}] = new LOD(${screenHeight.toFixed(3)}f, GetComponentsInChildren<Renderer>());`
|
|
3426
|
+
);
|
|
3427
|
+
});
|
|
3428
|
+
lines.push(" lodGroup.SetLODs(lods);");
|
|
3429
|
+
lines.push(" }");
|
|
3430
|
+
}
|
|
3431
|
+
if (rendering.shadowMode) {
|
|
3432
|
+
const mode = rendering.shadowMode === "none" ? "Off" : rendering.shadowMode === "cast" ? "On" : "TwoSided";
|
|
3433
|
+
lines.push(` public ShadowCastingMode shadowMode = ShadowCastingMode.${mode};`);
|
|
3434
|
+
}
|
|
3435
|
+
lines.push("}");
|
|
3436
|
+
return lines.join("\n");
|
|
3437
|
+
}
|
|
3438
|
+
function renderingToGodot(rendering) {
|
|
3439
|
+
const lines = [];
|
|
3440
|
+
lines.push(`# Rendering: ${rendering.name}`);
|
|
3441
|
+
lines.push("extends Node3D");
|
|
3442
|
+
lines.push("");
|
|
3443
|
+
lines.push(`@export var render_type: String = "${rendering.keyword}"`);
|
|
3444
|
+
if (rendering.shadowMode)
|
|
3445
|
+
lines.push(`@export var shadow_mode: String = "${rendering.shadowMode}"`);
|
|
3446
|
+
if (rendering.cullingMode)
|
|
3447
|
+
lines.push(`@export var culling_mode: String = "${rendering.cullingMode}"`);
|
|
3448
|
+
if (rendering.sortOrder != null)
|
|
3449
|
+
lines.push(`@export var sort_order: int = ${rendering.sortOrder}`);
|
|
3450
|
+
if (rendering.lodLevels) {
|
|
3451
|
+
lines.push("");
|
|
3452
|
+
for (let i = 0; i < rendering.lodLevels.length; i++) {
|
|
3453
|
+
const l = rendering.lodLevels[i];
|
|
3454
|
+
lines.push(`@export var lod${i}_distance: float = ${l.distance}`);
|
|
3455
|
+
}
|
|
3456
|
+
}
|
|
3457
|
+
return lines.join("\n");
|
|
3458
|
+
}
|
|
3459
|
+
function renderingToVRChat(rendering) {
|
|
3460
|
+
const safeName = rendering.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3461
|
+
const lines = [];
|
|
3462
|
+
lines.push(`// Rendering: ${rendering.name}`);
|
|
3463
|
+
lines.push(`public class ${safeName}Rendering : UdonSharpBehaviour {`);
|
|
3464
|
+
lines.push(` public string renderType = "${rendering.keyword}";`);
|
|
3465
|
+
if (rendering.lodLevels) lines.push(` public int lodLevels = ${rendering.lodLevels.length};`);
|
|
3466
|
+
if (rendering.shadowMode) lines.push(` public string shadowMode = "${rendering.shadowMode}";`);
|
|
3467
|
+
lines.push("}");
|
|
3468
|
+
return lines.join("\n");
|
|
3469
|
+
}
|
|
3470
|
+
function renderingToUSDA(rendering) {
|
|
3471
|
+
const safeName = rendering.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3472
|
+
const lines = [];
|
|
3473
|
+
lines.push(`def Scope "Rendering_${safeName}" {`);
|
|
3474
|
+
lines.push(` custom string holoscript:renderType = "${rendering.keyword}"`);
|
|
3475
|
+
if (rendering.shadowMode)
|
|
3476
|
+
lines.push(` custom string holoscript:shadowMode = "${rendering.shadowMode}"`);
|
|
3477
|
+
if (rendering.cullingMode)
|
|
3478
|
+
lines.push(` custom string holoscript:cullingMode = "${rendering.cullingMode}"`);
|
|
3479
|
+
if (rendering.lodLevels)
|
|
3480
|
+
lines.push(` custom int holoscript:lodLevels = ${rendering.lodLevels.length}`);
|
|
3481
|
+
lines.push("}");
|
|
3482
|
+
return lines.join("\n");
|
|
3483
|
+
}
|
|
3484
|
+
function compileNavigationBlock(block) {
|
|
3485
|
+
const props = block.properties || {};
|
|
3486
|
+
return {
|
|
3487
|
+
name: block.name || "unnamed",
|
|
3488
|
+
keyword: block.keyword,
|
|
3489
|
+
agentRadius: props.agent_radius || props.radius,
|
|
3490
|
+
agentHeight: props.agent_height || props.height,
|
|
3491
|
+
maxSlope: props.max_slope || props.slope,
|
|
3492
|
+
stepHeight: props.step_height || props.step,
|
|
3493
|
+
speed: props.speed,
|
|
3494
|
+
avoidancePriority: props.avoidance_priority || props.priority,
|
|
3495
|
+
behaviorRoot: props.behavior_root || props.root_node,
|
|
3496
|
+
traits: block.traits || [],
|
|
3497
|
+
properties: props
|
|
3498
|
+
};
|
|
3499
|
+
}
|
|
3500
|
+
function navigationToR3F(nav) {
|
|
3501
|
+
const safeName = nav.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3502
|
+
const lines = [];
|
|
3503
|
+
lines.push(`// Navigation: ${nav.name} (${nav.keyword})`);
|
|
3504
|
+
lines.push(`export const ${safeName}Config = {`);
|
|
3505
|
+
lines.push(` name: "${nav.name}",`);
|
|
3506
|
+
lines.push(` type: "${nav.keyword}",`);
|
|
3507
|
+
if (nav.agentRadius) lines.push(` agentRadius: ${nav.agentRadius},`);
|
|
3508
|
+
if (nav.agentHeight) lines.push(` agentHeight: ${nav.agentHeight},`);
|
|
3509
|
+
if (nav.maxSlope) lines.push(` maxSlope: ${nav.maxSlope},`);
|
|
3510
|
+
if (nav.stepHeight) lines.push(` stepHeight: ${nav.stepHeight},`);
|
|
3511
|
+
if (nav.speed) lines.push(` speed: ${nav.speed},`);
|
|
3512
|
+
if (nav.avoidancePriority != null) lines.push(` avoidancePriority: ${nav.avoidancePriority},`);
|
|
3513
|
+
if (nav.behaviorRoot) lines.push(` behaviorRoot: "${nav.behaviorRoot}",`);
|
|
3514
|
+
lines.push("};");
|
|
3515
|
+
return lines.join("\n");
|
|
3516
|
+
}
|
|
3517
|
+
function navigationToUnity(nav) {
|
|
3518
|
+
const safeName = nav.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3519
|
+
const lines = [];
|
|
3520
|
+
lines.push(`// Navigation: ${nav.name}`);
|
|
3521
|
+
lines.push(`public class ${safeName}Navigation : MonoBehaviour {`);
|
|
3522
|
+
lines.push(` public string navType = "${nav.keyword}";`);
|
|
3523
|
+
lines.push(" void Start() {");
|
|
3524
|
+
if (nav.keyword === "navmesh" || nav.keyword === "nav_mesh") {
|
|
3525
|
+
lines.push(" var surface = gameObject.AddComponent<NavMeshSurface>();");
|
|
3526
|
+
if (nav.agentRadius) lines.push(` // Agent radius: ${nav.agentRadius}`);
|
|
3527
|
+
if (nav.maxSlope) lines.push(` // Max slope: ${nav.maxSlope} degrees`);
|
|
3528
|
+
} else {
|
|
3529
|
+
lines.push(" var agent = gameObject.AddComponent<NavMeshAgent>();");
|
|
3530
|
+
if (nav.speed) lines.push(` agent.speed = ${nav.speed}f;`);
|
|
3531
|
+
if (nav.agentRadius) lines.push(` agent.radius = ${nav.agentRadius}f;`);
|
|
3532
|
+
if (nav.agentHeight) lines.push(` agent.height = ${nav.agentHeight}f;`);
|
|
3533
|
+
if (nav.stepHeight) lines.push(` agent.baseOffset = ${nav.stepHeight}f;`);
|
|
3534
|
+
if (nav.avoidancePriority != null)
|
|
3535
|
+
lines.push(` agent.avoidancePriority = ${nav.avoidancePriority};`);
|
|
3536
|
+
}
|
|
3537
|
+
lines.push(" }");
|
|
3538
|
+
lines.push("}");
|
|
3539
|
+
return lines.join("\n");
|
|
3540
|
+
}
|
|
3541
|
+
function navigationToGodot(nav) {
|
|
3542
|
+
const lines = [];
|
|
3543
|
+
lines.push(`# Navigation: ${nav.name}`);
|
|
3544
|
+
if (nav.keyword === "navmesh" || nav.keyword === "nav_mesh") {
|
|
3545
|
+
lines.push("extends NavigationRegion3D");
|
|
3546
|
+
lines.push("");
|
|
3547
|
+
if (nav.agentRadius) lines.push(`@export var agent_radius: float = ${nav.agentRadius}`);
|
|
3548
|
+
if (nav.maxSlope) lines.push(`@export var max_slope: float = ${nav.maxSlope}`);
|
|
3549
|
+
} else {
|
|
3550
|
+
lines.push("extends NavigationAgent3D");
|
|
3551
|
+
lines.push("");
|
|
3552
|
+
if (nav.speed) lines.push(`@export var speed: float = ${nav.speed}`);
|
|
3553
|
+
if (nav.agentRadius) lines.push(`@export var agent_radius: float = ${nav.agentRadius}`);
|
|
3554
|
+
if (nav.agentHeight) lines.push(`@export var agent_height: float = ${nav.agentHeight}`);
|
|
3555
|
+
if (nav.avoidancePriority != null)
|
|
3556
|
+
lines.push(`@export var avoidance_priority: int = ${nav.avoidancePriority}`);
|
|
3557
|
+
}
|
|
3558
|
+
lines.push("");
|
|
3559
|
+
lines.push("signal navigation_finished");
|
|
3560
|
+
lines.push("signal path_changed(new_path: PackedVector3Array)");
|
|
3561
|
+
return lines.join("\n");
|
|
3562
|
+
}
|
|
3563
|
+
function navigationToVRChat(nav) {
|
|
3564
|
+
const safeName = nav.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3565
|
+
const lines = [];
|
|
3566
|
+
lines.push(`// Navigation: ${nav.name}`);
|
|
3567
|
+
lines.push("[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]");
|
|
3568
|
+
lines.push(`public class ${safeName}Navigation : UdonSharpBehaviour {`);
|
|
3569
|
+
lines.push(` public string navType = "${nav.keyword}";`);
|
|
3570
|
+
if (nav.speed) lines.push(` public float speed = ${nav.speed}f;`);
|
|
3571
|
+
if (nav.agentRadius) lines.push(` public float agentRadius = ${nav.agentRadius}f;`);
|
|
3572
|
+
lines.push("}");
|
|
3573
|
+
return lines.join("\n");
|
|
3574
|
+
}
|
|
3575
|
+
function navigationToUSDA(nav) {
|
|
3576
|
+
const safeName = nav.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3577
|
+
const lines = [];
|
|
3578
|
+
lines.push(`def Scope "Navigation_${safeName}" {`);
|
|
3579
|
+
lines.push(` custom string holoscript:navType = "${nav.keyword}"`);
|
|
3580
|
+
if (nav.agentRadius) lines.push(` custom float holoscript:agentRadius = ${nav.agentRadius}`);
|
|
3581
|
+
if (nav.agentHeight) lines.push(` custom float holoscript:agentHeight = ${nav.agentHeight}`);
|
|
3582
|
+
if (nav.speed) lines.push(` custom float holoscript:speed = ${nav.speed}`);
|
|
3583
|
+
if (nav.maxSlope) lines.push(` custom float holoscript:maxSlope = ${nav.maxSlope}`);
|
|
3584
|
+
lines.push("}");
|
|
3585
|
+
return lines.join("\n");
|
|
3586
|
+
}
|
|
3587
|
+
function compileInputBlock(block) {
|
|
3588
|
+
const props = block.properties || {};
|
|
3589
|
+
return {
|
|
3590
|
+
name: block.name || "unnamed",
|
|
3591
|
+
keyword: block.keyword,
|
|
3592
|
+
inputType: props.input_type || props.type || block.keyword,
|
|
3593
|
+
platform: props.platform,
|
|
3594
|
+
binding: props.binding || props.key || props.button,
|
|
3595
|
+
action: props.action,
|
|
3596
|
+
threshold: props.threshold,
|
|
3597
|
+
interactionDistance: props.interaction_distance || props.distance,
|
|
3598
|
+
traits: block.traits || [],
|
|
3599
|
+
properties: props
|
|
3600
|
+
};
|
|
3601
|
+
}
|
|
3602
|
+
function inputToR3F(input) {
|
|
3603
|
+
const safeName = input.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3604
|
+
const lines = [];
|
|
3605
|
+
lines.push(`// Input: ${input.name} (${input.keyword})`);
|
|
3606
|
+
lines.push(`export const ${safeName}Config = {`);
|
|
3607
|
+
lines.push(` name: "${input.name}",`);
|
|
3608
|
+
lines.push(` type: "${input.keyword}",`);
|
|
3609
|
+
if (input.inputType) lines.push(` inputType: "${input.inputType}",`);
|
|
3610
|
+
if (input.platform) lines.push(` platform: "${input.platform}",`);
|
|
3611
|
+
if (input.binding) lines.push(` binding: "${input.binding}",`);
|
|
3612
|
+
if (input.action) lines.push(` action: "${input.action}",`);
|
|
3613
|
+
if (input.threshold) lines.push(` threshold: ${input.threshold},`);
|
|
3614
|
+
if (input.interactionDistance) lines.push(` interactionDistance: ${input.interactionDistance},`);
|
|
3615
|
+
lines.push("};");
|
|
3616
|
+
return lines.join("\n");
|
|
3617
|
+
}
|
|
3618
|
+
function inputToUnity(input) {
|
|
3619
|
+
const safeName = input.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3620
|
+
const lines = [];
|
|
3621
|
+
lines.push(`// Input: ${input.name}`);
|
|
3622
|
+
lines.push(`public class ${safeName}Input : MonoBehaviour {`);
|
|
3623
|
+
lines.push(` public string inputType = "${input.keyword}";`);
|
|
3624
|
+
if (input.binding) lines.push(` public string binding = "${input.binding}";`);
|
|
3625
|
+
if (input.action) lines.push(` public string action = "${input.action}";`);
|
|
3626
|
+
if (input.threshold) lines.push(` public float threshold = ${input.threshold}f;`);
|
|
3627
|
+
if (input.interactionDistance)
|
|
3628
|
+
lines.push(` public float interactionDistance = ${input.interactionDistance}f;`);
|
|
3629
|
+
if (input.platform === "vr_controller") {
|
|
3630
|
+
lines.push(" void Update() {");
|
|
3631
|
+
lines.push(" // XR input polling");
|
|
3632
|
+
lines.push(" var device = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);");
|
|
3633
|
+
lines.push(` device.TryGetFeatureValue(CommonUsages.trigger, out float triggerValue);`);
|
|
3634
|
+
lines.push(" }");
|
|
3635
|
+
}
|
|
3636
|
+
lines.push("}");
|
|
3637
|
+
return lines.join("\n");
|
|
3638
|
+
}
|
|
3639
|
+
function inputToGodot(input) {
|
|
3640
|
+
const lines = [];
|
|
3641
|
+
lines.push(`# Input: ${input.name}`);
|
|
3642
|
+
lines.push("extends Node");
|
|
3643
|
+
lines.push("");
|
|
3644
|
+
lines.push(`@export var input_type: String = "${input.keyword}"`);
|
|
3645
|
+
if (input.binding) lines.push(`@export var binding: String = "${input.binding}"`);
|
|
3646
|
+
if (input.action) lines.push(`@export var action_name: String = "${input.action}"`);
|
|
3647
|
+
if (input.threshold) lines.push(`@export var threshold: float = ${input.threshold}`);
|
|
3648
|
+
if (input.interactionDistance)
|
|
3649
|
+
lines.push(`@export var interaction_distance: float = ${input.interactionDistance}`);
|
|
3650
|
+
lines.push("");
|
|
3651
|
+
lines.push("signal action_triggered(action: String, value: float)");
|
|
3652
|
+
lines.push("signal gesture_recognized(gesture: String)");
|
|
3653
|
+
return lines.join("\n");
|
|
3654
|
+
}
|
|
3655
|
+
function inputToVRChat(input) {
|
|
3656
|
+
const safeName = input.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3657
|
+
const lines = [];
|
|
3658
|
+
lines.push(`// Input: ${input.name}`);
|
|
3659
|
+
lines.push(`public class ${safeName}Input : UdonSharpBehaviour {`);
|
|
3660
|
+
lines.push(` public string inputType = "${input.keyword}";`);
|
|
3661
|
+
if (input.action) lines.push(` public string action = "${input.action}";`);
|
|
3662
|
+
if (input.interactionDistance)
|
|
3663
|
+
lines.push(` public float interactionDistance = ${input.interactionDistance}f;`);
|
|
3664
|
+
if (input.keyword === "interaction" || input.keyword === "gesture_profile") {
|
|
3665
|
+
lines.push(" public override void Interact() {");
|
|
3666
|
+
lines.push(" // Handle VRChat interaction");
|
|
3667
|
+
lines.push(" }");
|
|
3668
|
+
}
|
|
3669
|
+
lines.push("}");
|
|
3670
|
+
return lines.join("\n");
|
|
3671
|
+
}
|
|
3672
|
+
function inputToUSDA(input) {
|
|
3673
|
+
const safeName = input.name.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3674
|
+
const lines = [];
|
|
3675
|
+
lines.push(`def Scope "Input_${safeName}" {`);
|
|
3676
|
+
lines.push(` custom string holoscript:inputType = "${input.keyword}"`);
|
|
3677
|
+
if (input.binding) lines.push(` custom string holoscript:binding = "${input.binding}"`);
|
|
3678
|
+
if (input.action) lines.push(` custom string holoscript:action = "${input.action}"`);
|
|
3679
|
+
if (input.interactionDistance)
|
|
3680
|
+
lines.push(` custom float holoscript:interactionDistance = ${input.interactionDistance}`);
|
|
3681
|
+
lines.push("}");
|
|
3682
|
+
return lines.join("\n");
|
|
3683
|
+
}
|
|
3684
|
+
function parseGravityVector(props) {
|
|
3685
|
+
const gv = props.gravity_vector ?? props.gravityVector;
|
|
3686
|
+
if (Array.isArray(gv) && gv.length === 3 && gv.every((n) => typeof n === "number")) {
|
|
3687
|
+
return [gv[0], gv[1], gv[2]];
|
|
3688
|
+
}
|
|
3689
|
+
const g = props.gravity;
|
|
3690
|
+
if (typeof g === "number" && !Number.isNaN(g)) {
|
|
3691
|
+
return [0, -Math.abs(g), 0];
|
|
3692
|
+
}
|
|
3693
|
+
return void 0;
|
|
3694
|
+
}
|
|
3695
|
+
function parseSimulationEnvironment(block) {
|
|
3696
|
+
const p = block.properties || {};
|
|
3697
|
+
const env = {};
|
|
3698
|
+
const topG = parseGravityVector(p);
|
|
3699
|
+
if (topG) env.gravity = topG;
|
|
3700
|
+
if (typeof p.skybox === "string" && p.skybox.trim()) {
|
|
3701
|
+
env.skyboxPreset = p.skybox.trim();
|
|
3702
|
+
}
|
|
3703
|
+
const colorRaw = p.skybox_color ?? p.skyboxColor ?? p.background_color;
|
|
3704
|
+
if (colorRaw != null && String(colorRaw).trim() !== "") {
|
|
3705
|
+
env.skyboxColor = String(colorRaw).trim();
|
|
3706
|
+
}
|
|
3707
|
+
const po = p.physics_overrides ?? p.physicsOverrides;
|
|
3708
|
+
if (po && typeof po === "object" && !Array.isArray(po)) {
|
|
3709
|
+
env.physicsOverrides = { ...po };
|
|
3710
|
+
}
|
|
3711
|
+
for (const child of block.children || []) {
|
|
3712
|
+
const c = child;
|
|
3713
|
+
if (c.type !== "DomainBlock") continue;
|
|
3714
|
+
const kw = c.keyword;
|
|
3715
|
+
const cp = c.properties || {};
|
|
3716
|
+
if (kw === "skybox" || kw === "environment_sky" || kw === "hdri") {
|
|
3717
|
+
if (typeof cp.preset === "string" && cp.preset.trim()) env.skyboxPreset = cp.preset.trim();
|
|
3718
|
+
if (cp.color != null && String(cp.color).trim() !== "") env.skyboxColor = String(cp.color).trim();
|
|
3719
|
+
}
|
|
3720
|
+
if (kw === "gravity" || kw === "world_gravity") {
|
|
3721
|
+
const g = parseGravityVector(cp);
|
|
3722
|
+
if (g) env.gravity = g;
|
|
3723
|
+
}
|
|
3724
|
+
if (kw === "physics_world" || kw === "physics_overrides") {
|
|
3725
|
+
env.physicsOverrides = { ...env.physicsOverrides, ...cp };
|
|
3726
|
+
}
|
|
3727
|
+
}
|
|
3728
|
+
if (!env.gravity && !env.skyboxPreset && !env.skyboxColor && !env.physicsOverrides) {
|
|
3729
|
+
return void 0;
|
|
3730
|
+
}
|
|
3731
|
+
return env;
|
|
3732
|
+
}
|
|
3733
|
+
function compileSimulationBlock(block) {
|
|
3734
|
+
const traits = block.traits || [];
|
|
3735
|
+
let simulationType = "unknown";
|
|
3736
|
+
if (traits.includes("thermal_simulation")) simulationType = "thermal";
|
|
3737
|
+
else if (traits.includes("structural_fem")) simulationType = "structural";
|
|
3738
|
+
else if (traits.includes("hydraulic_pipe")) simulationType = "hydraulic";
|
|
3739
|
+
const overlays = [];
|
|
3740
|
+
for (const child of block.children || []) {
|
|
3741
|
+
const c = child;
|
|
3742
|
+
if (c.traits?.includes("scalar_field_overlay") || c.keyword === "scalar_field_overlay") {
|
|
3743
|
+
const p = c.properties || {};
|
|
3744
|
+
overlays.push({
|
|
3745
|
+
source: p.source ?? "",
|
|
3746
|
+
colormap: p.colormap ?? "turbo",
|
|
3747
|
+
range: p.range ?? [0, 1],
|
|
3748
|
+
opacity: p.opacity ?? 0.7,
|
|
3749
|
+
visible: p.visible ?? true,
|
|
3750
|
+
label: p.label ?? ""
|
|
3751
|
+
});
|
|
3752
|
+
}
|
|
3753
|
+
}
|
|
3754
|
+
const environment = parseSimulationEnvironment(block);
|
|
3755
|
+
return {
|
|
3756
|
+
keyword: block.keyword,
|
|
3757
|
+
name: block.name,
|
|
3758
|
+
simulationType,
|
|
3759
|
+
traits,
|
|
3760
|
+
config: block.properties || {},
|
|
3761
|
+
environment,
|
|
3762
|
+
overlays
|
|
3763
|
+
};
|
|
3764
|
+
}
|
|
3765
|
+
function simulationEnvironmentToR3FChunks(env) {
|
|
3766
|
+
if (!env) return { visualLines: [], userDataExpr: null };
|
|
3767
|
+
const visualLines = [];
|
|
3768
|
+
if (env.skyboxColor) {
|
|
3769
|
+
const hex = env.skyboxColor.startsWith("#") ? env.skyboxColor : `#${env.skyboxColor}`;
|
|
3770
|
+
visualLines.push(`<color attach="background" args={['${hex}']} />`);
|
|
3771
|
+
}
|
|
3772
|
+
if (env.skyboxPreset) {
|
|
3773
|
+
visualLines.push(
|
|
3774
|
+
`<Environment preset={${JSON.stringify(env.skyboxPreset)}} background />`
|
|
3775
|
+
);
|
|
3776
|
+
}
|
|
3777
|
+
const meta = {};
|
|
3778
|
+
if (env.gravity) meta.gravity = env.gravity;
|
|
3779
|
+
if (env.physicsOverrides && Object.keys(env.physicsOverrides).length > 0) {
|
|
3780
|
+
meta.physicsOverrides = env.physicsOverrides;
|
|
3781
|
+
}
|
|
3782
|
+
const userDataExpr = Object.keys(meta).length > 0 ? JSON.stringify({ holoscript: meta }) : null;
|
|
3783
|
+
return { visualLines, userDataExpr };
|
|
3784
|
+
}
|
|
3785
|
+
function simulationToR3F(sim) {
|
|
3786
|
+
const configExpr = JSON.stringify(sim.config);
|
|
3787
|
+
const { visualLines, userDataExpr } = simulationEnvironmentToR3FChunks(sim.environment);
|
|
3788
|
+
const overlayJSX = sim.overlays.map(
|
|
3789
|
+
(o) => `<ScalarFieldOverlay colormap="${o.colormap}" range={[${o.range.join(", ")}]} opacity={${o.opacity}} visible={${o.visible}} label="${o.label}" />`
|
|
3790
|
+
).join("\n ");
|
|
3791
|
+
const envVisual = visualLines.length > 0 ? `${visualLines.join("\n ")}
|
|
3792
|
+
` : "";
|
|
3793
|
+
const wrapWithGroup = (body) => userDataExpr ? `<group userData={${userDataExpr}}>
|
|
3794
|
+
${body}
|
|
3795
|
+
</group>` : body;
|
|
3796
|
+
if (sim.simulationType === "unknown") {
|
|
3797
|
+
const body = `${envVisual}${overlayJSX}`;
|
|
3798
|
+
return `{/* Simulation: ${sim.name} (unknown solver \u2014 add thermal_simulation, structural_fem, or hydraulic_pipe trait) */}
|
|
3799
|
+
${wrapWithGroup(body)}`;
|
|
3800
|
+
}
|
|
3801
|
+
const providerInner = overlayJSX ? `
|
|
3802
|
+
${overlayJSX}
|
|
3803
|
+
` : "\n ";
|
|
3804
|
+
const provider = `${envVisual}<SimulationProvider type="${sim.simulationType}" config={${configExpr}}>${providerInner}</SimulationProvider>`;
|
|
3805
|
+
return `{/* Simulation: ${sim.name} (${sim.simulationType}) */}
|
|
3806
|
+
${wrapWithGroup(provider)}`;
|
|
3807
|
+
}
|
|
3808
|
+
function compileDomainBlocks(blocks, handlers, fallback) {
|
|
3809
|
+
return blocks.map((block) => {
|
|
3810
|
+
const handler = handlers[block.domain];
|
|
3811
|
+
if (handler) return handler(block);
|
|
3812
|
+
if (fallback) return fallback(block);
|
|
3813
|
+
return `/* Unhandled domain block: ${block.domain}/${block.keyword} "${block.name}" */`;
|
|
3814
|
+
});
|
|
3815
|
+
}
|
|
3816
|
+
function hexToRGB(hex) {
|
|
3817
|
+
const h = hex.replace("#", "");
|
|
3818
|
+
const r = parseInt(h.substring(0, 2), 16) / 255;
|
|
3819
|
+
const g = parseInt(h.substring(2, 4), 16) / 255;
|
|
3820
|
+
const b = parseInt(h.substring(4, 6), 16) / 255;
|
|
3821
|
+
return `${r.toFixed(3)}, ${g.toFixed(3)}, ${b.toFixed(3)}`;
|
|
3822
|
+
}
|
|
3823
|
+
function hexToRGBA(hex, alpha) {
|
|
3824
|
+
const h = hex.replace("#", "");
|
|
3825
|
+
return [
|
|
3826
|
+
parseInt(h.substring(0, 2), 16) / 255,
|
|
3827
|
+
parseInt(h.substring(2, 4), 16) / 255,
|
|
3828
|
+
parseInt(h.substring(4, 6), 16) / 255,
|
|
3829
|
+
alpha
|
|
3830
|
+
];
|
|
3831
|
+
}
|
|
3832
|
+
function getRequiredCapability() {
|
|
3833
|
+
return chunkKKP7JKN4_cjs.ANSCapabilityPath.DOMAIN_BLOCK;
|
|
3834
|
+
}
|
|
3835
|
+
var PHYSICAL_MATERIAL_KEYS; exports.DOMAIN_BLOCK_COMPILER_MIXIN_CAPABILITY = void 0;
|
|
3836
|
+
var init_DomainBlockCompilerMixin = chunkHCCQLAA4_cjs.__esm({
|
|
3837
|
+
"src/compiler/DomainBlockCompilerMixin.ts"() {
|
|
3838
|
+
chunkKKP7JKN4_cjs.init_CompilerBase();
|
|
3839
|
+
chunkKKP7JKN4_cjs.init_ANSNamespace();
|
|
3840
|
+
PHYSICAL_MATERIAL_KEYS = [
|
|
3841
|
+
"clearcoat",
|
|
3842
|
+
"clearcoatRoughness",
|
|
3843
|
+
"transmission",
|
|
3844
|
+
"thickness",
|
|
3845
|
+
"sheen",
|
|
3846
|
+
"sheenColor",
|
|
3847
|
+
"sheenRoughness",
|
|
3848
|
+
"specularIntensity",
|
|
3849
|
+
"iridescence",
|
|
3850
|
+
"attenuationColor",
|
|
3851
|
+
"attenuationDistance"
|
|
3852
|
+
];
|
|
3853
|
+
exports.DOMAIN_BLOCK_COMPILER_MIXIN_CAPABILITY = "/compile/mixin/domain-block";
|
|
3854
|
+
}
|
|
3855
|
+
});
|
|
3856
|
+
|
|
3857
|
+
exports.architectureToGodot = architectureToGodot;
|
|
3858
|
+
exports.architectureToR3F = architectureToR3F;
|
|
3859
|
+
exports.architectureToUSDA = architectureToUSDA;
|
|
3860
|
+
exports.architectureToUnity = architectureToUnity;
|
|
3861
|
+
exports.architectureToVRChat = architectureToVRChat;
|
|
3862
|
+
exports.audioSourceToAndroidXR = audioSourceToAndroidXR;
|
|
3863
|
+
exports.audioSourceToBabylon = audioSourceToBabylon;
|
|
3864
|
+
exports.audioSourceToGodot = audioSourceToGodot;
|
|
3865
|
+
exports.audioSourceToPlayCanvas = audioSourceToPlayCanvas;
|
|
3866
|
+
exports.audioSourceToR3F = audioSourceToR3F;
|
|
3867
|
+
exports.audioSourceToUSD = audioSourceToUSD;
|
|
3868
|
+
exports.audioSourceToUnity = audioSourceToUnity;
|
|
3869
|
+
exports.audioSourceToUnreal = audioSourceToUnreal;
|
|
3870
|
+
exports.audioSourceToVisionOS = audioSourceToVisionOS;
|
|
3871
|
+
exports.compileArchitectureBlock = compileArchitectureBlock;
|
|
3872
|
+
exports.compileAudioSourceBlock = compileAudioSourceBlock;
|
|
3873
|
+
exports.compileDataVizBlock = compileDataVizBlock;
|
|
3874
|
+
exports.compileDomainBlocks = compileDomainBlocks;
|
|
3875
|
+
exports.compileEducationBlock = compileEducationBlock;
|
|
3876
|
+
exports.compileHealthcareBlock = compileHealthcareBlock;
|
|
3877
|
+
exports.compileInputBlock = compileInputBlock;
|
|
3878
|
+
exports.compileIoTBlock = compileIoTBlock;
|
|
3879
|
+
exports.compileMaterialBlock = compileMaterialBlock;
|
|
3880
|
+
exports.compileMusicBlock = compileMusicBlock;
|
|
3881
|
+
exports.compileNarrativeBlock = compileNarrativeBlock;
|
|
3882
|
+
exports.compileNavigationBlock = compileNavigationBlock;
|
|
3883
|
+
exports.compileParticleBlock = compileParticleBlock;
|
|
3884
|
+
exports.compilePaymentBlock = compilePaymentBlock;
|
|
3885
|
+
exports.compilePhysicsBlock = compilePhysicsBlock;
|
|
3886
|
+
exports.compilePostProcessingBlock = compilePostProcessingBlock;
|
|
3887
|
+
exports.compileProceduralBlock = compileProceduralBlock;
|
|
3888
|
+
exports.compileRenderingBlock = compileRenderingBlock;
|
|
3889
|
+
exports.compileRoboticsBlock = compileRoboticsBlock;
|
|
3890
|
+
exports.compileSimulationBlock = compileSimulationBlock;
|
|
3891
|
+
exports.compileWeatherBlock = compileWeatherBlock;
|
|
3892
|
+
exports.compileWeb3Block = compileWeb3Block;
|
|
3893
|
+
exports.datavizToGodot = datavizToGodot;
|
|
3894
|
+
exports.datavizToR3F = datavizToR3F;
|
|
3895
|
+
exports.datavizToUSDA = datavizToUSDA;
|
|
3896
|
+
exports.datavizToUnity = datavizToUnity;
|
|
3897
|
+
exports.datavizToVRChat = datavizToVRChat;
|
|
3898
|
+
exports.educationToGodot = educationToGodot;
|
|
3899
|
+
exports.educationToR3F = educationToR3F;
|
|
3900
|
+
exports.educationToUSDA = educationToUSDA;
|
|
3901
|
+
exports.educationToUnity = educationToUnity;
|
|
3902
|
+
exports.educationToVRChat = educationToVRChat;
|
|
3903
|
+
exports.getRequiredCapability = getRequiredCapability;
|
|
3904
|
+
exports.healthcareToGodot = healthcareToGodot;
|
|
3905
|
+
exports.healthcareToR3F = healthcareToR3F;
|
|
3906
|
+
exports.healthcareToUSDA = healthcareToUSDA;
|
|
3907
|
+
exports.healthcareToUnity = healthcareToUnity;
|
|
3908
|
+
exports.healthcareToVRChat = healthcareToVRChat;
|
|
3909
|
+
exports.init_DomainBlockCompilerMixin = init_DomainBlockCompilerMixin;
|
|
3910
|
+
exports.inputToGodot = inputToGodot;
|
|
3911
|
+
exports.inputToR3F = inputToR3F;
|
|
3912
|
+
exports.inputToUSDA = inputToUSDA;
|
|
3913
|
+
exports.inputToUnity = inputToUnity;
|
|
3914
|
+
exports.inputToVRChat = inputToVRChat;
|
|
3915
|
+
exports.iotToGodot = iotToGodot;
|
|
3916
|
+
exports.iotToR3F = iotToR3F;
|
|
3917
|
+
exports.iotToUSDA = iotToUSDA;
|
|
3918
|
+
exports.iotToUnity = iotToUnity;
|
|
3919
|
+
exports.iotToVRChat = iotToVRChat;
|
|
3920
|
+
exports.isPhysicalMaterial = isPhysicalMaterial;
|
|
3921
|
+
exports.materialToAndroidXR = materialToAndroidXR;
|
|
3922
|
+
exports.materialToBabylon = materialToBabylon;
|
|
3923
|
+
exports.materialToGLTF = materialToGLTF;
|
|
3924
|
+
exports.materialToGodot = materialToGodot;
|
|
3925
|
+
exports.materialToPlayCanvas = materialToPlayCanvas;
|
|
3926
|
+
exports.materialToR3F = materialToR3F;
|
|
3927
|
+
exports.materialToSDF = materialToSDF;
|
|
3928
|
+
exports.materialToUSD = materialToUSD;
|
|
3929
|
+
exports.materialToUnity = materialToUnity;
|
|
3930
|
+
exports.materialToUnreal = materialToUnreal;
|
|
3931
|
+
exports.materialToVRChat = materialToVRChat;
|
|
3932
|
+
exports.materialToVisionOS = materialToVisionOS;
|
|
3933
|
+
exports.materialToWebGPU = materialToWebGPU;
|
|
3934
|
+
exports.musicToGodot = musicToGodot;
|
|
3935
|
+
exports.musicToR3F = musicToR3F;
|
|
3936
|
+
exports.musicToUSDA = musicToUSDA;
|
|
3937
|
+
exports.musicToUnity = musicToUnity;
|
|
3938
|
+
exports.musicToVRChat = musicToVRChat;
|
|
3939
|
+
exports.narrativeToGodot = narrativeToGodot;
|
|
3940
|
+
exports.narrativeToR3F = narrativeToR3F;
|
|
3941
|
+
exports.narrativeToUSDA = narrativeToUSDA;
|
|
3942
|
+
exports.narrativeToUnity = narrativeToUnity;
|
|
3943
|
+
exports.narrativeToVRChat = narrativeToVRChat;
|
|
3944
|
+
exports.navigationToGodot = navigationToGodot;
|
|
3945
|
+
exports.navigationToR3F = navigationToR3F;
|
|
3946
|
+
exports.navigationToUSDA = navigationToUSDA;
|
|
3947
|
+
exports.navigationToUnity = navigationToUnity;
|
|
3948
|
+
exports.navigationToVRChat = navigationToVRChat;
|
|
3949
|
+
exports.particlesToAndroidXR = particlesToAndroidXR;
|
|
3950
|
+
exports.particlesToBabylon = particlesToBabylon;
|
|
3951
|
+
exports.particlesToGodot = particlesToGodot;
|
|
3952
|
+
exports.particlesToPlayCanvas = particlesToPlayCanvas;
|
|
3953
|
+
exports.particlesToR3F = particlesToR3F;
|
|
3954
|
+
exports.particlesToUSD = particlesToUSD;
|
|
3955
|
+
exports.particlesToUnity = particlesToUnity;
|
|
3956
|
+
exports.particlesToUnreal = particlesToUnreal;
|
|
3957
|
+
exports.particlesToVisionOS = particlesToVisionOS;
|
|
3958
|
+
exports.paymentToGodot = paymentToGodot;
|
|
3959
|
+
exports.paymentToR3F = paymentToR3F;
|
|
3960
|
+
exports.paymentToUSDA = paymentToUSDA;
|
|
3961
|
+
exports.paymentToUnity = paymentToUnity;
|
|
3962
|
+
exports.paymentToVRChat = paymentToVRChat;
|
|
3963
|
+
exports.physicsToAndroidXR = physicsToAndroidXR;
|
|
3964
|
+
exports.physicsToBabylon = physicsToBabylon;
|
|
3965
|
+
exports.physicsToGodot = physicsToGodot;
|
|
3966
|
+
exports.physicsToPlayCanvas = physicsToPlayCanvas;
|
|
3967
|
+
exports.physicsToR3F = physicsToR3F;
|
|
3968
|
+
exports.physicsToSDF = physicsToSDF;
|
|
3969
|
+
exports.physicsToURDF = physicsToURDF;
|
|
3970
|
+
exports.physicsToUnity = physicsToUnity;
|
|
3971
|
+
exports.physicsToUnreal = physicsToUnreal;
|
|
3972
|
+
exports.physicsToVisionOS = physicsToVisionOS;
|
|
3973
|
+
exports.postProcessingToBabylon = postProcessingToBabylon;
|
|
3974
|
+
exports.postProcessingToGodot = postProcessingToGodot;
|
|
3975
|
+
exports.postProcessingToR3F = postProcessingToR3F;
|
|
3976
|
+
exports.postProcessingToUSD = postProcessingToUSD;
|
|
3977
|
+
exports.postProcessingToUnity = postProcessingToUnity;
|
|
3978
|
+
exports.postProcessingToUnreal = postProcessingToUnreal;
|
|
3979
|
+
exports.proceduralToGodot = proceduralToGodot;
|
|
3980
|
+
exports.proceduralToR3F = proceduralToR3F;
|
|
3981
|
+
exports.proceduralToUSDA = proceduralToUSDA;
|
|
3982
|
+
exports.proceduralToUnity = proceduralToUnity;
|
|
3983
|
+
exports.proceduralToVRChat = proceduralToVRChat;
|
|
3984
|
+
exports.renderingToGodot = renderingToGodot;
|
|
3985
|
+
exports.renderingToR3F = renderingToR3F;
|
|
3986
|
+
exports.renderingToUSDA = renderingToUSDA;
|
|
3987
|
+
exports.renderingToUnity = renderingToUnity;
|
|
3988
|
+
exports.renderingToVRChat = renderingToVRChat;
|
|
3989
|
+
exports.roboticsToGodot = roboticsToGodot;
|
|
3990
|
+
exports.roboticsToR3F = roboticsToR3F;
|
|
3991
|
+
exports.roboticsToUSDA = roboticsToUSDA;
|
|
3992
|
+
exports.roboticsToUnity = roboticsToUnity;
|
|
3993
|
+
exports.roboticsToVRChat = roboticsToVRChat;
|
|
3994
|
+
exports.simulationToR3F = simulationToR3F;
|
|
3995
|
+
exports.weatherToAndroidXR = weatherToAndroidXR;
|
|
3996
|
+
exports.weatherToGodot = weatherToGodot;
|
|
3997
|
+
exports.weatherToR3F = weatherToR3F;
|
|
3998
|
+
exports.weatherToUSD = weatherToUSD;
|
|
3999
|
+
exports.weatherToUnity = weatherToUnity;
|
|
4000
|
+
exports.weatherToUnreal = weatherToUnreal;
|
|
4001
|
+
exports.web3ToGodot = web3ToGodot;
|
|
4002
|
+
exports.web3ToR3F = web3ToR3F;
|
|
4003
|
+
exports.web3ToUSDA = web3ToUSDA;
|
|
4004
|
+
exports.web3ToUnity = web3ToUnity;
|
|
4005
|
+
exports.web3ToVRChat = web3ToVRChat;
|
|
4006
|
+
//# sourceMappingURL=chunk-HKEXJUWS.cjs.map
|
|
4007
|
+
//# sourceMappingURL=chunk-HKEXJUWS.cjs.map
|