@holoscript/core 6.0.4 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -1
  3. package/dist/compiler/index.d.ts +82 -0
  4. package/dist/constants.d.ts +3 -2
  5. package/dist/coordinators/index.d.ts +189 -0
  6. package/dist/index.d.ts +501 -19
  7. package/dist/paper-0c-spike/index.d.ts +29 -0
  8. package/dist/reconstruction/index.d.ts +78 -0
  9. package/dist/tools/index.d.ts +22 -1
  10. package/dist/traitDocs/traitDocs.d.ts +69 -0
  11. package/dist/traits/index.d.ts +61 -0
  12. package/package.json +105 -57
  13. package/dist/GLTFPipeline-DEN36VNK.js +0 -12
  14. package/dist/GLTFPipeline-YPCAK236.cjs +0 -33
  15. package/dist/HoloScriptPlusParser-BN6KVRCM.js +0 -692
  16. package/dist/HoloScriptPlusParser-NC5FE6AL.cjs +0 -697
  17. package/dist/USDZExporter-NTMBNTDB.js +0 -707
  18. package/dist/USDZExporter-UWGWNMMD.cjs +0 -709
  19. package/dist/chunk-27LWW5FU.cjs +0 -410
  20. package/dist/chunk-2CWOLHTE.js +0 -69
  21. package/dist/chunk-33LSUQDD.cjs +0 -835
  22. package/dist/chunk-3FJCK5XA.js +0 -2232
  23. package/dist/chunk-3FXV5S25.cjs +0 -633
  24. package/dist/chunk-3FYZOR7S.cjs +0 -69
  25. package/dist/chunk-3SAK5KFL.cjs +0 -83
  26. package/dist/chunk-4XSNJCLC.cjs +0 -1859
  27. package/dist/chunk-54FHG2MX.js +0 -655
  28. package/dist/chunk-56IF4NTA.js +0 -56
  29. package/dist/chunk-5BGSECRJ.cjs +0 -2237
  30. package/dist/chunk-5GLCTO44.js +0 -161
  31. package/dist/chunk-5O6TQC6M.cjs +0 -1871
  32. package/dist/chunk-5OEOHAAW.cjs +0 -682
  33. package/dist/chunk-5TOFIR6L.js +0 -407
  34. package/dist/chunk-5WUNN6ZN.cjs +0 -428
  35. package/dist/chunk-6TZPZCOJ.cjs +0 -1404
  36. package/dist/chunk-6UEHYZ7V.cjs +0 -773
  37. package/dist/chunk-6XSERL6L.js +0 -5678
  38. package/dist/chunk-72EQECGT.cjs +0 -908
  39. package/dist/chunk-7AGYRWKW.cjs +0 -507
  40. package/dist/chunk-7LCYLPW2.cjs +0 -663
  41. package/dist/chunk-A7PIMZGU.js +0 -263
  42. package/dist/chunk-ATSKSYVE.cjs +0 -51683
  43. package/dist/chunk-B5TCIAPQ.cjs +0 -117
  44. package/dist/chunk-BF2235SI.cjs +0 -5714
  45. package/dist/chunk-BKIGPPVM.js +0 -629
  46. package/dist/chunk-BND3ST2K.cjs +0 -662
  47. package/dist/chunk-BU7VWW2K.js +0 -2522
  48. package/dist/chunk-BWFJEM5A.js +0 -5419
  49. package/dist/chunk-CAUCGUEA.cjs +0 -130
  50. package/dist/chunk-CBJSLA2E.cjs +0 -5423
  51. package/dist/chunk-CDPGV4DN.js +0 -114
  52. package/dist/chunk-CLYEIWA5.cjs +0 -408
  53. package/dist/chunk-CS2EMTGF.js +0 -1966
  54. package/dist/chunk-DMG7C4H2.js +0 -975
  55. package/dist/chunk-DXJQDCFL.js +0 -468
  56. package/dist/chunk-E3FWRT3Z.js +0 -608
  57. package/dist/chunk-E3UALNFA.js +0 -421
  58. package/dist/chunk-EONILVMF.js +0 -762
  59. package/dist/chunk-EQV4R3EV.cjs +0 -769
  60. package/dist/chunk-F3HH56EB.cjs +0 -5538
  61. package/dist/chunk-F4IULT7N.js +0 -1488
  62. package/dist/chunk-FF3Q7ADR.js +0 -380
  63. package/dist/chunk-FFKU7BTK.cjs +0 -1046
  64. package/dist/chunk-FHQVYCH2.js +0 -70
  65. package/dist/chunk-FSF7EQVA.cjs +0 -1974
  66. package/dist/chunk-G4VZTCIB.js +0 -659
  67. package/dist/chunk-G7CT3EMP.cjs +0 -1002
  68. package/dist/chunk-GGHSW2NN.js +0 -51334
  69. package/dist/chunk-GVUR45UF.cjs +0 -777
  70. package/dist/chunk-H5Z7NASB.js +0 -9662
  71. package/dist/chunk-HE7ULERA.cjs +0 -697
  72. package/dist/chunk-HJJLD366.js +0 -1169
  73. package/dist/chunk-HPS76H7Q.js +0 -309
  74. package/dist/chunk-HQUEA5R6.cjs +0 -424
  75. package/dist/chunk-HYNTS5CP.js +0 -422
  76. package/dist/chunk-I6XZ5DZF.cjs +0 -488
  77. package/dist/chunk-IBDG74G2.cjs +0 -1219
  78. package/dist/chunk-IFNQFCTM.js +0 -3098
  79. package/dist/chunk-IHOUYQIA.js +0 -406
  80. package/dist/chunk-ILRBGFVD.cjs +0 -72
  81. package/dist/chunk-IWI6J7FX.js +0 -421
  82. package/dist/chunk-K3JDKWGI.cjs +0 -270
  83. package/dist/chunk-K6EKD26I.js +0 -630
  84. package/dist/chunk-KCQ5NDYC.cjs +0 -3172
  85. package/dist/chunk-KED34ILP.js +0 -832
  86. package/dist/chunk-KSGXLT74.cjs +0 -457
  87. package/dist/chunk-L4G4RLXX.js +0 -767
  88. package/dist/chunk-LDP5OK6G.js +0 -1216
  89. package/dist/chunk-LGGRPKTV.cjs +0 -735
  90. package/dist/chunk-LK5IAVH6.cjs +0 -1173
  91. package/dist/chunk-LSW7P7ML.js +0 -3675
  92. package/dist/chunk-LXJ4667L.cjs +0 -3874
  93. package/dist/chunk-LZ266PCM.cjs +0 -4499
  94. package/dist/chunk-MD6KDHVE.cjs +0 -237
  95. package/dist/chunk-MEASWI2Y.js +0 -126
  96. package/dist/chunk-MPXBVFHQ.js +0 -768
  97. package/dist/chunk-N5FTS757.cjs +0 -415
  98. package/dist/chunk-NCUKG4SK.cjs +0 -3075
  99. package/dist/chunk-NDQNIJEH.js +0 -1715
  100. package/dist/chunk-NOZZ46QU.js +0 -168
  101. package/dist/chunk-OFKWH2IP.js +0 -449
  102. package/dist/chunk-PHENW4MQ.js +0 -65
  103. package/dist/chunk-PMGODDJA.cjs +0 -319
  104. package/dist/chunk-Q4QX3AET.cjs +0 -1505
  105. package/dist/chunk-Q56TT7IL.js +0 -483
  106. package/dist/chunk-Q5JT3YML.cjs +0 -129
  107. package/dist/chunk-Q5SJOGHQ.cjs +0 -4256
  108. package/dist/chunk-QGKNANZ3.js +0 -3071
  109. package/dist/chunk-QLEAOI3Q.cjs +0 -424
  110. package/dist/chunk-R7MA7QWV.js +0 -732
  111. package/dist/chunk-RVYPEYPX.js +0 -678
  112. package/dist/chunk-S2N5TNMA.js +0 -1855
  113. package/dist/chunk-S565K7NK.js +0 -752
  114. package/dist/chunk-SDAMZIRE.js +0 -765
  115. package/dist/chunk-T36DDXSF.js +0 -4250
  116. package/dist/chunk-T4NKMBDL.js +0 -5474
  117. package/dist/chunk-T7LEXZUZ.cjs +0 -2526
  118. package/dist/chunk-TEWCN33Y.js +0 -694
  119. package/dist/chunk-TQSZUOW5.cjs +0 -793
  120. package/dist/chunk-TSH3MSQU.cjs +0 -129
  121. package/dist/chunk-UERJ3YJV.js +0 -504
  122. package/dist/chunk-UPJBDCVF.js +0 -1395
  123. package/dist/chunk-V3NN3HPP.js +0 -4462
  124. package/dist/chunk-VJ3L7CHT.cjs +0 -169
  125. package/dist/chunk-WB4Z63GG.js +0 -229
  126. package/dist/chunk-WDW67DZB.cjs +0 -9728
  127. package/dist/chunk-WGMEAYBG.js +0 -126
  128. package/dist/chunk-X4ZF6CNE.cjs +0 -473
  129. package/dist/chunk-X6SEAXAX.cjs +0 -3681
  130. package/dist/chunk-XCWFGZAA.js +0 -1043
  131. package/dist/chunk-XD6IYDUX.js +0 -903
  132. package/dist/chunk-XG23EUQX.cjs +0 -1717
  133. package/dist/chunk-XRKWN5PL.cjs +0 -173
  134. package/dist/chunk-XUILI4KB.cjs +0 -430
  135. package/dist/chunk-XUTX5CBW.js +0 -126
  136. package/dist/chunk-XWPNTWDN.cjs +0 -755
  137. package/dist/chunk-XXINBTZK.cjs +0 -633
  138. package/dist/chunk-YCXFCXDS.js +0 -1868
  139. package/dist/chunk-YQK5JNFK.js +0 -3725
  140. package/dist/chunk-YYXH45E2.js +0 -426
  141. package/dist/chunk-Z34RLXRA.cjs +0 -612
  142. package/dist/chunk-ZP4D3CSX.cjs +0 -72
  143. package/dist/cli/holoscript-runner.cjs +0 -2259
  144. package/dist/cli/holoscript-runner.js +0 -2234
  145. package/dist/codebase/index.cjs +0 -336
  146. package/dist/codebase/index.js +0 -331
  147. package/dist/compiler/agent-inference.cjs +0 -28
  148. package/dist/compiler/agent-inference.js +0 -5
  149. package/dist/compiler/android-xr.cjs +0 -19
  150. package/dist/compiler/android-xr.js +0 -9
  151. package/dist/compiler/android.cjs +0 -20
  152. package/dist/compiler/android.js +0 -10
  153. package/dist/compiler/ar.cjs +0 -20
  154. package/dist/compiler/ar.js +0 -8
  155. package/dist/compiler/babylon.cjs +0 -17
  156. package/dist/compiler/babylon.js +0 -11
  157. package/dist/compiler/coco.cjs +0 -27
  158. package/dist/compiler/coco.js +0 -4
  159. package/dist/compiler/domain-block-utils.cjs +0 -602
  160. package/dist/compiler/domain-block-utils.js +0 -8
  161. package/dist/compiler/dtdl.cjs +0 -24
  162. package/dist/compiler/dtdl.js +0 -8
  163. package/dist/compiler/gltf-pipeline.cjs +0 -39
  164. package/dist/compiler/gltf-pipeline.js +0 -4
  165. package/dist/compiler/godot.cjs +0 -15
  166. package/dist/compiler/godot.js +0 -9
  167. package/dist/compiler/incremental.cjs +0 -29
  168. package/dist/compiler/incremental.js +0 -4
  169. package/dist/compiler/index.cjs +0 -2578
  170. package/dist/compiler/index.js +0 -2383
  171. package/dist/compiler/ios.cjs +0 -20
  172. package/dist/compiler/ios.js +0 -10
  173. package/dist/compiler/multi-layer.cjs +0 -20
  174. package/dist/compiler/multi-layer.js +0 -11
  175. package/dist/compiler/nodetoy.cjs +0 -23
  176. package/dist/compiler/nodetoy.js +0 -4
  177. package/dist/compiler/openxr.cjs +0 -15
  178. package/dist/compiler/openxr.js +0 -9
  179. package/dist/compiler/playcanvas.cjs +0 -16
  180. package/dist/compiler/playcanvas.js +0 -10
  181. package/dist/compiler/r3f.cjs +0 -34
  182. package/dist/compiler/r3f.js +0 -12
  183. package/dist/compiler/remotion.cjs +0 -23
  184. package/dist/compiler/remotion.js +0 -4
  185. package/dist/compiler/reproducibility.cjs +0 -39
  186. package/dist/compiler/reproducibility.js +0 -4
  187. package/dist/compiler/sdf.cjs +0 -21
  188. package/dist/compiler/sdf.js +0 -9
  189. package/dist/compiler/semantic-scene.cjs +0 -31
  190. package/dist/compiler/semantic-scene.js +0 -4
  191. package/dist/compiler/state.cjs +0 -17
  192. package/dist/compiler/state.js +0 -7
  193. package/dist/compiler/trait-composition.cjs +0 -26
  194. package/dist/compiler/trait-composition.js +0 -5
  195. package/dist/compiler/unity.cjs +0 -15
  196. package/dist/compiler/unity.js +0 -9
  197. package/dist/compiler/unreal.cjs +0 -19
  198. package/dist/compiler/unreal.js +0 -9
  199. package/dist/compiler/urdf.cjs +0 -45
  200. package/dist/compiler/urdf.js +0 -9
  201. package/dist/compiler/usd-physics.cjs +0 -23
  202. package/dist/compiler/usd-physics.js +0 -6
  203. package/dist/compiler/visionos.cjs +0 -15
  204. package/dist/compiler/visionos.js +0 -9
  205. package/dist/compiler/vrchat.cjs +0 -19
  206. package/dist/compiler/vrchat.js +0 -9
  207. package/dist/compiler/vrr.cjs +0 -21
  208. package/dist/compiler/vrr.js +0 -9
  209. package/dist/compiler/wasm.cjs +0 -33
  210. package/dist/compiler/wasm.js +0 -9
  211. package/dist/compiler/webgpu.cjs +0 -15
  212. package/dist/compiler/webgpu.js +0 -9
  213. package/dist/debugger.cjs +0 -21
  214. package/dist/debugger.js +0 -8
  215. package/dist/entries/interop.cjs +0 -62
  216. package/dist/entries/interop.js +0 -5
  217. package/dist/entries/scripting.cjs +0 -68
  218. package/dist/entries/scripting.js +0 -11
  219. package/dist/index.cjs +0 -40921
  220. package/dist/index.js +0 -37763
  221. package/dist/math/vec3.cjs +0 -57
  222. package/dist/math/vec3.js +0 -4
  223. package/dist/ml-dsa-PHCWUBPX.cjs +0 -1178
  224. package/dist/ml-dsa-WYLJHJO6.js +0 -1178
  225. package/dist/parser.cjs +0 -27
  226. package/dist/parser.js +0 -10
  227. package/dist/playwright-5OSAPTNH.js +0 -98660
  228. package/dist/playwright-RL6GY4F7.cjs +0 -98673
  229. package/dist/runtime.cjs +0 -16
  230. package/dist/runtime.js +0 -7
  231. package/dist/storage/index.cjs +0 -37
  232. package/dist/storage/index.js +0 -4
  233. package/dist/traits/index.cjs +0 -14649
  234. package/dist/traits/index.js +0 -12243
  235. package/dist/type-checker.cjs +0 -18
  236. package/dist/type-checker.js +0 -5
@@ -1,4250 +0,0 @@
1
- import { init_material_properties_visual, init_surface_texture_visual, init_lighting_visual, init_gems_minerals_visual, init_fabric_cloth_visual, init_visual_effects_visual, init_age_condition_visual, init_water_fluid_visual, init_weather_phenomena_visual, init_emotion_mood_visual, init_size_scale_visual, init_environmental_biome_visual, init_magic_fantasy_visual, init_scifi_technology_visual, init_creatures_mythical_visual, init_nature_life_visual, init_furniture_decor_visual, init_construction_building_visual, init_containers_storage_visual, init_shape_form_visual, init_animals_visual, init_maritime_naval_visual, init_time_period_visual, init_accessibility_visual, init_accessibility_extended_visual, init_architecture_realestate_visual, init_audio_visual, init_cooking_food_visual, init_core_vr_interaction_visual, init_data_visualization_visual, init_education_learning_visual, init_environment_input_visual, init_game_mechanics_visual, init_geospatial_web3_visual, init_healthcare_medical_visual, init_humanoid_avatar_visual, init_intelligence_behavior_visual, init_interop_copresence_visual, init_iot_autonomous_agents_visual, init_locomotion_movement_visual, init_measurement_sensing_visual, init_media_analytics_visual, init_multisensory_haptic_visual, init_musical_sound_visual, init_music_performance_visual, init_narrative_storytelling_visual, init_networking_ai_visual, init_npc_roles_visual, init_object_interaction_visual, init_parser_core_ui_visual, init_physical_affordances_visual, init_physics_expansion_visual, init_procedural_generation_visual, init_resource_gathering_visual, init_safety_boundaries_visual, init_signs_communication_visual, init_simple_modifiers_visual, init_social_commerce_visual, init_social_effects_visual, init_sports_fitness_visual, init_state_persistence_visual, init_transportation_vehicles_visual, init_volumetric_webgpu_visual, init_weather_particles_visual, init_xr_platform_visual, MATERIAL_PROPERTIES_VISUALS, SURFACE_TEXTURE_VISUALS, LIGHTING_VISUALS, GEMS_MINERALS_VISUALS, FABRIC_CLOTH_VISUALS, VISUAL_EFFECTS_VISUALS, AGE_CONDITION_VISUALS, WATER_FLUID_VISUALS, WEATHER_PHENOMENA_VISUALS, EMOTION_MOOD_VISUALS, SIZE_SCALE_VISUALS, ENVIRONMENTAL_BIOME_VISUALS, MAGIC_FANTASY_VISUALS, SCIFI_TECHNOLOGY_VISUALS, CREATURES_MYTHICAL_VISUALS, NATURE_LIFE_VISUALS, FURNITURE_DECOR_VISUALS, CONSTRUCTION_BUILDING_VISUALS, CONTAINERS_STORAGE_VISUALS, SHAPE_FORM_VISUALS, ANIMALS_VISUALS, MARITIME_NAVAL_VISUALS, TIME_PERIOD_VISUALS, ACCESSIBILITY_VISUALS, ACCESSIBILITY_EXTENDED_VISUALS, ARCHITECTURE_REALESTATE_VISUALS, AUDIO_VISUALS, COOKING_FOOD_VISUALS, CORE_VR_INTERACTION_VISUALS, DATA_VISUALIZATION_VISUALS, EDUCATION_LEARNING_VISUALS, ENVIRONMENT_INPUT_VISUALS, GAME_MECHANICS_VISUALS, GEOSPATIAL_WEB3_VISUALS, HEALTHCARE_MEDICAL_VISUALS, HUMANOID_AVATAR_VISUALS, INTELLIGENCE_BEHAVIOR_VISUALS, INTEROP_COPRESENCE_VISUALS, IOT_AUTONOMOUS_AGENTS_VISUALS, LOCOMOTION_MOVEMENT_VISUALS, MEASUREMENT_SENSING_VISUALS, MEDIA_ANALYTICS_VISUALS, MULTISENSORY_HAPTIC_VISUALS, MUSICAL_SOUND_VISUALS, MUSIC_PERFORMANCE_VISUALS, NARRATIVE_STORYTELLING_VISUALS, NETWORKING_AI_VISUALS, NPC_ROLES_VISUALS, OBJECT_INTERACTION_VISUALS, PARSER_CORE_UI_VISUALS, PHYSICAL_AFFORDANCES_VISUALS, PHYSICS_EXPANSION_VISUALS, PROCEDURAL_GENERATION_VISUALS, RESOURCE_GATHERING_VISUALS, SAFETY_BOUNDARIES_VISUALS, SIGNS_COMMUNICATION_VISUALS, SIMPLE_MODIFIERS_VISUALS, SOCIAL_COMMERCE_VISUALS, SOCIAL_EFFECTS_VISUALS, SPORTS_FITNESS_VISUALS, STATE_PERSISTENCE_VISUALS, TRANSPORTATION_VEHICLES_VISUALS, VOLUMETRIC_WEBGPU_VISUALS, WEATHER_PARTICLES_VISUALS, XR_PLATFORM_VISUALS } from './chunk-H5Z7NASB.js';
2
- import { init_ProvenanceSemiring, ProvenanceSemiring } from './chunk-A7PIMZGU.js';
3
- import { init_TraitVisualRegistry, init_types, init_TraitCompositor, TraitCompositor, TraitVisualRegistry } from './chunk-DXJQDCFL.js';
4
- import { init_DomainBlockCompilerMixin, compileDomainBlocks, compileSimulationBlock, simulationToR3F, compileWeatherBlock, weatherToR3F, compileAudioSourceBlock, audioSourceToR3F, compilePostProcessingBlock, postProcessingToR3F, compileParticleBlock, particlesToR3F, compilePhysicsBlock, physicsToR3F, compileMaterialBlock, materialToR3F } from './chunk-YQK5JNFK.js';
5
- import { init_CompilerBase, UnauthorizedCompilerAccessError, escapeStringValue } from './chunk-6XSERL6L.js';
6
- import { __esm, __export } from './chunk-2CWOLHTE.js';
7
- import { getRBAC, WorkflowStep, ResourceType } from '@holoscript/platform';
8
-
9
- // src/traits/visual/presets/hologram-media.visual.ts
10
- var HOLOGRAM_MEDIA_VISUALS;
11
- var init_hologram_media_visual = __esm({
12
- "src/traits/visual/presets/hologram-media.visual.ts"() {
13
- HOLOGRAM_MEDIA_VISUALS = {
14
- depth_estimation: {
15
- material: { roughness: 0.3 },
16
- emissive: { color: "#6644FF", intensity: 0.2 },
17
- tags: ["ai", "depth", "hologram"],
18
- layer: "visual_effect"
19
- },
20
- displacement: {
21
- material: { roughness: 0.4 },
22
- emissive: { color: "#8866FF", intensity: 0.15 },
23
- tags: ["3d", "depth", "mesh"],
24
- layer: "visual_effect"
25
- },
26
- segment: {
27
- material: { roughness: 0.3 },
28
- emissive: { color: "#FF44AA", intensity: 0.15 },
29
- tags: ["ai", "segmentation", "mask"],
30
- layer: "visual_effect"
31
- },
32
- animated_texture: {
33
- material: { roughness: 0.3 },
34
- emissive: { color: "#44FFAA", intensity: 0.15 },
35
- tags: ["animation", "texture", "gif"],
36
- layer: "visual_effect"
37
- },
38
- holographic_sprite: {
39
- material: { roughness: 0.2 },
40
- emissive: { color: "#AA44FF", intensity: 0.3 },
41
- tags: ["hologram", "sprite", "3d"],
42
- layer: "visual_effect"
43
- },
44
- quilt: {
45
- material: { roughness: 0.3 },
46
- emissive: { color: "#44AAFF", intensity: 0.2 },
47
- tags: ["hologram", "multiview", "looking-glass"],
48
- layer: "visual_effect"
49
- },
50
- gaussian_splatting: {
51
- material: { roughness: 0.2 },
52
- emissive: { color: "#AACCFF", intensity: 0.15 },
53
- tags: ["3d", "photorealistic", "splat"],
54
- layer: "visual_effect"
55
- },
56
- spatial_video: {
57
- material: { roughness: 0.3 },
58
- emissive: { color: "#FF8844", intensity: 0.15 },
59
- tags: ["video", "stereo", "spatial"],
60
- layer: "visual_effect"
61
- },
62
- image: {
63
- material: { roughness: 0.4 },
64
- tags: ["media", "texture", "source"],
65
- layer: "base_material"
66
- },
67
- depth_sequence: {
68
- material: { roughness: 0.3 },
69
- emissive: { color: "#6644FF", intensity: 0.1 },
70
- tags: ["video", "depth", "temporal"],
71
- layer: "visual_effect"
72
- },
73
- temporal_smoothing: {
74
- material: { roughness: 0.3 },
75
- tags: ["processing", "temporal"],
76
- layer: "visual_effect"
77
- },
78
- depth_to_normal: {
79
- material: { roughness: 0.3 },
80
- emissive: { color: "#8888FF", intensity: 0.1 },
81
- tags: ["processing", "normal-map"],
82
- layer: "visual_effect"
83
- }
84
- };
85
- }
86
- });
87
-
88
- // src/traits/visual/presets/gaps-physics.visual.ts
89
- var GAPS_PHYSICS_VISUALS;
90
- var init_gaps_physics_visual = __esm({
91
- "src/traits/visual/presets/gaps-physics.visual.ts"() {
92
- GAPS_PHYSICS_VISUALS = /* @__PURE__ */ new Map([
93
- // --- Pillar A: Unified Physics ---
94
- [
95
- "fluid",
96
- {
97
- material: {
98
- type: "physical",
99
- color: "#1a6fc4",
100
- metalness: 0,
101
- roughness: 0.05,
102
- transmission: 0.95,
103
- ior: 1.33,
104
- thickness: 0.5
105
- },
106
- layers: [
107
- {
108
- type: "effect",
109
- name: "ssfr",
110
- priority: 50,
111
- config: {
112
- resolutionScale: 0.5,
113
- absorptionColor: [0.4, 0.04, 0],
114
- absorptionStrength: 2,
115
- fresnelPower: 0.02,
116
- refractionStrength: 0.1
117
- }
118
- }
119
- ]
120
- }
121
- ],
122
- [
123
- "soft_body_pro",
124
- {
125
- material: {
126
- type: "physical",
127
- color: "#e8a87c",
128
- metalness: 0,
129
- roughness: 0.6
130
- },
131
- layers: [
132
- {
133
- type: "deformation",
134
- name: "pbd_tearing",
135
- priority: 45,
136
- config: { tearThreshold: 0.8, tearColor: "#8b0000" }
137
- }
138
- ]
139
- }
140
- ],
141
- [
142
- "crowd_sim",
143
- {
144
- material: {
145
- type: "standard",
146
- color: "#7b68ee"
147
- },
148
- layers: [
149
- {
150
- type: "instanced",
151
- name: "crowd_instances",
152
- priority: 30,
153
- config: { maxInstances: 1e4, lodLevels: 3 }
154
- }
155
- ]
156
- }
157
- ],
158
- [
159
- "deformable_terrain",
160
- {
161
- material: {
162
- type: "standard",
163
- color: "#8b7355",
164
- roughness: 0.9
165
- },
166
- layers: [
167
- {
168
- type: "displacement",
169
- name: "heightmap_erosion",
170
- priority: 40,
171
- config: { displacementScale: 5 }
172
- }
173
- ]
174
- }
175
- ],
176
- [
177
- "volumetric_clouds",
178
- {
179
- material: {
180
- type: "shader",
181
- color: "#ffffff"
182
- },
183
- layers: [
184
- {
185
- type: "volumetric",
186
- name: "cloud_raymarcher",
187
- priority: 80,
188
- config: {
189
- absorptionCoeff: 0.04,
190
- scatteringCoeff: 0.06,
191
- phaseG: 0.3,
192
- maxSteps: 64
193
- }
194
- }
195
- ]
196
- }
197
- ],
198
- [
199
- "god_rays",
200
- {
201
- material: {
202
- type: "shader",
203
- color: "#fffde7"
204
- },
205
- layers: [
206
- {
207
- type: "post_process",
208
- name: "volumetric_light",
209
- priority: 85,
210
- config: { decay: 0.96, weight: 0.5, exposure: 0.3, samples: 100 }
211
- }
212
- ]
213
- }
214
- ],
215
- // --- Weather Hub ---
216
- [
217
- "weather",
218
- {
219
- material: {
220
- type: "none",
221
- color: "#87ceeb"
222
- },
223
- layers: [
224
- {
225
- type: "ambient",
226
- name: "weather_atmosphere",
227
- priority: 90,
228
- config: { affectsLighting: true, affectsFog: true }
229
- }
230
- ]
231
- }
232
- ],
233
- // --- Pillar B: Persistent World ---
234
- [
235
- "world_state",
236
- {
237
- material: {
238
- type: "none",
239
- color: "#4a90d9"
240
- },
241
- layers: []
242
- }
243
- ],
244
- [
245
- "spatial_voice",
246
- {
247
- material: {
248
- type: "none",
249
- color: "#90ee90"
250
- },
251
- layers: [
252
- {
253
- type: "indicator",
254
- name: "voice_range",
255
- priority: 10,
256
- config: { showRadius: true, radiusColor: "#90ee9040" }
257
- }
258
- ]
259
- }
260
- ],
261
- [
262
- "lip_sync",
263
- {
264
- material: {
265
- type: "none",
266
- color: "#ffb6c1"
267
- },
268
- layers: [
269
- {
270
- type: "morph",
271
- name: "viseme_blendshapes",
272
- priority: 60,
273
- config: { blendShapePrefix: "viseme_" }
274
- }
275
- ]
276
- }
277
- ],
278
- // --- Pillar C: Living Economy ---
279
- [
280
- "ai_companion",
281
- {
282
- material: {
283
- type: "standard",
284
- color: "#dda0dd",
285
- emissive: "#330033",
286
- emissiveIntensity: 0.2
287
- },
288
- layers: [
289
- {
290
- type: "indicator",
291
- name: "ai_thinking",
292
- priority: 15,
293
- config: { pulseColor: "#9b59b6", pulseSpeed: 1.5 }
294
- }
295
- ]
296
- }
297
- ],
298
- [
299
- "token_gated",
300
- {
301
- material: {
302
- type: "standard",
303
- color: "#ffd700",
304
- metalness: 0.8,
305
- roughness: 0.2
306
- },
307
- layers: [
308
- {
309
- type: "barrier",
310
- name: "token_gate_barrier",
311
- priority: 70,
312
- config: { barrierColor: "#ffd70060", shimmer: true }
313
- }
314
- ]
315
- }
316
- ],
317
- [
318
- "moderation",
319
- {
320
- material: {
321
- type: "none",
322
- color: "#ff6347"
323
- },
324
- layers: []
325
- }
326
- ],
327
- [
328
- "anti_grief",
329
- {
330
- material: {
331
- type: "none",
332
- color: "#32cd32"
333
- },
334
- layers: [
335
- {
336
- type: "shield",
337
- name: "grief_shield",
338
- priority: 95,
339
- config: { shieldColor: "#32cd3230" }
340
- }
341
- ]
342
- }
343
- ]
344
- ]);
345
- }
346
- });
347
-
348
- // src/traits/visual/presets/phone-sleeve-vr.visual.ts
349
- var PHONE_SLEEVE_VR_VISUALS;
350
- var init_phone_sleeve_vr_visual = __esm({
351
- "src/traits/visual/presets/phone-sleeve-vr.visual.ts"() {
352
- PHONE_SLEEVE_VR_VISUALS = {
353
- // --- Hardware Form Factor ---
354
- phone_sleeve: {
355
- material: { roughness: 0.3, metalness: 0.6 },
356
- emissive: { color: "#00CCFF", intensity: 0.2 },
357
- tags: ["vr", "phone", "sleeve", "headset"],
358
- layer: "visual_effect"
359
- },
360
- sleeve_nfc_trigger: {
361
- material: { roughness: 0.4 },
362
- emissive: { color: "#FFD700", intensity: 0.15 },
363
- tags: ["nfc", "trigger", "hardware"],
364
- layer: "visual_effect"
365
- },
366
- sleeve_lens_profile: {
367
- material: { roughness: 0.1, metalness: 0 },
368
- opacity: 0.6,
369
- tags: ["lens", "optics"],
370
- layer: "visual_effect"
371
- },
372
- phone_detection: {
373
- material: { roughness: 0.4 },
374
- emissive: { color: "#44FF88", intensity: 0.1 },
375
- tags: ["detection", "calibration"],
376
- layer: "visual_effect"
377
- },
378
- // --- Display ---
379
- stereo_split: {
380
- material: { roughness: 0.2 },
381
- emissive: { color: "#FF44AA", intensity: 0.2 },
382
- tags: ["stereoscopic", "display", "split"],
383
- layer: "visual_effect"
384
- },
385
- barrel_distortion: {
386
- material: { roughness: 0.3 },
387
- emissive: { color: "#AA44FF", intensity: 0.15 },
388
- tags: ["distortion", "shader", "lens"],
389
- layer: "visual_effect"
390
- },
391
- chromatic_aberration_fix: {
392
- material: { roughness: 0.3 },
393
- emissive: { color: "#FF8800", intensity: 0.1 },
394
- tags: ["color", "correction", "lens"],
395
- layer: "visual_effect"
396
- },
397
- ipd_adjust: {
398
- material: { roughness: 0.4 },
399
- emissive: { color: "#44CCFF", intensity: 0.1 },
400
- tags: ["calibration", "ipd", "comfort"],
401
- layer: "visual_effect"
402
- },
403
- // --- Sensor / Tracking ---
404
- gyro_head_tracking: {
405
- material: { roughness: 0.4 },
406
- emissive: { color: "#00FF88", intensity: 0.15 },
407
- tags: ["tracking", "gyroscope", "3dof"],
408
- layer: "visual_effect"
409
- },
410
- accel_sensor_fusion: {
411
- material: { roughness: 0.4 },
412
- emissive: { color: "#00CC66", intensity: 0.1 },
413
- tags: ["sensor", "accelerometer", "fusion"],
414
- layer: "visual_effect"
415
- },
416
- mag_drift_correction: {
417
- material: { roughness: 0.4 },
418
- emissive: { color: "#8844FF", intensity: 0.1 },
419
- tags: ["magnetometer", "drift", "correction"],
420
- layer: "visual_effect"
421
- },
422
- positional_estimation: {
423
- material: { roughness: 0.4 },
424
- emissive: { color: "#FFAA00", intensity: 0.15 },
425
- tags: ["6dof", "vio", "tracking"],
426
- layer: "visual_effect"
427
- },
428
- // --- Interaction ---
429
- gaze_cursor: {
430
- material: { roughness: 0.2 },
431
- emissive: { color: "#FFFFFF", intensity: 0.3 },
432
- tags: ["gaze", "cursor", "reticle"],
433
- layer: "visual_effect"
434
- },
435
- gaze_dwell_select: {
436
- material: { roughness: 0.3 },
437
- emissive: { color: "#FFFF44", intensity: 0.2 },
438
- tags: ["gaze", "dwell", "selection"],
439
- layer: "visual_effect"
440
- },
441
- bt_controller: {
442
- material: { roughness: 0.5, metalness: 0.3 },
443
- tags: ["bluetooth", "controller", "input"],
444
- layer: "visual_effect"
445
- },
446
- tap_select: {
447
- material: { roughness: 0.4 },
448
- emissive: { color: "#44FF44", intensity: 0.1 },
449
- tags: ["tap", "capacitive", "input"],
450
- layer: "visual_effect"
451
- },
452
- voice_command: {
453
- material: { roughness: 0.4 },
454
- emissive: { color: "#4488FF", intensity: 0.1 },
455
- tags: ["voice", "speech", "command"],
456
- layer: "visual_effect"
457
- },
458
- // --- Performance ---
459
- thermal_throttle: {
460
- material: { roughness: 0.6 },
461
- emissive: { color: "#FF4400", intensity: 0.2 },
462
- tags: ["thermal", "throttle", "performance"],
463
- layer: "visual_effect"
464
- },
465
- battery_aware_lod: {
466
- material: { roughness: 0.5 },
467
- emissive: { color: "#44FF00", intensity: 0.1 },
468
- tags: ["battery", "lod", "adaptive"],
469
- layer: "visual_effect"
470
- },
471
- sleeve_foveated: {
472
- material: { roughness: 0.3 },
473
- emissive: { color: "#CC44FF", intensity: 0.15 },
474
- tags: ["foveated", "rendering", "performance"],
475
- layer: "visual_effect"
476
- },
477
- low_persistence: {
478
- material: { roughness: 0.2 },
479
- emissive: { color: "#88CCFF", intensity: 0.1 },
480
- tags: ["display", "persistence", "blur"],
481
- layer: "visual_effect"
482
- },
483
- // --- Comfort ---
484
- vr_comfort_vignette: {
485
- material: { roughness: 0.5 },
486
- opacity: 0.7,
487
- tags: ["comfort", "vignette", "motion"],
488
- layer: "visual_effect"
489
- },
490
- reorient_snap: {
491
- material: { roughness: 0.4 },
492
- emissive: { color: "#44FFCC", intensity: 0.1 },
493
- tags: ["snap", "recenter", "comfort"],
494
- layer: "visual_effect"
495
- },
496
- static_horizon: {
497
- material: { roughness: 0.4 },
498
- emissive: { color: "#88FF88", intensity: 0.1 },
499
- tags: ["horizon", "stability", "nausea"],
500
- layer: "visual_effect"
501
- },
502
- session_timer: {
503
- material: { roughness: 0.4 },
504
- emissive: { color: "#FFCC00", intensity: 0.15 },
505
- tags: ["timer", "health", "breaks"],
506
- layer: "visual_effect"
507
- }
508
- };
509
- }
510
- });
511
-
512
- // src/traits/visual/index.ts
513
- function registerAllPresets() {
514
- const registry = TraitVisualRegistry.getInstance();
515
- for (const presetMap of ALL_PRESETS) {
516
- registry.registerBatch(presetMap);
517
- }
518
- }
519
- var ALL_PRESETS;
520
- var init_visual = __esm({
521
- "src/traits/visual/index.ts"() {
522
- init_TraitVisualRegistry();
523
- init_types();
524
- init_TraitVisualRegistry();
525
- init_material_properties_visual();
526
- init_surface_texture_visual();
527
- init_lighting_visual();
528
- init_gems_minerals_visual();
529
- init_fabric_cloth_visual();
530
- init_visual_effects_visual();
531
- init_age_condition_visual();
532
- init_water_fluid_visual();
533
- init_weather_phenomena_visual();
534
- init_emotion_mood_visual();
535
- init_size_scale_visual();
536
- init_environmental_biome_visual();
537
- init_magic_fantasy_visual();
538
- init_scifi_technology_visual();
539
- init_creatures_mythical_visual();
540
- init_nature_life_visual();
541
- init_furniture_decor_visual();
542
- init_construction_building_visual();
543
- init_containers_storage_visual();
544
- init_shape_form_visual();
545
- init_animals_visual();
546
- init_maritime_naval_visual();
547
- init_time_period_visual();
548
- init_accessibility_visual();
549
- init_accessibility_extended_visual();
550
- init_architecture_realestate_visual();
551
- init_audio_visual();
552
- init_cooking_food_visual();
553
- init_core_vr_interaction_visual();
554
- init_data_visualization_visual();
555
- init_education_learning_visual();
556
- init_environment_input_visual();
557
- init_game_mechanics_visual();
558
- init_geospatial_web3_visual();
559
- init_healthcare_medical_visual();
560
- init_humanoid_avatar_visual();
561
- init_intelligence_behavior_visual();
562
- init_interop_copresence_visual();
563
- init_iot_autonomous_agents_visual();
564
- init_locomotion_movement_visual();
565
- init_measurement_sensing_visual();
566
- init_media_analytics_visual();
567
- init_multisensory_haptic_visual();
568
- init_musical_sound_visual();
569
- init_music_performance_visual();
570
- init_narrative_storytelling_visual();
571
- init_networking_ai_visual();
572
- init_npc_roles_visual();
573
- init_object_interaction_visual();
574
- init_parser_core_ui_visual();
575
- init_physical_affordances_visual();
576
- init_physics_expansion_visual();
577
- init_procedural_generation_visual();
578
- init_resource_gathering_visual();
579
- init_safety_boundaries_visual();
580
- init_signs_communication_visual();
581
- init_simple_modifiers_visual();
582
- init_social_commerce_visual();
583
- init_social_effects_visual();
584
- init_sports_fitness_visual();
585
- init_state_persistence_visual();
586
- init_transportation_vehicles_visual();
587
- init_volumetric_webgpu_visual();
588
- init_weather_particles_visual();
589
- init_xr_platform_visual();
590
- init_hologram_media_visual();
591
- init_gaps_physics_visual();
592
- init_phone_sleeve_vr_visual();
593
- ALL_PRESETS = [
594
- // Original 12
595
- MATERIAL_PROPERTIES_VISUALS,
596
- SURFACE_TEXTURE_VISUALS,
597
- LIGHTING_VISUALS,
598
- GEMS_MINERALS_VISUALS,
599
- FABRIC_CLOTH_VISUALS,
600
- VISUAL_EFFECTS_VISUALS,
601
- AGE_CONDITION_VISUALS,
602
- WATER_FLUID_VISUALS,
603
- WEATHER_PHENOMENA_VISUALS,
604
- EMOTION_MOOD_VISUALS,
605
- SIZE_SCALE_VISUALS,
606
- ENVIRONMENTAL_BIOME_VISUALS,
607
- // Expansion wave 1
608
- MAGIC_FANTASY_VISUALS,
609
- SCIFI_TECHNOLOGY_VISUALS,
610
- CREATURES_MYTHICAL_VISUALS,
611
- NATURE_LIFE_VISUALS,
612
- FURNITURE_DECOR_VISUALS,
613
- CONSTRUCTION_BUILDING_VISUALS,
614
- CONTAINERS_STORAGE_VISUALS,
615
- SHAPE_FORM_VISUALS,
616
- ANIMALS_VISUALS,
617
- MARITIME_NAVAL_VISUALS,
618
- TIME_PERIOD_VISUALS,
619
- // Expansion wave 2 — full coverage
620
- ACCESSIBILITY_VISUALS,
621
- ACCESSIBILITY_EXTENDED_VISUALS,
622
- ARCHITECTURE_REALESTATE_VISUALS,
623
- AUDIO_VISUALS,
624
- COOKING_FOOD_VISUALS,
625
- CORE_VR_INTERACTION_VISUALS,
626
- DATA_VISUALIZATION_VISUALS,
627
- EDUCATION_LEARNING_VISUALS,
628
- ENVIRONMENT_INPUT_VISUALS,
629
- GAME_MECHANICS_VISUALS,
630
- GEOSPATIAL_WEB3_VISUALS,
631
- HEALTHCARE_MEDICAL_VISUALS,
632
- HUMANOID_AVATAR_VISUALS,
633
- INTELLIGENCE_BEHAVIOR_VISUALS,
634
- INTEROP_COPRESENCE_VISUALS,
635
- IOT_AUTONOMOUS_AGENTS_VISUALS,
636
- LOCOMOTION_MOVEMENT_VISUALS,
637
- MEASUREMENT_SENSING_VISUALS,
638
- MEDIA_ANALYTICS_VISUALS,
639
- MULTISENSORY_HAPTIC_VISUALS,
640
- MUSICAL_SOUND_VISUALS,
641
- MUSIC_PERFORMANCE_VISUALS,
642
- NARRATIVE_STORYTELLING_VISUALS,
643
- NETWORKING_AI_VISUALS,
644
- NPC_ROLES_VISUALS,
645
- OBJECT_INTERACTION_VISUALS,
646
- PARSER_CORE_UI_VISUALS,
647
- PHYSICAL_AFFORDANCES_VISUALS,
648
- PHYSICS_EXPANSION_VISUALS,
649
- PROCEDURAL_GENERATION_VISUALS,
650
- RESOURCE_GATHERING_VISUALS,
651
- SAFETY_BOUNDARIES_VISUALS,
652
- SIGNS_COMMUNICATION_VISUALS,
653
- SIMPLE_MODIFIERS_VISUALS,
654
- SOCIAL_COMMERCE_VISUALS,
655
- SOCIAL_EFFECTS_VISUALS,
656
- SPORTS_FITNESS_VISUALS,
657
- STATE_PERSISTENCE_VISUALS,
658
- TRANSPORTATION_VEHICLES_VISUALS,
659
- VOLUMETRIC_WEBGPU_VISUALS,
660
- WEATHER_PARTICLES_VISUALS,
661
- XR_PLATFORM_VISUALS,
662
- // Hologram Media Pipeline
663
- HOLOGRAM_MEDIA_VISUALS,
664
- // GAPS Feature Roadmap — Phase 1
665
- GAPS_PHYSICS_VISUALS,
666
- // Phone Sleeve VR — smartphone-as-headset
667
- PHONE_SLEEVE_VR_VISUALS
668
- ];
669
- registerAllPresets();
670
- }
671
- });
672
-
673
- // src/compiler/ObjectPool.ts
674
- var ASTNodePool;
675
- var init_ObjectPool = __esm({
676
- "src/compiler/ObjectPool.ts"() {
677
- ASTNodePool = class {
678
- /**
679
- * @param factory Creates a fresh instance of the node.
680
- * @param resetter Resets the node state before it is handed out again.
681
- * @param initialCapacity How many nodes to pre-allocate.
682
- */
683
- constructor(factory, resetter, initialCapacity = 1e4) {
684
- this.pool = [];
685
- this.factory = factory;
686
- this.resetter = resetter;
687
- for (let i = 0; i < initialCapacity; i++) {
688
- this.pool.push(this.factory());
689
- }
690
- }
691
- /**
692
- * Acquire a node from the pool, or create a new one if the pool is empty.
693
- */
694
- acquire() {
695
- if (this.pool.length > 0) {
696
- const node = this.pool.pop();
697
- this.resetter(node);
698
- return node;
699
- }
700
- return this.factory();
701
- }
702
- /**
703
- * Release a node back to the pool to be reused.
704
- */
705
- release(node) {
706
- this.pool.push(node);
707
- }
708
- /**
709
- * Release an array of nodes back to the pool.
710
- */
711
- releaseAll(nodes) {
712
- for (const node of nodes) {
713
- this.pool.push(node);
714
- }
715
- }
716
- /**
717
- * Clear the pool, allowing garbage collection.
718
- */
719
- clear() {
720
- this.pool.length = 0;
721
- }
722
- };
723
- }
724
- });
725
-
726
- // src/compiler/R3FCompiler.ts
727
- var R3FCompiler_exports = {};
728
- __export(R3FCompiler_exports, {
729
- ENVIRONMENT_PRESETS: () => ENVIRONMENT_PRESETS,
730
- MATERIAL_PRESETS: () => MATERIAL_PRESETS,
731
- QUALITY_TIER_SCALES: () => QUALITY_TIER_SCALES,
732
- R3FCompiler: () => R3FCompiler,
733
- UI_COMPONENT_PRESETS: () => UI_COMPONENT_PRESETS
734
- });
735
- var r3fNodePool, MATERIAL_PRESETS, ENVIRONMENT_PRESETS, MESH_TYPES, UI_COMPONENT_PRESETS, QUALITY_TIER_SCALES, R3FCompiler;
736
- var init_R3FCompiler = __esm({
737
- "src/compiler/R3FCompiler.ts"() {
738
- init_TraitCompositor();
739
- init_ProvenanceSemiring();
740
- init_visual();
741
- init_DomainBlockCompilerMixin();
742
- init_CompilerBase();
743
- init_ObjectPool();
744
- r3fNodePool = new ASTNodePool(
745
- () => ({ type: "", props: {} }),
746
- (node) => {
747
- node.type = "";
748
- node.id = void 0;
749
- node.props = {};
750
- node.children = void 0;
751
- node.traits = void 0;
752
- node.directives = void 0;
753
- node.assetMaturity = void 0;
754
- },
755
- 0
756
- // Was 20000 — demand-allocate instead of pre-allocating
757
- );
758
- MATERIAL_PRESETS = {
759
- plastic: { roughness: 0.5, metalness: 0, clearcoat: 0.1 },
760
- metal: { roughness: 0.2, metalness: 1 },
761
- chrome: { roughness: 0.05, metalness: 1, envMapIntensity: 1.5 },
762
- gold: { roughness: 0.3, metalness: 1, color: "#ffd700" },
763
- copper: { roughness: 0.4, metalness: 1, color: "#b87333" },
764
- glass: {
765
- roughness: 0,
766
- metalness: 0,
767
- transmission: 0.95,
768
- ior: 1.5,
769
- thickness: 0.5,
770
- transparent: true
771
- },
772
- crystal: {
773
- roughness: 0,
774
- metalness: 0.1,
775
- transmission: 0.9,
776
- ior: 2,
777
- iridescence: 1,
778
- iridescenceIOR: 1.3
779
- },
780
- wood: { roughness: 0.8, metalness: 0 },
781
- fabric: {
782
- roughness: 0.95,
783
- metalness: 0,
784
- sheen: 0.5,
785
- sheenRoughness: 0.8,
786
- sheenColor: "#ffffff"
787
- },
788
- rubber: { roughness: 0.9, metalness: 0 },
789
- leather: {
790
- roughness: 0.7,
791
- metalness: 0,
792
- sheen: 0.3,
793
- sheenRoughness: 0.6,
794
- sheenColor: "#3d2b1f"
795
- },
796
- water: {
797
- roughness: 0,
798
- metalness: 0,
799
- transmission: 0.9,
800
- ior: 1.33,
801
- transparent: true,
802
- color: "#006994"
803
- },
804
- emissive: { roughness: 0.5, metalness: 0, emissiveIntensity: 2 },
805
- hologram: {
806
- roughness: 0,
807
- metalness: 0.3,
808
- transparent: true,
809
- opacity: 0.6,
810
- emissiveIntensity: 1
811
- },
812
- stone: { roughness: 0.85, metalness: 0, color: "#808080" },
813
- marble: { roughness: 0.15, metalness: 0, color: "#F0EDE6", envMapIntensity: 0.8 },
814
- shiny: { roughness: 0.05, metalness: 0.3, envMapIntensity: 1.5, clearcoat: 0.8 },
815
- neon: {
816
- roughness: 0,
817
- metalness: 0,
818
- emissiveIntensity: 3,
819
- transparent: true,
820
- opacity: 0.9
821
- },
822
- toon: { roughness: 1, metalness: 0 },
823
- wireframe: { roughness: 0.5, metalness: 0.5, wireframe: true },
824
- velvet: {
825
- roughness: 1,
826
- metalness: 0,
827
- sheen: 1,
828
- sheenRoughness: 0.8,
829
- sheenColor: "#ffffff",
830
- clearcoat: 0.3
831
- },
832
- xray: { roughness: 0, metalness: 0, transparent: true, opacity: 0.3, emissiveIntensity: 0.5 },
833
- gradient: { roughness: 0.5, metalness: 0 },
834
- matte: { roughness: 1, metalness: 0 },
835
- // ===========================================================================
836
- // REALISTIC FABRICS — differentiated by sheen, roughness, and anisotropy
837
- // ===========================================================================
838
- cotton: {
839
- roughness: 0.95,
840
- metalness: 0,
841
- sheen: 0.6,
842
- sheenRoughness: 0.9,
843
- sheenColor: "#ffffff"
844
- },
845
- polyester: {
846
- roughness: 0.7,
847
- metalness: 0,
848
- sheen: 0.8,
849
- sheenRoughness: 0.4,
850
- sheenColor: "#e8e8e8"
851
- },
852
- silk: {
853
- roughness: 0.3,
854
- metalness: 0,
855
- sheen: 1,
856
- sheenRoughness: 0.2,
857
- sheenColor: "#fffaf0",
858
- anisotropy: 0.8,
859
- anisotropyRotation: 0
860
- },
861
- satin: {
862
- roughness: 0.25,
863
- metalness: 0,
864
- sheen: 0.9,
865
- sheenRoughness: 0.15,
866
- sheenColor: "#fff5ee",
867
- anisotropy: 0.6,
868
- anisotropyRotation: 0
869
- },
870
- linen: {
871
- roughness: 0.9,
872
- metalness: 0,
873
- sheen: 0.4,
874
- sheenRoughness: 0.85,
875
- sheenColor: "#f5f0e8"
876
- },
877
- wool: {
878
- roughness: 1,
879
- metalness: 0,
880
- sheen: 0.7,
881
- sheenRoughness: 1,
882
- sheenColor: "#e8dcc8"
883
- },
884
- denim: {
885
- roughness: 0.85,
886
- metalness: 0,
887
- color: "#2b4570",
888
- sheen: 0.5,
889
- sheenRoughness: 0.7,
890
- sheenColor: "#4a6fa5"
891
- },
892
- canvas: {
893
- roughness: 0.95,
894
- metalness: 0,
895
- color: "#c8b88a",
896
- sheen: 0.3,
897
- sheenRoughness: 0.9,
898
- sheenColor: "#d4c9a8"
899
- },
900
- burlap: {
901
- roughness: 1,
902
- metalness: 0,
903
- color: "#8b7355",
904
- sheen: 0.2,
905
- sheenRoughness: 1,
906
- sheenColor: "#a08060"
907
- },
908
- // ===========================================================================
909
- // SKIN & ORGANIC — differentiated by subsurface scattering
910
- // ===========================================================================
911
- skin: {
912
- roughness: 0.5,
913
- metalness: 0,
914
- color: "#e8b89d",
915
- thickness: 0.8,
916
- attenuationColor: "#cc4422",
917
- attenuationDistance: 0.5
918
- },
919
- skin_dark: {
920
- roughness: 0.45,
921
- metalness: 0,
922
- color: "#8d5524",
923
- thickness: 1,
924
- attenuationColor: "#661111",
925
- attenuationDistance: 0.3
926
- },
927
- // Dragon / creature material presets
928
- dragon_bone: {
929
- roughness: 0.35,
930
- metalness: 0.15,
931
- color: "#e8dcc8"
932
- },
933
- dragon_leather: {
934
- roughness: 0.8,
935
- metalness: 0,
936
- color: "#5c3a21"
937
- },
938
- dragon_scale: {
939
- roughness: 0.25,
940
- metalness: 0.4,
941
- color: "#1a0d3d"
942
- },
943
- obsidian: {
944
- roughness: 0.05,
945
- metalness: 0.1,
946
- color: "#0d0d0d",
947
- clearcoat: 0.9,
948
- clearcoatRoughness: 0.1,
949
- envMapIntensity: 1.2
950
- },
951
- skin_pale: {
952
- roughness: 0.55,
953
- metalness: 0,
954
- color: "#fde0c8",
955
- thickness: 0.6,
956
- attenuationColor: "#ee5533",
957
- attenuationDistance: 0.6
958
- },
959
- candle_wax: {
960
- roughness: 0.7,
961
- metalness: 0,
962
- color: "#fff8dc",
963
- thickness: 2,
964
- attenuationColor: "#ffaa44",
965
- attenuationDistance: 0.3,
966
- transmission: 0.15
967
- },
968
- jade: {
969
- roughness: 0.2,
970
- metalness: 0,
971
- color: "#00a86b",
972
- thickness: 1.5,
973
- attenuationColor: "#004d32",
974
- attenuationDistance: 1,
975
- transmission: 0.1
976
- },
977
- milk: {
978
- roughness: 0.3,
979
- metalness: 0,
980
- color: "#fdfff5",
981
- thickness: 1,
982
- attenuationColor: "#fff5d6",
983
- attenuationDistance: 0.2,
984
- transmission: 0.6,
985
- ior: 1.35
986
- },
987
- leaf: {
988
- roughness: 0.6,
989
- metalness: 0,
990
- color: "#228b22",
991
- thickness: 0.3,
992
- attenuationColor: "#44cc22",
993
- attenuationDistance: 0.5
994
- },
995
- honey: {
996
- roughness: 0.1,
997
- metalness: 0,
998
- color: "#eb9605",
999
- thickness: 1.5,
1000
- attenuationColor: "#cc6600",
1001
- attenuationDistance: 0.4,
1002
- transmission: 0.7,
1003
- ior: 1.5
1004
- },
1005
- // ===========================================================================
1006
- // MUD & EARTH — differentiated by roughness, color, and subtle properties
1007
- // ===========================================================================
1008
- clay_mud: {
1009
- roughness: 0.95,
1010
- metalness: 0,
1011
- color: "#8b4513",
1012
- thickness: 0.5,
1013
- attenuationColor: "#663311",
1014
- attenuationDistance: 0.8
1015
- },
1016
- sandy_mud: {
1017
- roughness: 0.85,
1018
- metalness: 0.02,
1019
- color: "#c2a66b"
1020
- },
1021
- wet_mud: {
1022
- roughness: 0.4,
1023
- metalness: 0,
1024
- color: "#3d2b1f",
1025
- clearcoat: 0.6,
1026
- clearcoatRoughness: 0.2
1027
- },
1028
- dry_earth: {
1029
- roughness: 1,
1030
- metalness: 0,
1031
- color: "#9b7653"
1032
- },
1033
- peat: {
1034
- roughness: 0.9,
1035
- metalness: 0,
1036
- color: "#2d1f0e"
1037
- },
1038
- red_clay: {
1039
- roughness: 0.95,
1040
- metalness: 0,
1041
- color: "#cc4b2e",
1042
- thickness: 0.4,
1043
- attenuationColor: "#993322",
1044
- attenuationDistance: 0.6
1045
- },
1046
- volcanic_ash: {
1047
- roughness: 0.8,
1048
- metalness: 0.05,
1049
- color: "#3c3c3c"
1050
- },
1051
- wet_sand: {
1052
- roughness: 0.6,
1053
- metalness: 0.02,
1054
- color: "#c2b280",
1055
- clearcoat: 0.3,
1056
- clearcoatRoughness: 0.4
1057
- },
1058
- dry_sand: {
1059
- roughness: 0.95,
1060
- metalness: 0.02,
1061
- color: "#e0cc8e"
1062
- },
1063
- // ===========================================================================
1064
- // METALS (BRUSHED/ANISOTROPIC) — directional roughness
1065
- // ===========================================================================
1066
- brushed_steel: {
1067
- roughness: 0.35,
1068
- metalness: 1,
1069
- color: "#c0c0c0",
1070
- anisotropy: 0.7,
1071
- anisotropyRotation: 0
1072
- },
1073
- brushed_aluminum: {
1074
- roughness: 0.3,
1075
- metalness: 1,
1076
- color: "#d0d0d0",
1077
- anisotropy: 0.8,
1078
- anisotropyRotation: 0
1079
- },
1080
- brushed_copper: {
1081
- roughness: 0.35,
1082
- metalness: 1,
1083
- color: "#b87333",
1084
- anisotropy: 0.6,
1085
- anisotropyRotation: 0
1086
- },
1087
- cast_iron: {
1088
- roughness: 0.7,
1089
- metalness: 0.9,
1090
- color: "#3a3a3a"
1091
- },
1092
- bronze: {
1093
- roughness: 0.45,
1094
- metalness: 1,
1095
- color: "#cd7f32"
1096
- },
1097
- silver: {
1098
- roughness: 0.15,
1099
- metalness: 1,
1100
- color: "#c0c0c0",
1101
- envMapIntensity: 1.3
1102
- },
1103
- platinum: {
1104
- roughness: 0.2,
1105
- metalness: 1,
1106
- color: "#e5e4e2",
1107
- envMapIntensity: 1.2
1108
- },
1109
- rust: {
1110
- roughness: 0.9,
1111
- metalness: 0.3,
1112
- color: "#8b3a15"
1113
- },
1114
- // ===========================================================================
1115
- // HAIR & FIBERS — anisotropy-driven
1116
- // ===========================================================================
1117
- hair_dark: {
1118
- roughness: 0.35,
1119
- metalness: 0,
1120
- color: "#1a1209",
1121
- anisotropy: 1,
1122
- anisotropyRotation: Math.PI / 2,
1123
- sheen: 0.3,
1124
- sheenRoughness: 0.3,
1125
- sheenColor: "#2a2219"
1126
- },
1127
- hair_blonde: {
1128
- roughness: 0.3,
1129
- metalness: 0,
1130
- color: "#c8a55a",
1131
- anisotropy: 1,
1132
- anisotropyRotation: Math.PI / 2,
1133
- sheen: 0.4,
1134
- sheenRoughness: 0.25,
1135
- sheenColor: "#d4b86a"
1136
- },
1137
- hair_red: {
1138
- roughness: 0.35,
1139
- metalness: 0,
1140
- color: "#8b3a15",
1141
- anisotropy: 1,
1142
- anisotropyRotation: Math.PI / 2,
1143
- sheen: 0.35,
1144
- sheenRoughness: 0.3,
1145
- sheenColor: "#a04520"
1146
- },
1147
- // ===========================================================================
1148
- // WET SURFACES — clearcoat simulates water film
1149
- // ===========================================================================
1150
- wet_stone: {
1151
- roughness: 0.3,
1152
- metalness: 0,
1153
- color: "#606060",
1154
- clearcoat: 0.8,
1155
- clearcoatRoughness: 0.1
1156
- },
1157
- wet_wood: {
1158
- roughness: 0.4,
1159
- metalness: 0,
1160
- color: "#5a3a1a",
1161
- clearcoat: 0.7,
1162
- clearcoatRoughness: 0.15
1163
- },
1164
- wet_concrete: {
1165
- roughness: 0.5,
1166
- metalness: 0,
1167
- color: "#707070",
1168
- clearcoat: 0.5,
1169
- clearcoatRoughness: 0.2
1170
- },
1171
- // ===========================================================================
1172
- // FOOD & ORGANIC — SSS-heavy
1173
- // ===========================================================================
1174
- fruit: {
1175
- roughness: 0.4,
1176
- metalness: 0,
1177
- color: "#ff4444",
1178
- thickness: 0.8,
1179
- attenuationColor: "#cc2200",
1180
- attenuationDistance: 0.5,
1181
- clearcoat: 0.3,
1182
- clearcoatRoughness: 0.2
1183
- },
1184
- cheese: {
1185
- roughness: 0.7,
1186
- metalness: 0,
1187
- color: "#ffc125",
1188
- thickness: 1.2,
1189
- attenuationColor: "#cc9900",
1190
- attenuationDistance: 0.4
1191
- },
1192
- bread: {
1193
- roughness: 0.95,
1194
- metalness: 0,
1195
- color: "#c4a35a",
1196
- thickness: 0.3,
1197
- attenuationColor: "#8b6914",
1198
- attenuationDistance: 0.8
1199
- },
1200
- chocolate: {
1201
- roughness: 0.5,
1202
- metalness: 0,
1203
- color: "#3b1e08",
1204
- clearcoat: 0.2,
1205
- clearcoatRoughness: 0.3
1206
- },
1207
- // ===========================================================================
1208
- // COATED SURFACES — clearcoat-driven
1209
- // ===========================================================================
1210
- car_paint: {
1211
- roughness: 0.1,
1212
- metalness: 0,
1213
- clearcoat: 1,
1214
- clearcoatRoughness: 0.05
1215
- },
1216
- lacquer: {
1217
- roughness: 0.05,
1218
- metalness: 0,
1219
- clearcoat: 1,
1220
- clearcoatRoughness: 0.02
1221
- },
1222
- varnished_wood: {
1223
- roughness: 0.3,
1224
- metalness: 0,
1225
- color: "#8b5e3c",
1226
- clearcoat: 0.9,
1227
- clearcoatRoughness: 0.1
1228
- },
1229
- glazed_ceramic: {
1230
- roughness: 0.15,
1231
- metalness: 0,
1232
- color: "#f0ede6",
1233
- clearcoat: 0.8,
1234
- clearcoatRoughness: 0.05
1235
- },
1236
- enamel: {
1237
- roughness: 0.1,
1238
- metalness: 0,
1239
- clearcoat: 0.9,
1240
- clearcoatRoughness: 0.03
1241
- },
1242
- // ===========================================================================
1243
- // IRIDESCENT — thin-film interference
1244
- // ===========================================================================
1245
- soap_bubble: {
1246
- roughness: 0,
1247
- metalness: 0,
1248
- transmission: 0.9,
1249
- ior: 1.33,
1250
- transparent: true,
1251
- opacity: 0.3,
1252
- iridescence: 1,
1253
- iridescenceIOR: 1.5
1254
- },
1255
- oil_slick: {
1256
- roughness: 0,
1257
- metalness: 0.1,
1258
- color: "#1a1a2e",
1259
- iridescence: 1,
1260
- iridescenceIOR: 1.8
1261
- },
1262
- beetle_shell: {
1263
- roughness: 0.2,
1264
- metalness: 0.3,
1265
- color: "#0a3d0a",
1266
- iridescence: 0.8,
1267
- iridescenceIOR: 1.6,
1268
- clearcoat: 0.5,
1269
- clearcoatRoughness: 0.1
1270
- },
1271
- pearl: {
1272
- roughness: 0.15,
1273
- metalness: 0,
1274
- color: "#fdeef4",
1275
- iridescence: 0.6,
1276
- iridescenceIOR: 1.3,
1277
- sheen: 0.3,
1278
- sheenRoughness: 0.2,
1279
- sheenColor: "#fff0f5"
1280
- },
1281
- abalone: {
1282
- roughness: 0.1,
1283
- metalness: 0.1,
1284
- color: "#e0f0e8",
1285
- iridescence: 1,
1286
- iridescenceIOR: 1.5
1287
- },
1288
- // ===========================================================================
1289
- // GEMSTONES — transmission + IOR + iridescence
1290
- // ===========================================================================
1291
- diamond: {
1292
- roughness: 0,
1293
- metalness: 0,
1294
- color: "#ffffff",
1295
- transmission: 0.95,
1296
- ior: 2.417,
1297
- thickness: 0.5,
1298
- transparent: true
1299
- },
1300
- ruby: {
1301
- roughness: 0.05,
1302
- metalness: 0,
1303
- color: "#e0115f",
1304
- transmission: 0.4,
1305
- ior: 1.76,
1306
- thickness: 1
1307
- },
1308
- sapphire: {
1309
- roughness: 0.05,
1310
- metalness: 0,
1311
- color: "#0f52ba",
1312
- transmission: 0.4,
1313
- ior: 1.77,
1314
- thickness: 1
1315
- },
1316
- emerald: {
1317
- roughness: 0.1,
1318
- metalness: 0,
1319
- color: "#50c878",
1320
- transmission: 0.3,
1321
- ior: 1.57,
1322
- thickness: 1.2
1323
- },
1324
- amber: {
1325
- roughness: 0.1,
1326
- metalness: 0,
1327
- color: "#ffbf00",
1328
- transmission: 0.6,
1329
- ior: 1.55,
1330
- thickness: 2,
1331
- transparent: true,
1332
- attenuationColor: "#cc6600",
1333
- attenuationDistance: 1
1334
- },
1335
- opal: {
1336
- roughness: 0.15,
1337
- metalness: 0,
1338
- color: "#e8e0d0",
1339
- iridescence: 0.9,
1340
- iridescenceIOR: 1.45,
1341
- transmission: 0.1,
1342
- ior: 1.45
1343
- },
1344
- amethyst: {
1345
- roughness: 0.05,
1346
- metalness: 0,
1347
- color: "#9966cc",
1348
- transmission: 0.5,
1349
- ior: 1.54,
1350
- thickness: 1,
1351
- transparent: true
1352
- },
1353
- topaz: {
1354
- roughness: 0.02,
1355
- metalness: 0,
1356
- color: "#ffc87c",
1357
- transmission: 0.7,
1358
- ior: 1.63,
1359
- thickness: 0.8,
1360
- transparent: true
1361
- },
1362
- turquoise: {
1363
- roughness: 0.6,
1364
- metalness: 0,
1365
- color: "#40e0d0"
1366
- },
1367
- lapis_lazuli: {
1368
- roughness: 0.4,
1369
- metalness: 0,
1370
- color: "#26619c",
1371
- clearcoat: 0.3,
1372
- clearcoatRoughness: 0.1
1373
- },
1374
- // ===========================================================================
1375
- // MORE METALS — extended metallic palette
1376
- // ===========================================================================
1377
- titanium: {
1378
- roughness: 0.25,
1379
- metalness: 1,
1380
- color: "#878681"
1381
- },
1382
- tungsten: {
1383
- roughness: 0.3,
1384
- metalness: 1,
1385
- color: "#696969"
1386
- },
1387
- tin: {
1388
- roughness: 0.35,
1389
- metalness: 1,
1390
- color: "#b0b0b0",
1391
- envMapIntensity: 0.8
1392
- },
1393
- lead: {
1394
- roughness: 0.6,
1395
- metalness: 0.9,
1396
- color: "#595959"
1397
- },
1398
- brass: {
1399
- roughness: 0.35,
1400
- metalness: 1,
1401
- color: "#b5a642"
1402
- },
1403
- wrought_iron: {
1404
- roughness: 0.7,
1405
- metalness: 0.85,
1406
- color: "#2c2c2c"
1407
- },
1408
- mercury: {
1409
- roughness: 0,
1410
- metalness: 1,
1411
- color: "#d4d4d4",
1412
- envMapIntensity: 2
1413
- },
1414
- // ===========================================================================
1415
- // NATURAL / WEATHER — environmental surfaces
1416
- // ===========================================================================
1417
- snow: {
1418
- roughness: 0.8,
1419
- metalness: 0,
1420
- color: "#f0f8ff",
1421
- thickness: 0.5,
1422
- attenuationColor: "#c8e0ff",
1423
- attenuationDistance: 2
1424
- },
1425
- fresh_snow: {
1426
- roughness: 0.6,
1427
- metalness: 0,
1428
- color: "#ffffff",
1429
- sheen: 0.3,
1430
- sheenRoughness: 0.5,
1431
- sheenColor: "#e8f0ff"
1432
- },
1433
- frost: {
1434
- roughness: 0.3,
1435
- metalness: 0,
1436
- color: "#e8f4f8",
1437
- transmission: 0.15,
1438
- ior: 1.31,
1439
- clearcoat: 0.4,
1440
- clearcoatRoughness: 0.1
1441
- },
1442
- ice: {
1443
- roughness: 0.1,
1444
- metalness: 0,
1445
- color: "#d6eaf8",
1446
- transmission: 0.8,
1447
- ior: 1.31,
1448
- transparent: true
1449
- },
1450
- moss: {
1451
- roughness: 1,
1452
- metalness: 0,
1453
- color: "#4a7c3f",
1454
- sheen: 0.2,
1455
- sheenRoughness: 1,
1456
- sheenColor: "#5a9c4f"
1457
- },
1458
- lichen: {
1459
- roughness: 0.9,
1460
- metalness: 0,
1461
- color: "#8fa37a"
1462
- },
1463
- bark: {
1464
- roughness: 0.95,
1465
- metalness: 0,
1466
- color: "#5c4033"
1467
- },
1468
- dried_leaves: {
1469
- roughness: 0.9,
1470
- metalness: 0,
1471
- color: "#8b6914",
1472
- thickness: 0.1,
1473
- attenuationColor: "#664400",
1474
- attenuationDistance: 0.3
1475
- },
1476
- // ===========================================================================
1477
- // AGED / WEATHERED — patina, tarnish, wear
1478
- // ===========================================================================
1479
- patina: {
1480
- roughness: 0.6,
1481
- metalness: 0.4,
1482
- color: "#4a9c7e"
1483
- },
1484
- tarnished_silver: {
1485
- roughness: 0.5,
1486
- metalness: 0.7,
1487
- color: "#8a8a7a"
1488
- },
1489
- aged_bronze: {
1490
- roughness: 0.55,
1491
- metalness: 0.6,
1492
- color: "#6b8e5a"
1493
- },
1494
- weathered_wood: {
1495
- roughness: 0.95,
1496
- metalness: 0,
1497
- color: "#8a8070"
1498
- },
1499
- cracked_paint: {
1500
- roughness: 0.8,
1501
- metalness: 0,
1502
- color: "#c8c0b0"
1503
- },
1504
- oxidized_copper: {
1505
- roughness: 0.65,
1506
- metalness: 0.5,
1507
- color: "#2e8b57"
1508
- },
1509
- // ===========================================================================
1510
- // CONSTRUCTION — architectural materials
1511
- // ===========================================================================
1512
- asphalt: {
1513
- roughness: 0.9,
1514
- metalness: 0,
1515
- color: "#3a3a3a"
1516
- },
1517
- cement: {
1518
- roughness: 0.85,
1519
- metalness: 0,
1520
- color: "#a0a0a0"
1521
- },
1522
- tile_ceramic: {
1523
- roughness: 0.2,
1524
- metalness: 0,
1525
- color: "#e8e0d0",
1526
- clearcoat: 0.6,
1527
- clearcoatRoughness: 0.05
1528
- },
1529
- tile_porcelain: {
1530
- roughness: 0.1,
1531
- metalness: 0,
1532
- color: "#f5f5f5",
1533
- clearcoat: 0.8,
1534
- clearcoatRoughness: 0.02
1535
- },
1536
- linoleum: {
1537
- roughness: 0.6,
1538
- metalness: 0,
1539
- color: "#c0b090",
1540
- clearcoat: 0.2,
1541
- clearcoatRoughness: 0.3
1542
- },
1543
- drywall: {
1544
- roughness: 1,
1545
- metalness: 0,
1546
- color: "#f0ece0"
1547
- },
1548
- rebar: {
1549
- roughness: 0.6,
1550
- metalness: 0.9,
1551
- color: "#5a4a3a"
1552
- },
1553
- stucco: {
1554
- roughness: 0.95,
1555
- metalness: 0,
1556
- color: "#e8dcc8"
1557
- },
1558
- gravel: {
1559
- roughness: 1,
1560
- metalness: 0.02,
1561
- color: "#8a8070"
1562
- },
1563
- // ===========================================================================
1564
- // LEATHER VARIANTS — sheen + clearcoat differentiation
1565
- // ===========================================================================
1566
- suede: {
1567
- roughness: 1,
1568
- metalness: 0,
1569
- color: "#8b6914",
1570
- sheen: 0.6,
1571
- sheenRoughness: 1,
1572
- sheenColor: "#a07828"
1573
- },
1574
- patent_leather: {
1575
- roughness: 0.05,
1576
- metalness: 0,
1577
- color: "#1a1a1a",
1578
- clearcoat: 1,
1579
- clearcoatRoughness: 0.02
1580
- },
1581
- distressed_leather: {
1582
- roughness: 0.8,
1583
- metalness: 0,
1584
- color: "#5a3a1a",
1585
- sheen: 0.15,
1586
- sheenRoughness: 0.8,
1587
- sheenColor: "#4a3010"
1588
- },
1589
- nubuck: {
1590
- roughness: 0.95,
1591
- metalness: 0,
1592
- color: "#c8a882",
1593
- sheen: 0.5,
1594
- sheenRoughness: 0.9,
1595
- sheenColor: "#d4b892"
1596
- },
1597
- // ===========================================================================
1598
- // RUBBER VARIANTS
1599
- // ===========================================================================
1600
- tire_rubber: {
1601
- roughness: 0.85,
1602
- metalness: 0,
1603
- color: "#1a1a1a"
1604
- },
1605
- silicone: {
1606
- roughness: 0.6,
1607
- metalness: 0,
1608
- color: "#e0e0e0",
1609
- thickness: 0.5,
1610
- attenuationColor: "#cccccc",
1611
- attenuationDistance: 1,
1612
- transmission: 0.05
1613
- },
1614
- latex: {
1615
- roughness: 0.3,
1616
- metalness: 0,
1617
- color: "#ffefd5",
1618
- clearcoat: 0.5,
1619
- clearcoatRoughness: 0.1,
1620
- thickness: 0.3,
1621
- attenuationColor: "#ffcc88",
1622
- attenuationDistance: 0.5
1623
- },
1624
- eraser: {
1625
- roughness: 0.95,
1626
- metalness: 0,
1627
- color: "#ff6b81"
1628
- },
1629
- // ===========================================================================
1630
- // LIQUIDS — transmission + animated surface hints
1631
- // ===========================================================================
1632
- lava: {
1633
- roughness: 0.8,
1634
- metalness: 0,
1635
- color: "#ff4400",
1636
- emissive: "#ff2200",
1637
- emissiveIntensity: 3
1638
- },
1639
- blood: {
1640
- roughness: 0.2,
1641
- metalness: 0,
1642
- color: "#8b0000",
1643
- clearcoat: 0.7,
1644
- clearcoatRoughness: 0.05,
1645
- thickness: 1,
1646
- attenuationColor: "#440000",
1647
- attenuationDistance: 0.3
1648
- },
1649
- oil_liquid: {
1650
- roughness: 0.05,
1651
- metalness: 0,
1652
- color: "#1a1a0a",
1653
- clearcoat: 0.9,
1654
- clearcoatRoughness: 0.02
1655
- },
1656
- molten_metal: {
1657
- roughness: 0.15,
1658
- metalness: 0.8,
1659
- color: "#ff8c00",
1660
- emissive: "#ff6600",
1661
- emissiveIntensity: 5
1662
- },
1663
- syrup: {
1664
- roughness: 0.1,
1665
- metalness: 0,
1666
- color: "#8b4513",
1667
- transmission: 0.4,
1668
- ior: 1.49,
1669
- thickness: 2,
1670
- attenuationColor: "#663300",
1671
- attenuationDistance: 0.5
1672
- },
1673
- // ===========================================================================
1674
- // BLACKBODY / THERMAL — temperature-driven emission
1675
- // ===========================================================================
1676
- heated_metal_low: {
1677
- roughness: 0.5,
1678
- metalness: 0.9,
1679
- color: "#4a4a4a",
1680
- emissive: "#ff1a00",
1681
- emissiveIntensity: 1.5
1682
- },
1683
- heated_metal_mid: {
1684
- roughness: 0.4,
1685
- metalness: 0.8,
1686
- color: "#5a5a5a",
1687
- emissive: "#ff6600",
1688
- emissiveIntensity: 3
1689
- },
1690
- heated_metal_hot: {
1691
- roughness: 0.3,
1692
- metalness: 0.7,
1693
- color: "#6a6a6a",
1694
- emissive: "#ffcc00",
1695
- emissiveIntensity: 5
1696
- },
1697
- heated_metal_white: {
1698
- roughness: 0.2,
1699
- metalness: 0.6,
1700
- color: "#8a8a8a",
1701
- emissive: "#ffffff",
1702
- emissiveIntensity: 8
1703
- },
1704
- ember: {
1705
- roughness: 0.9,
1706
- metalness: 0,
1707
- color: "#2a0a00",
1708
- emissive: "#ff4400",
1709
- emissiveIntensity: 2
1710
- },
1711
- coal: {
1712
- roughness: 0.85,
1713
- metalness: 0,
1714
- color: "#1a1a1a",
1715
- emissive: "#cc2200",
1716
- emissiveIntensity: 0.5
1717
- },
1718
- // ===========================================================================
1719
- // SPECIAL EFFECTS — sparkle, glow, energy
1720
- // ===========================================================================
1721
- glitter: {
1722
- roughness: 0.2,
1723
- metalness: 0.8,
1724
- color: "#ffd700",
1725
- envMapIntensity: 2
1726
- },
1727
- sequin: {
1728
- roughness: 0.05,
1729
- metalness: 1,
1730
- envMapIntensity: 2.5,
1731
- iridescence: 0.3
1732
- },
1733
- mica: {
1734
- roughness: 0.3,
1735
- metalness: 0.2,
1736
- color: "#c8b888",
1737
- iridescence: 0.4,
1738
- iridescenceIOR: 1.58,
1739
- sheen: 0.2,
1740
- sheenRoughness: 0.3,
1741
- sheenColor: "#d4c498"
1742
- },
1743
- fluorescent_green: {
1744
- roughness: 0.5,
1745
- metalness: 0,
1746
- color: "#39ff14",
1747
- emissive: "#39ff14",
1748
- emissiveIntensity: 1.5
1749
- },
1750
- fluorescent_orange: {
1751
- roughness: 0.5,
1752
- metalness: 0,
1753
- color: "#ff6700",
1754
- emissive: "#ff6700",
1755
- emissiveIntensity: 1.5
1756
- },
1757
- fluorescent_pink: {
1758
- roughness: 0.5,
1759
- metalness: 0,
1760
- color: "#ff1493",
1761
- emissive: "#ff1493",
1762
- emissiveIntensity: 1.5
1763
- },
1764
- glow_in_dark: {
1765
- roughness: 0.7,
1766
- metalness: 0,
1767
- color: "#2a3a2a",
1768
- emissive: "#44ff44",
1769
- emissiveIntensity: 0.8
1770
- },
1771
- plasma: {
1772
- roughness: 0,
1773
- metalness: 0,
1774
- color: "#4400ff",
1775
- emissive: "#8844ff",
1776
- emissiveIntensity: 4,
1777
- transparent: true,
1778
- opacity: 0.7
1779
- },
1780
- energy_field: {
1781
- roughness: 0,
1782
- metalness: 0,
1783
- emissive: "#00ccff",
1784
- emissiveIntensity: 3,
1785
- transparent: true,
1786
- opacity: 0.4,
1787
- transmission: 0.6
1788
- },
1789
- force_field: {
1790
- roughness: 0,
1791
- metalness: 0,
1792
- emissive: "#00ff88",
1793
- emissiveIntensity: 2,
1794
- transparent: true,
1795
- opacity: 0.2,
1796
- iridescence: 0.8,
1797
- iridescenceIOR: 1.5
1798
- },
1799
- // ===========================================================================
1800
- // RETROREFLECTIVE — safety, signage
1801
- // ===========================================================================
1802
- safety_vest: {
1803
- roughness: 0.6,
1804
- metalness: 0,
1805
- color: "#ccff00",
1806
- emissive: "#ccff00",
1807
- emissiveIntensity: 0.3
1808
- },
1809
- road_sign: {
1810
- roughness: 0.4,
1811
- metalness: 0.1,
1812
- color: "#ffffff",
1813
- envMapIntensity: 1.8,
1814
- emissive: "#ffffff",
1815
- emissiveIntensity: 0.2
1816
- },
1817
- reflective_tape: {
1818
- roughness: 0.2,
1819
- metalness: 0.3,
1820
- color: "#e0e0e0",
1821
- envMapIntensity: 2.5
1822
- },
1823
- // ===========================================================================
1824
- // MISC — everything else in the real world
1825
- // ===========================================================================
1826
- chalkboard: {
1827
- roughness: 0.9,
1828
- metalness: 0,
1829
- color: "#2a3a2a"
1830
- },
1831
- chalk: {
1832
- roughness: 1,
1833
- metalness: 0,
1834
- color: "#ffffff"
1835
- },
1836
- charcoal: {
1837
- roughness: 0.9,
1838
- metalness: 0,
1839
- color: "#1a1a1a"
1840
- },
1841
- cork: {
1842
- roughness: 0.95,
1843
- metalness: 0,
1844
- color: "#b88a50"
1845
- },
1846
- felt: {
1847
- roughness: 1,
1848
- metalness: 0,
1849
- color: "#5a8a5a",
1850
- sheen: 0.4,
1851
- sheenRoughness: 1,
1852
- sheenColor: "#6a9a6a"
1853
- },
1854
- sponge: {
1855
- roughness: 1,
1856
- metalness: 0,
1857
- color: "#e8c840"
1858
- },
1859
- porcelain: {
1860
- roughness: 0.1,
1861
- metalness: 0,
1862
- color: "#f8f4f0",
1863
- clearcoat: 0.7,
1864
- clearcoatRoughness: 0.02
1865
- },
1866
- terracotta: {
1867
- roughness: 0.85,
1868
- metalness: 0,
1869
- color: "#cc6644"
1870
- },
1871
- concrete_polished: {
1872
- roughness: 0.3,
1873
- metalness: 0,
1874
- color: "#a0a0a0",
1875
- clearcoat: 0.3,
1876
- clearcoatRoughness: 0.15
1877
- },
1878
- rope: {
1879
- roughness: 1,
1880
- metalness: 0,
1881
- color: "#c4a35a",
1882
- sheen: 0.2,
1883
- sheenRoughness: 1,
1884
- sheenColor: "#b89848"
1885
- },
1886
- wicker: {
1887
- roughness: 0.9,
1888
- metalness: 0,
1889
- color: "#a08050"
1890
- },
1891
- parchment: {
1892
- roughness: 0.8,
1893
- metalness: 0,
1894
- color: "#f0e6c8",
1895
- thickness: 0.1,
1896
- attenuationColor: "#d4c0a0",
1897
- attenuationDistance: 0.2
1898
- },
1899
- // ===========================================================================
1900
- // ANIMATED MATERIALS — time-driven surface effects (wired to scene.time)
1901
- // These set metadata flags that the runtime uses to drive animated shaders.
1902
- // ===========================================================================
1903
- flowing_water: {
1904
- roughness: 0,
1905
- metalness: 0,
1906
- color: "#006994",
1907
- transmission: 0.85,
1908
- ior: 1.33,
1909
- transparent: true,
1910
- _animated: { pattern: "flow", speed: 0.8, amplitude: 0.3 }
1911
- },
1912
- rippling_water: {
1913
- roughness: 0.05,
1914
- metalness: 0,
1915
- color: "#005577",
1916
- transmission: 0.8,
1917
- ior: 1.33,
1918
- transparent: true,
1919
- _animated: { pattern: "ripple", speed: 1, amplitude: 0.4 }
1920
- },
1921
- flickering_fire: {
1922
- roughness: 0.8,
1923
- metalness: 0,
1924
- color: "#ff4400",
1925
- emissive: "#ff2200",
1926
- emissiveIntensity: 3,
1927
- _animated: { pattern: "flicker", speed: 3, amplitude: 0.6 }
1928
- },
1929
- pulsing_glow: {
1930
- roughness: 0.5,
1931
- metalness: 0,
1932
- emissive: "#00ff88",
1933
- emissiveIntensity: 2,
1934
- _animated: { pattern: "pulse", speed: 1.5, amplitude: 0.5 }
1935
- },
1936
- breathing_light: {
1937
- roughness: 0.3,
1938
- metalness: 0,
1939
- emissive: "#4488ff",
1940
- emissiveIntensity: 1.5,
1941
- _animated: { pattern: "breathe", speed: 0.5, amplitude: 0.8 }
1942
- },
1943
- scrolling_lava: {
1944
- roughness: 0.8,
1945
- metalness: 0,
1946
- color: "#ff4400",
1947
- emissive: "#ff2200",
1948
- emissiveIntensity: 4,
1949
- _animated: { pattern: "scroll", speed: 0.3, amplitude: 1 }
1950
- },
1951
- waving_grass: {
1952
- roughness: 0.9,
1953
- metalness: 0,
1954
- color: "#228b22",
1955
- sheen: 0.2,
1956
- sheenRoughness: 0.8,
1957
- sheenColor: "#44cc22",
1958
- _animated: { pattern: "wave", speed: 0.8, amplitude: 0.2 }
1959
- },
1960
- flickering_neon: {
1961
- roughness: 0,
1962
- metalness: 0,
1963
- emissive: "#ff00ff",
1964
- emissiveIntensity: 3.5,
1965
- transparent: true,
1966
- opacity: 0.9,
1967
- _animated: { pattern: "flicker", speed: 5, amplitude: 0.4 }
1968
- },
1969
- pulsing_crystal: {
1970
- roughness: 0,
1971
- metalness: 0.1,
1972
- transmission: 0.8,
1973
- ior: 2,
1974
- iridescence: 0.8,
1975
- iridescenceIOR: 1.3,
1976
- emissive: "#8844ff",
1977
- emissiveIntensity: 1,
1978
- _animated: { pattern: "pulse", speed: 0.8, amplitude: 0.6 }
1979
- },
1980
- animated_hologram: {
1981
- roughness: 0,
1982
- metalness: 0.3,
1983
- transparent: true,
1984
- opacity: 0.5,
1985
- emissive: "#00ccff",
1986
- emissiveIntensity: 1.5,
1987
- _animated: { pattern: "scroll", speed: 1.5, amplitude: 0.3 }
1988
- },
1989
- boiling_surface: {
1990
- roughness: 0.7,
1991
- metalness: 0,
1992
- color: "#cc4400",
1993
- emissive: "#ff6600",
1994
- emissiveIntensity: 2,
1995
- _animated: { pattern: "noise", speed: 2, amplitude: 0.5 }
1996
- },
1997
- shimmer_heat: {
1998
- roughness: 0,
1999
- metalness: 0,
2000
- transparent: true,
2001
- opacity: 0.15,
2002
- _animated: { pattern: "wave", speed: 2, amplitude: 0.1 }
2003
- },
2004
- // ===========================================================================
2005
- // VOLUMETRIC MATERIALS — metadata for ray-marched volume rendering
2006
- // These presets describe volumetric phenomena; the runtime renders them via
2007
- // a ray marching pass on a bounding box/sphere geometry.
2008
- // ===========================================================================
2009
- fog: {
2010
- roughness: 0,
2011
- metalness: 0,
2012
- color: "#c0c0c0",
2013
- transparent: true,
2014
- opacity: 0.3,
2015
- _volumetric: { type: "fog", density: 0.3, scattering: 0.8, absorption: 0.05 }
2016
- },
2017
- dense_fog: {
2018
- roughness: 0,
2019
- metalness: 0,
2020
- color: "#a0a0a0",
2021
- transparent: true,
2022
- opacity: 0.5,
2023
- _volumetric: { type: "fog", density: 0.7, scattering: 0.9, absorption: 0.1 }
2024
- },
2025
- smoke: {
2026
- roughness: 0,
2027
- metalness: 0,
2028
- color: "#404040",
2029
- transparent: true,
2030
- opacity: 0.4,
2031
- _volumetric: {
2032
- type: "smoke",
2033
- density: 0.5,
2034
- scattering: 0.3,
2035
- absorption: 0.4,
2036
- riseSpeed: 0.5,
2037
- turbulence: 0.6
2038
- }
2039
- },
2040
- campfire_smoke: {
2041
- roughness: 0,
2042
- metalness: 0,
2043
- color: "#505050",
2044
- transparent: true,
2045
- opacity: 0.35,
2046
- _volumetric: {
2047
- type: "smoke",
2048
- density: 0.4,
2049
- scattering: 0.25,
2050
- absorption: 0.5,
2051
- riseSpeed: 0.8,
2052
- turbulence: 0.4
2053
- }
2054
- },
2055
- fire_volume: {
2056
- roughness: 0,
2057
- metalness: 0,
2058
- color: "#ff4400",
2059
- emissive: "#ff2200",
2060
- emissiveIntensity: 4,
2061
- transparent: true,
2062
- opacity: 0.7,
2063
- _volumetric: {
2064
- type: "fire",
2065
- density: 0.6,
2066
- scattering: 0.1,
2067
- absorption: 0.2,
2068
- riseSpeed: 1.2,
2069
- turbulence: 0.7,
2070
- temperature: 2500
2071
- }
2072
- },
2073
- candle_flame: {
2074
- roughness: 0,
2075
- metalness: 0,
2076
- color: "#ffaa33",
2077
- emissive: "#ff8800",
2078
- emissiveIntensity: 3,
2079
- transparent: true,
2080
- opacity: 0.6,
2081
- _volumetric: {
2082
- type: "fire",
2083
- density: 0.4,
2084
- scattering: 0.05,
2085
- absorption: 0.1,
2086
- riseSpeed: 0.3,
2087
- turbulence: 0.2,
2088
- temperature: 1800
2089
- }
2090
- },
2091
- clouds: {
2092
- roughness: 0,
2093
- metalness: 0,
2094
- color: "#ffffff",
2095
- transparent: true,
2096
- opacity: 0.6,
2097
- _volumetric: {
2098
- type: "clouds",
2099
- density: 0.4,
2100
- scattering: 0.95,
2101
- absorption: 0.02,
2102
- noiseScale: 2,
2103
- octaves: 6
2104
- }
2105
- },
2106
- storm_clouds: {
2107
- roughness: 0,
2108
- metalness: 0,
2109
- color: "#3a3a4a",
2110
- transparent: true,
2111
- opacity: 0.8,
2112
- _volumetric: {
2113
- type: "clouds",
2114
- density: 0.7,
2115
- scattering: 0.6,
2116
- absorption: 0.15,
2117
- noiseScale: 1.5,
2118
- octaves: 6
2119
- }
2120
- },
2121
- dust_motes: {
2122
- roughness: 0,
2123
- metalness: 0,
2124
- color: "#c8b888",
2125
- transparent: true,
2126
- opacity: 0.15,
2127
- _volumetric: { type: "dust", density: 0.1, scattering: 0.5, absorption: 0.02 }
2128
- },
2129
- mist: {
2130
- roughness: 0,
2131
- metalness: 0,
2132
- color: "#e0e8f0",
2133
- transparent: true,
2134
- opacity: 0.25,
2135
- _volumetric: {
2136
- type: "mist",
2137
- density: 0.2,
2138
- scattering: 0.85,
2139
- absorption: 0.03,
2140
- heightFalloff: 1.5
2141
- }
2142
- },
2143
- steam: {
2144
- roughness: 0,
2145
- metalness: 0,
2146
- color: "#e8e8e8",
2147
- transparent: true,
2148
- opacity: 0.3,
2149
- _volumetric: {
2150
- type: "steam",
2151
- density: 0.35,
2152
- scattering: 0.7,
2153
- absorption: 0.05,
2154
- riseSpeed: 1,
2155
- turbulence: 0.3
2156
- }
2157
- },
2158
- aurora_borealis: {
2159
- roughness: 0,
2160
- metalness: 0,
2161
- emissive: "#00ff88",
2162
- emissiveIntensity: 2,
2163
- transparent: true,
2164
- opacity: 0.3,
2165
- _volumetric: {
2166
- type: "aurora",
2167
- density: 0.15,
2168
- scattering: 0.1,
2169
- absorption: 0.01,
2170
- emissionIntensity: 2
2171
- }
2172
- },
2173
- nebula: {
2174
- roughness: 0,
2175
- metalness: 0,
2176
- emissive: "#ff44aa",
2177
- emissiveIntensity: 1.5,
2178
- transparent: true,
2179
- opacity: 0.4,
2180
- _volumetric: {
2181
- type: "nebula",
2182
- density: 0.25,
2183
- scattering: 0.3,
2184
- absorption: 0.05,
2185
- emissionIntensity: 1.5,
2186
- noiseScale: 1
2187
- }
2188
- },
2189
- underwater_caustics: {
2190
- roughness: 0,
2191
- metalness: 0,
2192
- color: "#003366",
2193
- transparent: true,
2194
- opacity: 0.2,
2195
- _volumetric: { type: "underwater", density: 0.15, scattering: 0.6, absorption: 0.1 }
2196
- },
2197
- god_rays: {
2198
- roughness: 0,
2199
- metalness: 0,
2200
- color: "#ffffd0",
2201
- transparent: true,
2202
- opacity: 0.15,
2203
- emissive: "#ffff88",
2204
- emissiveIntensity: 0.5,
2205
- _volumetric: { type: "god_rays", density: 0.1, scattering: 0.9, absorption: 0.01 }
2206
- },
2207
- neon_gas: {
2208
- roughness: 0,
2209
- metalness: 0,
2210
- emissive: "#ff4400",
2211
- emissiveIntensity: 3,
2212
- transparent: true,
2213
- opacity: 0.5,
2214
- _volumetric: {
2215
- type: "neon_gas",
2216
- density: 0.3,
2217
- scattering: 0.2,
2218
- absorption: 0.05,
2219
- emissionIntensity: 3
2220
- }
2221
- },
2222
- explosion: {
2223
- roughness: 0,
2224
- metalness: 0,
2225
- color: "#ff6600",
2226
- emissive: "#ff4400",
2227
- emissiveIntensity: 6,
2228
- transparent: true,
2229
- opacity: 0.8,
2230
- _volumetric: {
2231
- type: "fire",
2232
- density: 0.8,
2233
- scattering: 0.15,
2234
- absorption: 0.3,
2235
- riseSpeed: 2,
2236
- turbulence: 1,
2237
- temperature: 4e3
2238
- }
2239
- },
2240
- toxic_gas: {
2241
- roughness: 0,
2242
- metalness: 0,
2243
- color: "#44cc00",
2244
- emissive: "#33aa00",
2245
- emissiveIntensity: 1,
2246
- transparent: true,
2247
- opacity: 0.35,
2248
- _volumetric: {
2249
- type: "smoke",
2250
- density: 0.3,
2251
- scattering: 0.4,
2252
- absorption: 0.2,
2253
- riseSpeed: 0.2,
2254
- turbulence: 0.3
2255
- }
2256
- },
2257
- magical_mist: {
2258
- roughness: 0,
2259
- metalness: 0,
2260
- emissive: "#8844ff",
2261
- emissiveIntensity: 1.5,
2262
- transparent: true,
2263
- opacity: 0.3,
2264
- iridescence: 0.6,
2265
- iridescenceIOR: 1.5,
2266
- _volumetric: {
2267
- type: "mist",
2268
- density: 0.2,
2269
- scattering: 0.5,
2270
- absorption: 0.03,
2271
- emissionIntensity: 1.5
2272
- }
2273
- },
2274
- // --- Architectural & Natural Stone ---
2275
- brick: { roughness: 0.9, metalness: 0, color: "#a6523c" },
2276
- concrete: { roughness: 0.88, metalness: 0, color: "#8a8a8a" },
2277
- granite: { roughness: 0.6, metalness: 0, color: "#666670" },
2278
- sandstone: { roughness: 0.85, metalness: 0, color: "#cca66e" },
2279
- slate: { roughness: 0.7, metalness: 0, color: "#3f4450" },
2280
- adobe: { roughness: 0.95, metalness: 0, color: "#bf9160" },
2281
- plaster: { roughness: 0.82, metalness: 0, color: "#ebe8de" },
2282
- // --- Plant & Cellulose ---
2283
- bamboo: { roughness: 0.65, metalness: 0, color: "#b3a84d" },
2284
- paper: { roughness: 0.9, metalness: 0, color: "#f3f0e5" },
2285
- cardboard: { roughness: 0.88, metalness: 0, color: "#b88c58" },
2286
- // --- Organic & Animal ---
2287
- bone: { roughness: 0.7, metalness: 0, color: "#e0d4b5" },
2288
- ivory: { roughness: 0.35, metalness: 0, color: "#f0e8c5", envMapIntensity: 0.4 },
2289
- coral: { roughness: 0.75, metalness: 0, color: "#f2614d" },
2290
- shell: {
2291
- roughness: 0.25,
2292
- metalness: 0.05,
2293
- color: "#f5ede0",
2294
- iridescence: 0.8,
2295
- iridescenceIOR: 1.5,
2296
- envMapIntensity: 0.6
2297
- },
2298
- thatch: { roughness: 0.95, metalness: 0, color: "#c0a84a" },
2299
- // --- Synthetic & Engineered ---
2300
- resin: {
2301
- roughness: 0.08,
2302
- metalness: 0,
2303
- transmission: 0.75,
2304
- ior: 1.5,
2305
- color: "#e8c46a",
2306
- transparent: true,
2307
- opacity: 0.88
2308
- },
2309
- foam: { roughness: 0.95, metalness: 0, color: "#f0f0f0" },
2310
- composite: { roughness: 0.5, metalness: 0.25, color: "#333338" },
2311
- carbon_fiber: {
2312
- roughness: 0.28,
2313
- metalness: 0.6,
2314
- color: "#111114",
2315
- envMapIntensity: 1.2,
2316
- clearcoat: 0.6,
2317
- clearcoatRoughness: 0.1
2318
- },
2319
- kevlar: { roughness: 0.82, metalness: 0, color: "#ccbb66" },
2320
- fiberglass: {
2321
- roughness: 0.3,
2322
- metalness: 0.05,
2323
- transmission: 0.4,
2324
- ior: 1.45,
2325
- color: "#e0ede0",
2326
- transparent: true,
2327
- opacity: 0.92
2328
- },
2329
- stained_glass: {
2330
- roughness: 0.05,
2331
- metalness: 0,
2332
- transmission: 0.85,
2333
- ior: 1.52,
2334
- color: "#cc44ff",
2335
- transparent: true,
2336
- opacity: 0.75,
2337
- thickness: 0.3
2338
- }
2339
- };
2340
- ENVIRONMENT_PRESETS = {
2341
- forest_sunset: {
2342
- background: true,
2343
- envPreset: "sunset",
2344
- fog: { color: "#ff9966", near: 10, far: 100 },
2345
- ground: { color: "#2d5a27" },
2346
- lighting: {
2347
- ambient: { color: "#ffa366", intensity: 0.3 },
2348
- directional: { color: "#ff7700", intensity: 1.5, position: [10, 20, 5], shadows: true }
2349
- }
2350
- },
2351
- cyberpunk_city: {
2352
- background: true,
2353
- envPreset: "night",
2354
- fog: { color: "#0a0020", near: 5, far: 60 },
2355
- ground: { color: "#1a1a2e" },
2356
- lighting: {
2357
- ambient: { color: "#220044", intensity: 0.2 },
2358
- directional: { color: "#ff00ff", intensity: 0.5, position: [5, 15, 5], shadows: true },
2359
- points: [
2360
- { color: "#00ffff", intensity: 3, position: [-5, 3, -5], distance: 15 },
2361
- { color: "#ff00ff", intensity: 3, position: [5, 3, 5], distance: 15 }
2362
- ]
2363
- },
2364
- postprocessing: { bloom: { intensity: 1.5, luminanceThreshold: 0.1 } }
2365
- },
2366
- space_void: {
2367
- background: true,
2368
- envPreset: "night",
2369
- lighting: {
2370
- ambient: { color: "#111133", intensity: 0.1 },
2371
- directional: { color: "#ffffff", intensity: 0.5, position: [0, 10, 0], shadows: false }
2372
- }
2373
- },
2374
- studio: {
2375
- background: true,
2376
- envPreset: "studio",
2377
- ground: { color: "#cccccc" },
2378
- lighting: {
2379
- ambient: { color: "#ffffff", intensity: 0.4 },
2380
- directional: { color: "#ffffff", intensity: 1, position: [5, 10, 5], shadows: true }
2381
- }
2382
- },
2383
- underwater: {
2384
- background: true,
2385
- envPreset: "dawn",
2386
- fog: { color: "#003366", near: 2, far: 40 },
2387
- ground: { color: "#1a3a4a" },
2388
- lighting: {
2389
- ambient: { color: "#004488", intensity: 0.3 },
2390
- directional: { color: "#66aacc", intensity: 0.8, position: [0, 20, 0], shadows: true }
2391
- }
2392
- },
2393
- desert: {
2394
- background: true,
2395
- envPreset: "sunset",
2396
- fog: { color: "#d4a574", near: 20, far: 150 },
2397
- ground: { color: "#c4a35a" },
2398
- lighting: {
2399
- ambient: { color: "#f5deb3", intensity: 0.4 },
2400
- directional: { color: "#ffffcc", intensity: 2, position: [15, 30, 10], shadows: true }
2401
- }
2402
- }
2403
- };
2404
- MESH_TYPES = /* @__PURE__ */ new Set([
2405
- "orb",
2406
- "sphere",
2407
- "cube",
2408
- "box",
2409
- "cylinder",
2410
- "pyramid",
2411
- "cone",
2412
- "plane",
2413
- "torus",
2414
- "ring",
2415
- "capsule",
2416
- "object",
2417
- "avatar",
2418
- "dna",
2419
- "gaussian_splat",
2420
- "splat",
2421
- "nerf",
2422
- "volumetric_video",
2423
- // Procedural geometry types (hull/spline/membrane/blob/metaball)
2424
- "hull",
2425
- "spline",
2426
- "membrane",
2427
- "blob",
2428
- "metaball"
2429
- ]);
2430
- UI_COMPONENT_PRESETS = {
2431
- UIPanel: {
2432
- component: "Container",
2433
- // @react-three/uikit Container
2434
- defaultProps: {
2435
- flexDirection: "column",
2436
- padding: 16,
2437
- backgroundColor: "rgba(0, 0, 0, 0.8)",
2438
- borderRadius: 8
2439
- }
2440
- },
2441
- UIText: {
2442
- component: "Text",
2443
- // @react-three/uikit Text
2444
- defaultProps: {
2445
- fontSize: 16,
2446
- color: "white"
2447
- }
2448
- },
2449
- UIButton: {
2450
- component: "Button",
2451
- // Custom button using Container with hover
2452
- defaultProps: {
2453
- padding: 12,
2454
- paddingX: 24,
2455
- backgroundColor: "#4a90d9",
2456
- borderRadius: 4,
2457
- cursor: "pointer"
2458
- }
2459
- },
2460
- UISlider: {
2461
- component: "Slider",
2462
- // Custom slider implementation
2463
- defaultProps: {
2464
- width: 200,
2465
- height: 20,
2466
- trackColor: "#333",
2467
- fillColor: "#4a90d9",
2468
- thumbSize: 16
2469
- }
2470
- },
2471
- UIInput: {
2472
- component: "Input",
2473
- // @react-three/uikit Input
2474
- defaultProps: {
2475
- width: 200,
2476
- padding: 8,
2477
- backgroundColor: "#222",
2478
- borderColor: "#444",
2479
- borderWidth: 1,
2480
- borderRadius: 4,
2481
- color: "white"
2482
- }
2483
- },
2484
- UIImage: {
2485
- component: "Image",
2486
- // @react-three/uikit Image
2487
- defaultProps: {
2488
- objectFit: "contain"
2489
- }
2490
- },
2491
- UIChart: {
2492
- component: "Chart",
2493
- // Custom chart component
2494
- defaultProps: {
2495
- width: 300,
2496
- height: 200,
2497
- backgroundColor: "#1a1a2e"
2498
- }
2499
- },
2500
- UIGauge: {
2501
- component: "Gauge",
2502
- // Custom gauge component
2503
- defaultProps: {
2504
- size: 100,
2505
- strokeWidth: 8,
2506
- trackColor: "#333",
2507
- fillColor: "#4a90d9"
2508
- }
2509
- }
2510
- };
2511
- QUALITY_TIER_SCALES = {
2512
- low: {
2513
- particleScale: 0.25,
2514
- lodLevel: "draft",
2515
- maxLights: 2,
2516
- shadowMapSize: 512,
2517
- shaderComplexity: "basic"
2518
- },
2519
- med: {
2520
- particleScale: 0.6,
2521
- lodLevel: "mesh",
2522
- maxLights: 4,
2523
- shadowMapSize: 1024,
2524
- shaderComplexity: "standard"
2525
- },
2526
- high: {
2527
- particleScale: 1,
2528
- lodLevel: "final",
2529
- maxLights: 8,
2530
- shadowMapSize: 2048,
2531
- shaderComplexity: "physical"
2532
- },
2533
- ultra: {
2534
- particleScale: 1.5,
2535
- lodLevel: "final",
2536
- maxLights: 16,
2537
- shadowMapSize: 4096,
2538
- shaderComplexity: "physical"
2539
- }
2540
- };
2541
- R3FCompiler = class {
2542
- constructor(options = {}) {
2543
- // ─── RBAC Enforcement ─────────────────────────────────────────────────
2544
- this.compilerName = "R3FCompiler";
2545
- this.rbac = getRBAC();
2546
- this.qualityTier = options.qualityTier ?? "high";
2547
- this.tierScales = QUALITY_TIER_SCALES[this.qualityTier];
2548
- this._defaultLighting = options.defaultLighting ?? true;
2549
- }
2550
- /**
2551
- * Validate agent permissions before compilation.
2552
- * Skips validation when no token is provided (backwards compatibility).
2553
- *
2554
- * Checks:
2555
- * 1. AST read access (can the agent read AST?)
2556
- * 2. Code generation access (can the agent generate code?)
2557
- * 3. Output path scope (if outputPath provided)
2558
- *
2559
- * @param agentToken - Agent JWT token (optional for backwards compat)
2560
- * @param outputPath - Optional output file path for scope validation
2561
- * @throws UnauthorizedCompilerAccessError if token is provided but invalid/unauthorized
2562
- */
2563
- validateCompilerAccess(agentToken, outputPath) {
2564
- if (!agentToken) return;
2565
- const astDecision = this.rbac.checkAccess({
2566
- token: agentToken,
2567
- resourceType: ResourceType.AST,
2568
- operation: "read",
2569
- expectedWorkflowStep: WorkflowStep.GENERATE_ASSEMBLY
2570
- });
2571
- if (!astDecision.allowed) {
2572
- throw new UnauthorizedCompilerAccessError(astDecision, "AST access", this.compilerName);
2573
- }
2574
- const codeDecision = this.rbac.checkAccess({
2575
- token: agentToken,
2576
- resourceType: ResourceType.CODE,
2577
- operation: "write",
2578
- expectedWorkflowStep: WorkflowStep.GENERATE_ASSEMBLY
2579
- });
2580
- if (!codeDecision.allowed) {
2581
- throw new UnauthorizedCompilerAccessError(codeDecision, "code generation", this.compilerName);
2582
- }
2583
- if (outputPath) {
2584
- const outputDecision = this.rbac.checkAccess({
2585
- token: agentToken,
2586
- resourceType: ResourceType.OUTPUT,
2587
- operation: "write",
2588
- resourcePath: outputPath,
2589
- expectedWorkflowStep: WorkflowStep.SERIALIZE
2590
- });
2591
- if (!outputDecision.allowed) {
2592
- throw new UnauthorizedCompilerAccessError(
2593
- outputDecision,
2594
- `output write to '${outputPath}'`,
2595
- this.compilerName
2596
- );
2597
- }
2598
- }
2599
- }
2600
- // ─── Spread Expansion Utility ─────────────────────────────────────────
2601
- /**
2602
- * Expands spread expressions in a properties object.
2603
- * Spreads are stored with keys like `__spread_0`, `__spread_1` and have
2604
- * the structure: { type: 'spread', argument: <value> }
2605
- *
2606
- * @param props - The properties object potentially containing spreads
2607
- * @param context - Optional context for resolving references (templates, state)
2608
- * @returns A new object with spreads expanded and merged
2609
- */
2610
- expandSpreads(props, context) {
2611
- const result = {};
2612
- const spreadKeys = [];
2613
- for (const [key, value] of Object.entries(props)) {
2614
- if (key.startsWith("__spread_")) {
2615
- spreadKeys.push(key);
2616
- } else if (value && typeof value === "object" && value.type === "spread") {
2617
- spreadKeys.push(key);
2618
- } else {
2619
- if (value && typeof value === "object" && !Array.isArray(value) && !("__ref" in value) && !("__expr" in value)) {
2620
- result[key] = this.expandSpreads(value, context);
2621
- } else if (Array.isArray(value)) {
2622
- result[key] = this.expandArraySpreads(value, context);
2623
- } else {
2624
- result[key] = value;
2625
- }
2626
- }
2627
- }
2628
- for (const spreadKey of spreadKeys) {
2629
- const spreadValue = props[spreadKey];
2630
- if (spreadValue && typeof spreadValue === "object" && spreadValue.type === "spread") {
2631
- const resolved = this.resolveSpreadArgument(
2632
- spreadValue.argument,
2633
- context
2634
- );
2635
- if (resolved && typeof resolved === "object" && !Array.isArray(resolved)) {
2636
- Object.assign(result, this.expandSpreads(resolved, context));
2637
- }
2638
- }
2639
- }
2640
- for (const [key, value] of Object.entries(props)) {
2641
- if (!key.startsWith("__spread_") && !(value && typeof value === "object" && value.type === "spread")) {
2642
- if (value && typeof value === "object" && !Array.isArray(value) && !("__ref" in value) && !("__expr" in value)) {
2643
- result[key] = this.expandSpreads(value, context);
2644
- } else if (Array.isArray(value)) {
2645
- result[key] = this.expandArraySpreads(value, context);
2646
- } else {
2647
- result[key] = value;
2648
- }
2649
- }
2650
- }
2651
- return result;
2652
- }
2653
- /**
2654
- * Expands spread expressions within an array.
2655
- * Spread elements have { type: 'spread', argument: <value> }
2656
- */
2657
- expandArraySpreads(arr, context) {
2658
- const result = [];
2659
- for (const item of arr) {
2660
- if (item && typeof item === "object" && item.type === "spread") {
2661
- const resolved = this.resolveSpreadArgument(
2662
- item.argument,
2663
- context
2664
- );
2665
- if (Array.isArray(resolved)) {
2666
- result.push(...resolved);
2667
- } else if (resolved !== void 0 && resolved !== null) {
2668
- result.push(resolved);
2669
- }
2670
- } else if (item && typeof item === "object" && !Array.isArray(item)) {
2671
- result.push(this.expandSpreads(item, context));
2672
- } else {
2673
- result.push(item);
2674
- }
2675
- }
2676
- return result;
2677
- }
2678
- /**
2679
- * Resolves a spread argument to its value.
2680
- * Handles: direct values, __ref references, template references
2681
- */
2682
- resolveSpreadArgument(argument, context) {
2683
- if (argument === null || argument === void 0) {
2684
- return void 0;
2685
- }
2686
- if (typeof argument === "object" && !("__ref" in argument)) {
2687
- return argument;
2688
- }
2689
- if (typeof argument === "object" && "__ref" in argument) {
2690
- const ref = argument.__ref;
2691
- if (context?.templates) {
2692
- const template = context.templates.get(ref);
2693
- if (template) {
2694
- return template.properties || template;
2695
- }
2696
- }
2697
- if (context?.state && ref in context.state) {
2698
- return context.state[ref];
2699
- }
2700
- if (context?.state && ref.includes(".")) {
2701
- const parts = ref.split(".");
2702
- let value = context.state;
2703
- for (const part of parts) {
2704
- if (value && typeof value === "object" && part in value) {
2705
- value = value[part];
2706
- } else {
2707
- value = void 0;
2708
- break;
2709
- }
2710
- }
2711
- if (value !== void 0) {
2712
- return value;
2713
- }
2714
- }
2715
- return argument;
2716
- }
2717
- if (typeof argument === "string") {
2718
- if (context?.templates) {
2719
- const template = context.templates.get(argument);
2720
- if (template) {
2721
- return template.properties || template;
2722
- }
2723
- }
2724
- return { __ref: argument };
2725
- }
2726
- return argument;
2727
- }
2728
- // ─── HSPlusAST Compilation ────────────────────────────────────────────
2729
- compile(ast, agentToken, outputPath) {
2730
- this.validateCompilerAccess(agentToken, outputPath);
2731
- const root = this.compileNode(ast.root);
2732
- if (this.hasPostProcessing(root)) {
2733
- root.children?.unshift({
2734
- type: "EffectComposer",
2735
- props: {},
2736
- children: this.extractPostProcessingNodes(root)
2737
- });
2738
- }
2739
- this.injectDefaultLighting(root);
2740
- const domainBlocks = ast.domainBlocks ?? [];
2741
- if (domainBlocks.length > 0) {
2742
- const compiled = compileDomainBlocks(
2743
- domainBlocks,
2744
- {
2745
- material: (block) => {
2746
- const mat = compileMaterialBlock(block);
2747
- return {
2748
- type: "DomainBlockOutput",
2749
- props: {
2750
- __raw: materialToR3F(mat, this.tierScales),
2751
- __domain: "material",
2752
- __name: mat.name
2753
- },
2754
- children: []
2755
- };
2756
- },
2757
- physics: (block) => {
2758
- const phys = compilePhysicsBlock(block);
2759
- return {
2760
- type: "DomainBlockOutput",
2761
- props: {
2762
- __raw: physicsToR3F(phys),
2763
- __domain: "physics",
2764
- __name: phys.name || phys.keyword
2765
- },
2766
- children: []
2767
- };
2768
- },
2769
- vfx: (block) => {
2770
- const ps = compileParticleBlock(block);
2771
- return {
2772
- type: "DomainBlockOutput",
2773
- props: {
2774
- __raw: particlesToR3F(ps, this.tierScales),
2775
- __domain: "vfx",
2776
- __name: ps.name
2777
- },
2778
- children: []
2779
- };
2780
- },
2781
- postfx: (block) => {
2782
- const pp = compilePostProcessingBlock(block);
2783
- return {
2784
- type: "DomainBlockOutput",
2785
- props: {
2786
- __raw: postProcessingToR3F(pp),
2787
- __domain: "postfx",
2788
- __name: pp.name || "PostProcessing"
2789
- },
2790
- children: []
2791
- };
2792
- },
2793
- audio: (block) => {
2794
- const audio = compileAudioSourceBlock(block);
2795
- return {
2796
- type: "DomainBlockOutput",
2797
- props: { __raw: audioSourceToR3F(audio), __domain: "audio", __name: audio.name },
2798
- children: []
2799
- };
2800
- },
2801
- weather: (block) => {
2802
- const weather = compileWeatherBlock(block);
2803
- return {
2804
- type: "DomainBlockOutput",
2805
- props: {
2806
- __raw: weatherToR3F(weather),
2807
- __domain: "weather",
2808
- __name: weather.name || "Weather"
2809
- },
2810
- children: []
2811
- };
2812
- },
2813
- simulation: (block) => {
2814
- const sim = compileSimulationBlock(block);
2815
- return {
2816
- type: "DomainBlockOutput",
2817
- props: {
2818
- __raw: simulationToR3F(sim),
2819
- __domain: "simulation",
2820
- __name: sim.name || "Simulation"
2821
- },
2822
- children: []
2823
- };
2824
- }
2825
- }
2826
- );
2827
- if (!root.children) root.children = [];
2828
- for (const c of compiled) {
2829
- if (typeof c === "object") root.children.push(c);
2830
- }
2831
- }
2832
- return root;
2833
- }
2834
- createNode(type, props = {}, id) {
2835
- const node = r3fNodePool.acquire();
2836
- node.type = type;
2837
- node.id = id;
2838
- node.props = props;
2839
- node.children = [];
2840
- node.traits = /* @__PURE__ */ new Map();
2841
- node.directives = [];
2842
- return node;
2843
- }
2844
- compileNode(node) {
2845
- if (node.type === "system") {
2846
- return this.compileSystemNode(node);
2847
- }
2848
- if (node.type === "component") {
2849
- return this.compileComponentNode(node);
2850
- }
2851
- const rawProps = node.properties || {};
2852
- const type = this.mapType(node.type, rawProps);
2853
- const r3fNode = r3fNodePool.acquire();
2854
- r3fNode.type = type;
2855
- const rawId = node.id || node.name;
2856
- r3fNode.id = rawId ? escapeStringValue(rawId, "JSX") : void 0;
2857
- r3fNode.props = this.compileProperties(node, rawProps);
2858
- r3fNode.children = [];
2859
- r3fNode.traits = /* @__PURE__ */ new Map();
2860
- r3fNode.directives = node.directives || [];
2861
- if (node.directives) {
2862
- for (const directive of node.directives) {
2863
- if (directive.type === "trait") {
2864
- r3fNode.traits?.set(
2865
- directive.name,
2866
- directive.config
2867
- );
2868
- }
2869
- }
2870
- }
2871
- const enhanced = node;
2872
- if (enhanced.graphics) {
2873
- this.applyGraphicsConfig(r3fNode, enhanced.graphics);
2874
- }
2875
- if (enhanced.children && Array.isArray(enhanced.children)) {
2876
- r3fNode.children = enhanced.children.map(
2877
- (child) => this.compileNode(child)
2878
- );
2879
- }
2880
- return r3fNode;
2881
- }
2882
- // ─── HoloComposition Compilation (.holo files) ────────────────────────
2883
- compileComposition(composition, agentToken, outputPath) {
2884
- this.validateCompilerAccess(agentToken, outputPath);
2885
- const root = r3fNodePool.acquire();
2886
- root.type = "group";
2887
- root.id = composition.name ? escapeStringValue(composition.name, "JSX") : void 0;
2888
- root.props = {};
2889
- root.children = [];
2890
- root.traits = /* @__PURE__ */ new Map();
2891
- root.directives = [];
2892
- const templateMap = /* @__PURE__ */ new Map();
2893
- if (Array.isArray(composition.templates)) {
2894
- for (const tmpl of composition.templates) {
2895
- templateMap.set(tmpl.name, tmpl);
2896
- }
2897
- }
2898
- if (composition.children && Array.isArray(composition.children)) {
2899
- for (const child of composition.children) {
2900
- if (child.type === "template" && child.name) {
2901
- templateMap.set(child.name, child);
2902
- }
2903
- }
2904
- for (const child of composition.children) {
2905
- root.children.push(this.compileChildNode(child, templateMap));
2906
- }
2907
- }
2908
- if (composition.environment) {
2909
- root.children.push(
2910
- ...this.compileEnvironmentBlock(composition.environment)
2911
- );
2912
- }
2913
- if (Array.isArray(composition.lights)) {
2914
- for (const light of composition.lights) {
2915
- root.children.push(this.compileLightBlock(light));
2916
- }
2917
- }
2918
- if (Array.isArray(composition.objects)) {
2919
- for (const obj of composition.objects) {
2920
- root.children.push(this.compileObjectDecl(obj, templateMap));
2921
- }
2922
- }
2923
- if (Array.isArray(composition.spatialGroups)) {
2924
- for (const group of composition.spatialGroups) {
2925
- root.children.push(this.compileSpatialGroup(group, templateMap));
2926
- }
2927
- }
2928
- if (Array.isArray(composition.timelines)) {
2929
- for (const timeline of composition.timelines) {
2930
- root.children.push(this.compileTimelineBlock(timeline));
2931
- }
2932
- }
2933
- if (Array.isArray(composition.audio)) {
2934
- for (const audio of composition.audio) {
2935
- root.children.push(this.compileAudioBlock(audio));
2936
- }
2937
- }
2938
- if (Array.isArray(composition.zones)) {
2939
- for (const zone of composition.zones) {
2940
- root.children.push(this.compileZoneBlock(zone));
2941
- }
2942
- }
2943
- if (composition.ui) {
2944
- root.children.push(this.compileUIBlock(composition.ui));
2945
- }
2946
- if (Array.isArray(composition.transitions)) {
2947
- for (const transition of composition.transitions) {
2948
- root.children.push(this.compileTransitionBlock(transition));
2949
- }
2950
- }
2951
- if (Array.isArray(composition.conditionals)) {
2952
- for (const cond of composition.conditionals) {
2953
- root.children.push(this.compileConditionalBlock(cond, templateMap));
2954
- }
2955
- }
2956
- if (Array.isArray(composition.iterators)) {
2957
- for (const iter of composition.iterators) {
2958
- root.children.push(this.compileForEachBlock(iter, templateMap));
2959
- }
2960
- }
2961
- if (composition.camera) {
2962
- root.children.push(this.compileCameraBlock(composition.camera));
2963
- }
2964
- if (composition.effects) {
2965
- root.children.unshift(
2966
- this.compileEffectsBlock(composition.effects)
2967
- );
2968
- } else if (this.hasPostProcessing(root)) {
2969
- root.children.unshift({
2970
- type: "EffectComposer",
2971
- props: {},
2972
- children: this.extractPostProcessingNodes(root)
2973
- });
2974
- }
2975
- this.injectDefaultLighting(root);
2976
- return root;
2977
- }
2978
- compileLightBlock(light) {
2979
- const lightMapping = {
2980
- directional: "directionalLight",
2981
- point: "pointLight",
2982
- spot: "spotLight",
2983
- hemisphere: "hemisphereLight",
2984
- ambient: "ambientLight",
2985
- area: "rectAreaLight"
2986
- };
2987
- const type = lightMapping[light.lightType] || "directionalLight";
2988
- const props = {};
2989
- if (Array.isArray(light.properties)) {
2990
- for (const prop of light.properties) {
2991
- const key = prop.key;
2992
- const value = prop.value;
2993
- if (key === "cast_shadow" || key === "castShadow") {
2994
- props.castShadow = value;
2995
- } else if (key === "ground_color" || key === "groundColor") {
2996
- props.groundColor = value;
2997
- } else if (key === "shadow_map_size") {
2998
- props["shadow-mapSize"] = Array.isArray(value) ? value : [value, value];
2999
- } else {
3000
- props[key] = value;
3001
- }
3002
- }
3003
- }
3004
- if ((light.lightType === "directional" || light.lightType === "spot") && props.castShadow === void 0) {
3005
- props.castShadow = true;
3006
- }
3007
- const r3fNode = r3fNodePool.acquire();
3008
- r3fNode.type = type;
3009
- r3fNode.id = light.name ? escapeStringValue(light.name, "JSX") : void 0;
3010
- r3fNode.props = props;
3011
- r3fNode.children = [];
3012
- r3fNode.traits = /* @__PURE__ */ new Map();
3013
- r3fNode.directives = [];
3014
- return r3fNode;
3015
- }
3016
- compileEffectsBlock(effects) {
3017
- const children = [];
3018
- if (Array.isArray(effects.effects)) {
3019
- for (const effect of effects.effects) {
3020
- const effectMapping = {
3021
- bloom: "Bloom",
3022
- ssao: "SSAO",
3023
- vignette: "Vignette",
3024
- dof: "DepthOfField",
3025
- chromatic_aberration: "ChromaticAberration",
3026
- tone_mapping: "ToneMapping",
3027
- noise: "Noise"
3028
- };
3029
- const effectType = effect.effectType;
3030
- const type = effectMapping[effectType] || effectType;
3031
- children.push(
3032
- this.createNode(type, { ...effect.properties || {} })
3033
- );
3034
- }
3035
- }
3036
- const composer = this.createNode("EffectComposer", {});
3037
- composer.children = children;
3038
- return composer;
3039
- }
3040
- compileCameraBlock(camera) {
3041
- const props = {};
3042
- if (Array.isArray(camera.properties)) {
3043
- for (const prop of camera.properties) {
3044
- if (prop.key === "field_of_view" || prop.key === "fov") {
3045
- props.fov = prop.value;
3046
- } else if (prop.key === "look_at" || prop.key === "lookAt") {
3047
- props.lookAt = prop.value;
3048
- } else {
3049
- props[prop.key] = prop.value;
3050
- }
3051
- }
3052
- }
3053
- props.cameraType = camera.cameraType;
3054
- return this.createNode("Camera", props, "__camera");
3055
- }
3056
- compileEnvironmentBlock(env) {
3057
- const nodes = [];
3058
- const envProps = {};
3059
- if (env.properties) {
3060
- for (const prop of env.properties) {
3061
- envProps[prop.key] = prop.value;
3062
- }
3063
- }
3064
- const presetName = envProps.skybox || envProps.preset;
3065
- if (presetName) {
3066
- const preset = ENVIRONMENT_PRESETS[presetName];
3067
- if (preset) {
3068
- nodes.push(
3069
- this.createNode("Environment", {
3070
- background: true,
3071
- preset: preset.envPreset || presetName
3072
- })
3073
- );
3074
- const lighting = preset.lighting;
3075
- if (lighting?.ambient) {
3076
- nodes.push(
3077
- this.createNode("ambientLight", {
3078
- color: lighting.ambient.color,
3079
- intensity: lighting.ambient.intensity
3080
- })
3081
- );
3082
- }
3083
- if (lighting?.directional) {
3084
- const dl = lighting.directional;
3085
- nodes.push(
3086
- this.createNode("directionalLight", {
3087
- color: dl.color,
3088
- intensity: dl.intensity,
3089
- position: dl.position,
3090
- castShadow: dl.shadows !== false,
3091
- "shadow-mapSize": [2048, 2048]
3092
- })
3093
- );
3094
- }
3095
- if (Array.isArray(lighting?.points)) {
3096
- for (const pl of lighting.points) {
3097
- nodes.push(
3098
- this.createNode("pointLight", {
3099
- color: pl.color,
3100
- intensity: pl.intensity,
3101
- position: pl.position,
3102
- distance: pl.distance
3103
- })
3104
- );
3105
- }
3106
- }
3107
- const presetMap = preset;
3108
- if (presetMap.fog) {
3109
- const fogMap = presetMap.fog;
3110
- nodes.push(
3111
- this.createNode("fog", {
3112
- attach: "fog",
3113
- color: fogMap.color,
3114
- near: fogMap.near,
3115
- far: fogMap.far
3116
- })
3117
- );
3118
- }
3119
- if (presetMap.ground) {
3120
- const groundMap = presetMap.ground;
3121
- nodes.push(
3122
- this.createNode(
3123
- "mesh",
3124
- {
3125
- hsType: "plane",
3126
- rotation: [-Math.PI / 2, 0, 0],
3127
- position: [0, -0.01, 0],
3128
- receiveShadow: true,
3129
- args: [200, 200],
3130
- color: groundMap.color,
3131
- materialProps: { roughness: 0.8, metalness: 0 }
3132
- },
3133
- "__ground"
3134
- )
3135
- );
3136
- }
3137
- } else {
3138
- nodes.push(this.createNode("Environment", { background: true, preset: presetName }));
3139
- }
3140
- }
3141
- if (envProps.ambient_light !== void 0) {
3142
- nodes.push(
3143
- this.createNode("ambientLight", {
3144
- intensity: typeof envProps.ambient_light === "number" ? envProps.ambient_light : 0.5
3145
- })
3146
- );
3147
- }
3148
- const explicitFog = envProps.fog;
3149
- if (explicitFog && typeof explicitFog === "object") {
3150
- nodes.push(
3151
- this.createNode("fog", {
3152
- attach: "fog",
3153
- color: explicitFog.color || "#cccccc",
3154
- near: explicitFog.near || 10,
3155
- far: explicitFog.far || 100
3156
- })
3157
- );
3158
- }
3159
- return nodes;
3160
- }
3161
- compileObjectDecl(obj, templateMap) {
3162
- const props = {};
3163
- let geometryType = "cube";
3164
- if (obj.template && templateMap) {
3165
- const tmpl = templateMap.get(obj.template);
3166
- if (tmpl) {
3167
- const tmplTraits = tmpl.traits;
3168
- if (tmplTraits && Array.isArray(tmplTraits)) {
3169
- const existingTraitNames = new Set(
3170
- (obj.traits || []).map(
3171
- (t) => t.name
3172
- )
3173
- );
3174
- obj.traits = [
3175
- ...tmplTraits.filter(
3176
- (t) => !existingTraitNames.has(t.name)
3177
- ),
3178
- ...obj.traits || []
3179
- ];
3180
- }
3181
- const tmplProps = tmpl.properties;
3182
- if (tmplProps && Array.isArray(tmplProps)) {
3183
- const existingKeys = new Set(
3184
- (obj.properties || []).map(
3185
- (p) => p.key
3186
- )
3187
- );
3188
- const mergedProps = tmplProps.filter((p) => !existingKeys.has(p.key)).map((p) => ({
3189
- type: "ObjectProperty",
3190
- key: p.key,
3191
- value: p.value
3192
- }));
3193
- obj.properties = [...mergedProps, ...obj.properties || []];
3194
- }
3195
- }
3196
- }
3197
- if (obj.properties && Array.isArray(obj.properties)) {
3198
- const expandedProperties = [];
3199
- for (const p of obj.properties) {
3200
- const prop = p;
3201
- if (prop && prop.type === "spread") {
3202
- const resolved = this.resolveSpreadArgument(
3203
- prop.target || prop.argument,
3204
- {
3205
- templates: templateMap
3206
- }
3207
- );
3208
- if (resolved && typeof resolved === "object" && !Array.isArray(resolved)) {
3209
- for (const [key, value] of Object.entries(resolved)) {
3210
- expandedProperties.push({ key, value });
3211
- }
3212
- } else if (Array.isArray(resolved)) {
3213
- expandedProperties.push(...resolved);
3214
- }
3215
- } else {
3216
- expandedProperties.push(prop);
3217
- }
3218
- }
3219
- obj.properties = expandedProperties;
3220
- }
3221
- if (obj.properties) {
3222
- for (const p of obj.properties) {
3223
- const key = p.key;
3224
- const value = p.value;
3225
- if (key === "geometry" || key === "mesh") {
3226
- geometryType = value;
3227
- } else if (key === "type") {
3228
- const valStr = value;
3229
- if (["text", "sparkles", "portal", "audio"].includes(valStr)) {
3230
- geometryType = valStr;
3231
- } else if (["directional", "point", "spot", "hemisphere", "ambient", "area"].includes(valStr)) {
3232
- geometryType = "light";
3233
- props.lightType = valStr;
3234
- } else {
3235
- props[key] = value;
3236
- }
3237
- } else if (key === "light_type") {
3238
- props.lightType = value;
3239
- } else if (key === "position" && Array.isArray(value)) {
3240
- props.position = value;
3241
- } else if (key === "rotation" && Array.isArray(value)) {
3242
- props.rotation = value;
3243
- } else if (key === "scale") {
3244
- props.scale = Array.isArray(value) ? value : [value, value, value];
3245
- } else if (key === "color") {
3246
- props.color = value;
3247
- } else if (key === "src" || key === "model" || key === "source") {
3248
- props.src = value;
3249
- geometryType = "model";
3250
- } else if (key === "text") {
3251
- props.children = this.resolveValue(value);
3252
- props.text = this.resolveValue(value);
3253
- } else if (key === "font_size") {
3254
- props.fontSize = value;
3255
- } else if (key === "material") {
3256
- const currentMaterialProps = props.materialProps || {};
3257
- if (typeof value === "string" && MATERIAL_PRESETS[value]) {
3258
- props.materialProps = { ...MATERIAL_PRESETS[value], ...currentMaterialProps };
3259
- } else if (typeof value === "object" && value !== null) {
3260
- const valObj = value;
3261
- if (valObj.preset && typeof valObj.preset === "string" && MATERIAL_PRESETS[valObj.preset]) {
3262
- const { preset: _, ...rest } = valObj;
3263
- props.materialProps = {
3264
- ...MATERIAL_PRESETS[valObj.preset],
3265
- ...rest,
3266
- ...currentMaterialProps
3267
- };
3268
- } else {
3269
- props.materialProps = { ...currentMaterialProps, ...valObj };
3270
- }
3271
- }
3272
- } else if (key === "roughness" || key === "metalness" || key === "metallic") {
3273
- const mProps = props.materialProps || {};
3274
- mProps[key === "metallic" ? "metalness" : key] = value;
3275
- props.materialProps = mProps;
3276
- } else if (key === "opacity") {
3277
- const mProps = props.materialProps || {};
3278
- mProps.opacity = value;
3279
- mProps.transparent = value < 1;
3280
- props.materialProps = mProps;
3281
- } else if (key === "emissive") {
3282
- props.materialProps = {
3283
- ...props.materialProps || {},
3284
- emissive: value
3285
- };
3286
- } else if (key === "emissiveIntensity" || key === "emissive_intensity") {
3287
- props.materialProps = {
3288
- ...props.materialProps || {},
3289
- emissiveIntensity: value
3290
- };
3291
- } else if (key === "size") {
3292
- if (Array.isArray(value)) {
3293
- props.args = value;
3294
- }
3295
- props.size = value;
3296
- } else if (key === "radius") {
3297
- props.size = value * 2;
3298
- } else if (key === "intensity") {
3299
- props.intensity = value;
3300
- } else if (key === "cast_shadow" || key === "castShadow") {
3301
- props.castShadow = value;
3302
- } else if (key === "receiveShadow" || key === "receive_shadow") {
3303
- props.receiveShadow = value;
3304
- } else if (key === "visible") {
3305
- props[key] = value;
3306
- } else if (key === "maturity") {
3307
- props.maturityOverride = value;
3308
- } else if (key === "promoteUrl" || key === "promote_url") {
3309
- props.promoteUrl = value;
3310
- } else if (key === "collisionShape" || key === "collision_shape") {
3311
- props.collisionShape = value;
3312
- } else {
3313
- props[key] = this.resolveValue(value);
3314
- }
3315
- }
3316
- }
3317
- if (obj.traits && Array.isArray(obj.traits)) {
3318
- const semiring = new ProvenanceSemiring();
3319
- const physicsApplications = obj.traits.filter((t) => t.name === "physics" || t.name === "collidable").map((t) => {
3320
- let baseConfig = t.config || {};
3321
- if (t.name === "collidable" && !baseConfig.type)
3322
- baseConfig = { ...baseConfig, type: "fixed" };
3323
- if (t.name === "physics" && !baseConfig.type)
3324
- baseConfig = { ...baseConfig, type: "dynamic" };
3325
- return {
3326
- name: t.name,
3327
- config: baseConfig,
3328
- context: obj.provenance?.context
3329
- };
3330
- });
3331
- if (physicsApplications.length > 0) {
3332
- const { config: mergedPhysics } = semiring.add(physicsApplications);
3333
- props.rigidBody = { ...mergedPhysics };
3334
- props.collider = { type: "auto" };
3335
- if (props.rigidBody?.type === "fixed") {
3336
- props.castShadow = true;
3337
- props.receiveShadow = true;
3338
- }
3339
- }
3340
- for (const trait of obj.traits) {
3341
- const name = trait.name;
3342
- if (name === "physics" || name === "collidable") {
3343
- continue;
3344
- } else if (name === "grabbable") {
3345
- props.castShadow = true;
3346
- props.grabbable = trait.config || true;
3347
- if (!props.rigidBody) props.rigidBody = { type: "dynamic" };
3348
- if (!props.collider) props.collider = { type: "auto" };
3349
- } else if (name === "hoverable") {
3350
- props.hoverable = trait.config || true;
3351
- } else if (name === "animated") {
3352
- props.animated = trait.config || true;
3353
- } else if (name === "positional" || name === "spatial_audio") {
3354
- props.spatial = true;
3355
- } else if (name === "shadow") {
3356
- props.castShadow = true;
3357
- if (trait.config?.mapSize)
3358
- props["shadow-mapSize"] = [trait.config.mapSize, trait.config.mapSize];
3359
- } else if (name === "material") {
3360
- const presetName = trait.config?.preset;
3361
- if (presetName && typeof presetName === "string" && MATERIAL_PRESETS[presetName]) {
3362
- const { preset: _, ...rest } = trait.config;
3363
- props.materialProps = {
3364
- ...MATERIAL_PRESETS[presetName],
3365
- ...rest,
3366
- ...props.materialProps
3367
- };
3368
- } else {
3369
- props.materialProps = {
3370
- ...props.materialProps,
3371
- ...trait.config
3372
- };
3373
- }
3374
- } else if (name === "networked") {
3375
- props.networked = trait.config || true;
3376
- } else if (name === "moldable") {
3377
- props.moldable = trait.config || true;
3378
- } else if (name === "stretchable") {
3379
- props.stretchable = trait.config || true;
3380
- } else if (name === "bloom") {
3381
- props.bloom = trait.config || { intensity: 1 };
3382
- } else if (name === "portal") {
3383
- props.portal = trait.config || true;
3384
- } else if (name === "attach") {
3385
- props.attach = trait.config || true;
3386
- } else if (name === "orbit") {
3387
- props.orbit = trait.config || true;
3388
- } else if (name === "look_at") {
3389
- props.lookAtTarget = trait.config || true;
3390
- } else if (name === "follow") {
3391
- props.follow = trait.config || true;
3392
- } else if (name === "plane_detection") {
3393
- props.planeDetection = trait.config || { mode: "all" };
3394
- } else if (name === "mesh_detection") {
3395
- props.meshDetection = trait.config || { classification: true };
3396
- } else if (name === "anchor") {
3397
- props.anchor = trait.config || { type: "spatial" };
3398
- } else if (name === "persistent_anchor") {
3399
- props.persistentAnchor = trait.config || { storage: "local" };
3400
- } else if (name === "shared_anchor") {
3401
- props.sharedAnchor = trait.config || { authority: "creator" };
3402
- } else if (name === "occlusion") {
3403
- props.occlusionMode = trait.config?.mode || "environment";
3404
- props.occlusion = trait.config || true;
3405
- } else if (name === "light_estimation") {
3406
- props.lightEstimation = trait.config || { auto_apply: true };
3407
- } else if (name === "geospatial") {
3408
- props.geospatial = trait.config || true;
3409
- } else if (name === "gaussian_splat") {
3410
- props.gaussianSplat = trait.config || true;
3411
- } else if (name === "nerf") {
3412
- props.nerf = trait.config || true;
3413
- } else if (name === "volumetric_video") {
3414
- props.volumetricVideo = trait.config || true;
3415
- } else if (name === "point_cloud") {
3416
- props.pointCloud = trait.config || true;
3417
- } else if (name === "photogrammetry") {
3418
- props.photogrammetry = trait.config || true;
3419
- } else if (name === "cloth") {
3420
- props.cloth = trait.config || { stiffness: 0.8 };
3421
- if (!props.rigidBody) props.rigidBody = { type: "dynamic" };
3422
- } else if (name === "fluid") {
3423
- props.fluid = trait.config || { viscosity: 0.01 };
3424
- props.__gapsComponents = props.__gapsComponents || [];
3425
- props.__gapsComponents.push("FluidRenderer");
3426
- } else if (name === "soft_body") {
3427
- props.softBody = trait.config || { elasticity: 0.5 };
3428
- if (!props.rigidBody) props.rigidBody = { type: "dynamic" };
3429
- } else if (name === "rope") {
3430
- props.rope = trait.config || { segments: 20 };
3431
- } else if (name === "chain") {
3432
- props.chain = trait.config || { link_count: 20 };
3433
- } else if (name === "wind") {
3434
- props.wind = trait.config || { strength: 5 };
3435
- } else if (name === "buoyancy") {
3436
- props.buoyancy = trait.config || { water_level: 0 };
3437
- } else if (name === "destruction") {
3438
- props.destruction = trait.config || { health: 100 };
3439
- if (!props.rigidBody) props.rigidBody = { type: "dynamic" };
3440
- if (!props.collider) props.collider = { type: "auto" };
3441
- } else if (name === "soft_body_pro") {
3442
- props.softBodyPro = trait.config || { tear_threshold: 0.5 };
3443
- if (!props.rigidBody) props.rigidBody = { type: "dynamic" };
3444
- } else if (name === "crowd_sim") {
3445
- props.crowdSim = trait.config || { max_agents: 1e3 };
3446
- } else if (name === "deformable_terrain") {
3447
- props.deformableTerrain = trait.config || { resolution: 256 };
3448
- } else if (name === "volumetric_clouds") {
3449
- props.volumetricClouds = trait.config || { coverage: 0.5 };
3450
- props.__gapsComponents = props.__gapsComponents || [];
3451
- props.__gapsComponents.push("CloudRenderer");
3452
- } else if (name === "god_rays") {
3453
- props.godRays = trait.config || { intensity: 1 };
3454
- props.__gapsComponents = props.__gapsComponents || [];
3455
- props.__gapsComponents.push("GodRaysEffect");
3456
- } else if (name === "spatial_voice") {
3457
- props.spatialVoice = trait.config || { max_distance: 30 };
3458
- props.spatial = true;
3459
- } else if (name === "ai_companion") {
3460
- props.aiCompanion = trait.config || { personality: "friendly" };
3461
- } else if (name === "moderation") {
3462
- props.moderation = trait.config || { sensitivity: "medium" };
3463
- } else if (name === "anti_grief") {
3464
- props.antiGrief = trait.config || { detection_window: 30 };
3465
- } else if (name === "world_state") {
3466
- props.worldState = trait.config || { sync_rate: 10 };
3467
- } else if (name === "token_gated") {
3468
- props.tokenGated = trait.config || { token_contract: "", min_balance: 1 };
3469
- } else if (name === "ambisonics") {
3470
- props.ambisonics = trait.config || { order: 1 };
3471
- props.spatial = true;
3472
- } else if (name === "hrtf") {
3473
- props.hrtf = trait.config || true;
3474
- props.spatial = true;
3475
- } else if (name === "reverb_zone") {
3476
- props.reverbZone = trait.config || { preset: "room" };
3477
- } else if (name === "audio_occlusion") {
3478
- props.audioOcclusion = trait.config || true;
3479
- } else if (name === "audio_portal") {
3480
- props.audioPortal = trait.config || true;
3481
- } else if (name === "head_tracked_audio") {
3482
- props.headTrackedAudio = trait.config || true;
3483
- props.spatial = true;
3484
- } else if (name === "accessible") {
3485
- props.accessible = trait.config || { role: "generic" };
3486
- } else if (name === "alt_text") {
3487
- props.altText = trait.config?.text || "";
3488
- } else if (name === "magnifiable") {
3489
- props.magnifiable = trait.config || { max_scale: 3 };
3490
- } else if (name === "high_contrast") {
3491
- props.highContrast = trait.config || { mode: "outline" };
3492
- } else if (name === "motion_reduced") {
3493
- props.motionReduced = trait.config || true;
3494
- if (props.animated) props.animated = false;
3495
- } else if (name === "compute") {
3496
- props.compute = trait.config || true;
3497
- } else if (name === "gpu_particle") {
3498
- props.gpuParticle = trait.config || { count: 1e4 };
3499
- } else if (name === "gpu_physics") {
3500
- props.gpuPhysics = trait.config || true;
3501
- } else if (name === "digital_twin") {
3502
- props.digitalTwin = trait.config || true;
3503
- } else if (name === "sensor") {
3504
- props.sensor = trait.config || true;
3505
- } else if (name === "data_binding") {
3506
- props.dataBinding = trait.config || true;
3507
- } else if (name === "behavior_tree") {
3508
- props.behaviorTree = trait.config || true;
3509
- } else if (name === "llm_agent") {
3510
- props.llmAgent = trait.config || true;
3511
- } else if (name === "neural_link") {
3512
- props.neuralLink = trait.config || { model: "brittney-v4.gguf", temperature: 0.7 };
3513
- } else if (name === "perception") {
3514
- props.perception = trait.config || { sight_range: 20 };
3515
- } else if (name === "patrol") {
3516
- props.patrol = trait.config || true;
3517
- } else if (name === "co_located") {
3518
- props.coLocated = trait.config || true;
3519
- } else if (name === "shared_world") {
3520
- props.sharedWorld = trait.config || true;
3521
- } else if (name === "voice_proximity") {
3522
- props.voiceProximity = trait.config || { max_distance: 20 };
3523
- props.spatial = true;
3524
- } else if (name === "spatial_persona") {
3525
- props.spatialPersona = trait.config || { style: "realistic" };
3526
- } else if (name === "shareplay") {
3527
- props.sharePlay = trait.config || { activity_type: "custom" };
3528
- } else if (name === "object_tracking") {
3529
- props.objectTracking = trait.config || true;
3530
- } else if (name === "scene_reconstruction") {
3531
- props.sceneReconstruction = trait.config || { mode: "mesh" };
3532
- } else if (name === "eye_tracked") {
3533
- props.eyeTracked = true;
3534
- } else if (name === "eye_hand_fusion") {
3535
- props.eyeHandFusion = true;
3536
- } else if (name === "controlnet") {
3537
- props.controlNet = trait.config || { model: "canny" };
3538
- } else if (name === "ai_texture_gen") {
3539
- props.aiTextureGen = trait.config || { style: "photorealistic" };
3540
- } else if (name === "diffusion_realtime") {
3541
- props.diffusionRealtime = trait.config || { backend: "cuda" };
3542
- } else if (name === "ai_upscaling") {
3543
- props.aiUpscaling = trait.config || { factor: 2 };
3544
- } else if (name === "ai_inpainting") {
3545
- props.aiInpainting = trait.config || true;
3546
- } else if (name === "neural_forge") {
3547
- props.neuralForge = trait.config || true;
3548
- } else if (name === "embedding_search") {
3549
- props.embeddingSearch = trait.config || { dimensions: 1536 };
3550
- } else if (name === "ai_npc_brain") {
3551
- props.aiNpcBrain = trait.config || { model: "llm" };
3552
- } else if (name === "vector_db") {
3553
- props.vectorDb = trait.config || true;
3554
- } else if (name === "vision" || name === "ai_vision") {
3555
- props.vision = trait.config || { task: "detection" };
3556
- } else if (name === "spatial_awareness") {
3557
- props.spatialAwareness = trait.config || true;
3558
- } else if (name === "neural_animation") {
3559
- props.neuralAnimation = trait.config || { style: "motion_matching" };
3560
- } else if (name === "draft") {
3561
- props.draftMode = true;
3562
- props.draftShape = trait.config?.shape || "box";
3563
- props.draftColor = trait.config?.color || "#88aaff";
3564
- props.draftOpacity = trait.config?.opacity ?? 1;
3565
- props.draftWireframe = trait.config?.wireframe || false;
3566
- if (trait.config?.collision !== false) {
3567
- if (!props.rigidBody) props.rigidBody = { type: "fixed" };
3568
- if (!props.collider) props.collider = { type: "auto" };
3569
- }
3570
- } else {
3571
- props[name] = trait.config || true;
3572
- if (!props.__unrecognizedTraits) {
3573
- props.__unrecognizedTraits = [];
3574
- }
3575
- props.__unrecognizedTraits.push(name);
3576
- }
3577
- }
3578
- }
3579
- if (obj.traits && Array.isArray(obj.traits)) {
3580
- const traitNames = obj.traits.map(
3581
- (t) => t.name
3582
- );
3583
- const compositor = new TraitCompositor();
3584
- const composedMaterial = compositor.compose(traitNames);
3585
- if (Object.keys(composedMaterial).length > 0) {
3586
- props.materialProps = {
3587
- ...props.materialProps,
3588
- ...composedMaterial
3589
- };
3590
- }
3591
- }
3592
- let type;
3593
- if (geometryType === "model" && props.src) {
3594
- type = "gltfModel";
3595
- } else if (geometryType === "light") {
3596
- const lightType = props.lightType || props.type || "directional";
3597
- const lightMapping = {
3598
- directional: "directionalLight",
3599
- point: "pointLight",
3600
- spot: "spotLight",
3601
- hemisphere: "hemisphereLight",
3602
- ambient: "ambientLight",
3603
- area: "rectAreaLight"
3604
- };
3605
- type = lightMapping[lightType] || "directionalLight";
3606
- delete props.lightType;
3607
- } else if (geometryType === "text") {
3608
- type = "Text";
3609
- } else if (geometryType === "sparkles") {
3610
- type = "Sparkles";
3611
- } else if (geometryType === "portal") {
3612
- type = "Portal";
3613
- } else {
3614
- type = "mesh";
3615
- props.hsType = geometryType;
3616
- if (!props.args) {
3617
- const size = typeof props.size === "number" ? props.size : 1;
3618
- props.args = this.getGeometryArgs(geometryType, { size });
3619
- }
3620
- }
3621
- const r3fNode = this.createNode(type, props, obj.name);
3622
- if (props.draftMode) {
3623
- r3fNode.assetMaturity = "draft";
3624
- } else if (props.maturityOverride) {
3625
- const m = props.maturityOverride;
3626
- if (m === "draft" || m === "mesh" || m === "final") {
3627
- r3fNode.assetMaturity = m;
3628
- }
3629
- }
3630
- if (obj.children && Array.isArray(obj.children)) {
3631
- for (const child of obj.children) {
3632
- r3fNode.children.push(this.compileObjectDecl(child));
3633
- }
3634
- }
3635
- if (props.__gapsComponents && Array.isArray(props.__gapsComponents)) {
3636
- for (const componentType of props.__gapsComponents) {
3637
- const componentProps = {};
3638
- if (componentType === "CloudRenderer" && props.volumetricClouds) {
3639
- const vc = props.volumetricClouds;
3640
- componentProps.coverage = vc.coverage ?? 0.5;
3641
- componentProps.altitude = vc.altitude ?? 500;
3642
- componentProps.windOffset = vc.wind ?? [0, 0, 0];
3643
- componentProps.layers = vc.layers ?? 3;
3644
- } else if (componentType === "GodRaysEffect" && props.godRays) {
3645
- const gr = props.godRays;
3646
- componentProps.intensity = gr.intensity ?? 1;
3647
- componentProps.decay = gr.decay ?? 0.96;
3648
- componentProps.lightColor = gr.color ?? "#fffde7";
3649
- } else if (componentType === "FluidRenderer" && props.fluid) {
3650
- const fl = props.fluid;
3651
- componentProps.color = fl.color ?? "#1a6fc4";
3652
- componentProps.particleSize = fl.particle_radius ?? 0.02;
3653
- componentProps.renderMode = fl.render_mode ?? "points";
3654
- }
3655
- r3fNode.children.push(
3656
- this.createNode(componentType, componentProps, `${obj.name}-${componentType}`)
3657
- );
3658
- }
3659
- delete props.__gapsComponents;
3660
- }
3661
- return r3fNode;
3662
- }
3663
- /**
3664
- * Compile a SystemNode into an R3FNode.
3665
- *
3666
- * Systems are logical containers with state, actions, lifecycle hooks,
3667
- * and optionally child objects/UI. In the R3F tree, a system compiles
3668
- * to a group node annotated with its rich metadata (state, actions,
3669
- * hooks) so the runtime/renderer can wire up behavior.
3670
- */
3671
- compileSystemNode(node, templateMap) {
3672
- const props = {};
3673
- if (node.state) {
3674
- props.systemState = node.state;
3675
- }
3676
- if (node.actions) {
3677
- props.systemActions = node.actions;
3678
- }
3679
- if (node.hooks) {
3680
- props.systemHooks = node.hooks;
3681
- }
3682
- if (node.properties && typeof node.properties === "object") {
3683
- for (const [key, value] of Object.entries(node.properties)) {
3684
- props[key] = value;
3685
- }
3686
- }
3687
- const r3fNode = this.createNode("System", props, node.id || node.name);
3688
- if (node.directives) {
3689
- r3fNode.directives = node.directives;
3690
- }
3691
- if (node.directives) {
3692
- for (const d of node.directives) {
3693
- if (d.type === "trait") {
3694
- r3fNode.traits?.set(d.name, d.config || {});
3695
- }
3696
- }
3697
- }
3698
- if (node.children && Array.isArray(node.children)) {
3699
- for (const child of node.children) {
3700
- r3fNode.children.push(this.compileChildNode(child, templateMap));
3701
- }
3702
- }
3703
- if (node.ui && Array.isArray(node.ui)) {
3704
- for (const uiNode of node.ui) {
3705
- r3fNode.children.push(this.compileNode(uiNode));
3706
- }
3707
- }
3708
- return r3fNode;
3709
- }
3710
- /**
3711
- * Compile a ComponentNode into an R3FNode.
3712
- *
3713
- * Components are UI-focused containers with props, state, actions,
3714
- * and render/UI blocks. They compile to a group node annotated with
3715
- * component metadata for the runtime.
3716
- */
3717
- compileComponentNode(node, templateMap) {
3718
- const props = {};
3719
- if (node.props) {
3720
- props.componentProps = node.props;
3721
- }
3722
- if (node.state) {
3723
- props.componentState = node.state;
3724
- }
3725
- if (node.actions) {
3726
- props.componentActions = node.actions;
3727
- }
3728
- if (node.hooks) {
3729
- props.componentHooks = node.hooks;
3730
- }
3731
- if (node.properties && typeof node.properties === "object") {
3732
- for (const [key, value] of Object.entries(node.properties)) {
3733
- props[key] = value;
3734
- }
3735
- }
3736
- const r3fNode = this.createNode(
3737
- "Component",
3738
- props,
3739
- node.id || node.name
3740
- );
3741
- if (node.directives) {
3742
- r3fNode.directives = node.directives;
3743
- }
3744
- if (node.directives) {
3745
- for (const d of node.directives) {
3746
- if (d.type === "trait") {
3747
- r3fNode.traits?.set(d.name, d.config || {});
3748
- }
3749
- }
3750
- }
3751
- if (node.children && Array.isArray(node.children)) {
3752
- for (const child of node.children) {
3753
- r3fNode.children.push(this.compileChildNode(child, templateMap));
3754
- }
3755
- }
3756
- if (node.ui && Array.isArray(node.ui)) {
3757
- for (const uiNode of node.ui) {
3758
- r3fNode.children.push(this.compileNode(uiNode));
3759
- }
3760
- }
3761
- return r3fNode;
3762
- }
3763
- /**
3764
- * Dispatch a child node to the appropriate compile method based on its type.
3765
- * Used by compileSystemNode, compileComponentNode, and compileComposition
3766
- * when processing the parser's children array.
3767
- */
3768
- compileChildNode(child, templateMap) {
3769
- switch (child.type) {
3770
- case "system":
3771
- return this.compileSystemNode(child, templateMap);
3772
- case "component":
3773
- return this.compileComponentNode(child, templateMap);
3774
- case "object":
3775
- return this.compileObjectDecl(child, templateMap);
3776
- case "template":
3777
- if (templateMap && typeof child.name === "string") {
3778
- templateMap.set(child.name, child);
3779
- }
3780
- return this.compileTemplateNode(child, templateMap);
3781
- case "spatial_group":
3782
- return this.compileSpatialGroup(child, templateMap);
3783
- default:
3784
- return this.compileNode(child);
3785
- }
3786
- }
3787
- /**
3788
- * Compile a template node. Templates define reusable types.
3789
- * In the R3F tree, they compile to an empty group (they're not
3790
- * rendered directly — objects "using" them inherit their properties).
3791
- */
3792
- compileTemplateNode(node, _templateMap) {
3793
- const props = {};
3794
- if (node.state || node.properties?.state) {
3795
- props.templateState = node.state || node.properties?.state;
3796
- }
3797
- if (node.properties) {
3798
- for (const [key, value] of Object.entries(node.properties)) {
3799
- if (key !== "state") {
3800
- props[key] = value;
3801
- }
3802
- }
3803
- }
3804
- return this.createNode("Template", props, node.name);
3805
- }
3806
- compileSpatialGroup(group, templateMap) {
3807
- const props = {};
3808
- if (group.properties) {
3809
- for (const prop of group.properties) {
3810
- if (prop.key === "position") props.position = prop.value;
3811
- else if (prop.key === "rotation") props.rotation = prop.value;
3812
- else if (prop.key === "scale")
3813
- props.scale = Array.isArray(prop.value) ? prop.value : [prop.value, prop.value, prop.value];
3814
- }
3815
- }
3816
- const node = this.createNode("group", props, group.name);
3817
- if (group.objects) {
3818
- for (const obj of group.objects)
3819
- node.children.push(this.compileObjectDecl(obj, templateMap));
3820
- }
3821
- if (group.groups) {
3822
- for (const sub of group.groups)
3823
- node.children.push(this.compileSpatialGroup(sub, templateMap));
3824
- }
3825
- return node;
3826
- }
3827
- compileTimelineBlock(timeline) {
3828
- const entries = [];
3829
- if (timeline.entries) {
3830
- for (const entry of timeline.entries) {
3831
- const action = entry.action;
3832
- const entryProps = { time: entry.time, actionKind: action.kind };
3833
- if (action.kind === "animate") {
3834
- entryProps.target = action.target;
3835
- entryProps.properties = action.properties;
3836
- } else if (action.kind === "emit") {
3837
- entryProps.event = action.event;
3838
- if (action.data !== void 0) entryProps.data = action.data;
3839
- } else if (action.kind === "call") {
3840
- entryProps.method = action.method;
3841
- if (action.args) entryProps.args = action.args;
3842
- }
3843
- entries.push(this.createNode("TimelineEntry", entryProps));
3844
- }
3845
- }
3846
- const safeName = timeline.name ? escapeStringValue(timeline.name, "JSX") : void 0;
3847
- const timelineNode = this.createNode(
3848
- "Timeline",
3849
- { autoplay: timeline.autoplay, loop: timeline.loop },
3850
- safeName
3851
- );
3852
- timelineNode.children = entries;
3853
- return timelineNode;
3854
- }
3855
- compileAudioBlock(audio) {
3856
- const props = {};
3857
- if (audio.properties) {
3858
- for (const prop of audio.properties) {
3859
- if (prop.key === "src" || prop.key === "source") {
3860
- props.src = prop.value;
3861
- } else if (prop.key === "rolloff") {
3862
- props.rolloffFactor = prop.value;
3863
- } else {
3864
- props[prop.key] = prop.value;
3865
- }
3866
- }
3867
- }
3868
- const safeName = audio.name ? escapeStringValue(audio.name, "JSX") : void 0;
3869
- return this.createNode("Audio", props, safeName);
3870
- }
3871
- compileZoneBlock(zone) {
3872
- const props = {};
3873
- if (zone.properties) {
3874
- for (const prop of zone.properties) {
3875
- props[prop.key] = prop.value;
3876
- }
3877
- }
3878
- if (zone.handlers && zone.handlers.length > 0) {
3879
- props.handlers = zone.handlers.map(
3880
- (h) => ({
3881
- event: h.event,
3882
- parameters: h.parameters,
3883
- body: h.body
3884
- })
3885
- );
3886
- }
3887
- const safeName = zone.name ? escapeStringValue(zone.name, "JSX") : void 0;
3888
- return this.createNode("Zone", props, safeName);
3889
- }
3890
- compileUIBlock(ui) {
3891
- const children = [];
3892
- if (ui.elements) {
3893
- for (const el of ui.elements) {
3894
- const elProps = {};
3895
- if (el.properties) {
3896
- for (const prop of el.properties) {
3897
- if (prop.key === "font_size") {
3898
- elProps.fontSize = prop.value;
3899
- } else {
3900
- elProps[prop.key] = this.resolveValue(prop.value);
3901
- }
3902
- }
3903
- }
3904
- const safeElName = el.name ? escapeStringValue(el.name, "JSX") : void 0;
3905
- children.push(this.createNode("UIElement", elProps, safeElName));
3906
- }
3907
- }
3908
- const uiNode = this.createNode("UI", {}, "__ui");
3909
- uiNode.children = children;
3910
- return uiNode;
3911
- }
3912
- compileTransitionBlock(transition) {
3913
- const props = {};
3914
- if (transition.properties) {
3915
- for (const prop of transition.properties) {
3916
- props[prop.key] = prop.value;
3917
- }
3918
- }
3919
- const safeName = transition.name ? escapeStringValue(transition.name, "JSX") : void 0;
3920
- return this.createNode("Transition", props, safeName);
3921
- }
3922
- compileConditionalBlock(cond, templateMap) {
3923
- const children = [];
3924
- if (cond.objects) {
3925
- for (const obj of cond.objects)
3926
- children.push(this.compileObjectDecl(obj, templateMap));
3927
- }
3928
- if (cond.spatialGroups) {
3929
- for (const g of cond.spatialGroups)
3930
- children.push(this.compileSpatialGroup(g, templateMap));
3931
- }
3932
- const elseChildren = [];
3933
- if (cond.elseObjects) {
3934
- for (const obj of cond.elseObjects)
3935
- elseChildren.push(this.compileObjectDecl(obj, templateMap));
3936
- }
3937
- if (cond.elseSpatialGroups) {
3938
- for (const g of cond.elseSpatialGroups)
3939
- elseChildren.push(this.compileSpatialGroup(g, templateMap));
3940
- }
3941
- const conditionalNode = this.createNode("ConditionalGroup", {
3942
- condition: cond.condition,
3943
- elseChildren: elseChildren.length > 0 ? elseChildren : void 0
3944
- });
3945
- conditionalNode.children = children;
3946
- return conditionalNode;
3947
- }
3948
- compileForEachBlock(iter, templateMap) {
3949
- const templateChildren = [];
3950
- if (iter.objects) {
3951
- for (const obj of iter.objects)
3952
- templateChildren.push(this.compileObjectDecl(obj, templateMap));
3953
- }
3954
- if (iter.spatialGroups) {
3955
- for (const g of iter.spatialGroups)
3956
- templateChildren.push(this.compileSpatialGroup(g, templateMap));
3957
- }
3958
- const forEachNode = this.createNode("ForEachGroup", {
3959
- variable: iter.variable,
3960
- iterable: iter.iterable
3961
- });
3962
- forEachNode.children = templateChildren;
3963
- return forEachNode;
3964
- }
3965
- /**
3966
- * Resolve a property value, converting bind expressions into runtime-reactive markers.
3967
- */
3968
- resolveValue(value) {
3969
- if (value && typeof value === "object" && value.__bind) {
3970
- return {
3971
- __bind: true,
3972
- source: value.source,
3973
- transform: value.transform
3974
- };
3975
- }
3976
- return value;
3977
- }
3978
- // ─── Shared Helpers ───────────────────────────────────────────────────
3979
- injectDefaultLighting(root) {
3980
- if (!this._defaultLighting) return;
3981
- if (!this.treeHasLights(root)) {
3982
- const shadowSize = this.tierScales.shadowMapSize;
3983
- root.children?.unshift(
3984
- this.createNode("ambientLight", { intensity: 0.4, color: "#ffffff" }),
3985
- this.createNode("directionalLight", {
3986
- intensity: 1,
3987
- position: [5, 10, 5],
3988
- castShadow: true,
3989
- "shadow-mapSize": [shadowSize, shadowSize],
3990
- color: "#ffffff"
3991
- })
3992
- );
3993
- }
3994
- }
3995
- treeHasLights(node) {
3996
- if (node.type.toLowerCase().includes("light")) return true;
3997
- return node.children?.some((c) => this.treeHasLights(c)) || false;
3998
- }
3999
- hasPostProcessing(node) {
4000
- if (node.traits?.has("bloom") || node.traits?.has("postprocessing"))
4001
- return true;
4002
- if (node.props.bloom) return true;
4003
- return node.children?.some((c) => this.hasPostProcessing(c)) || false;
4004
- }
4005
- extractPostProcessingNodes(node) {
4006
- const effects = [];
4007
- const ppTrait = node.traits?.get(
4008
- "postprocessing"
4009
- );
4010
- if (ppTrait) {
4011
- if (ppTrait.bloom)
4012
- effects.push(this.createNode("Bloom", ppTrait.bloom));
4013
- if (ppTrait.ssao)
4014
- effects.push(this.createNode("SSAO", ppTrait.ssao));
4015
- if (ppTrait.vignette)
4016
- effects.push(this.createNode("Vignette", ppTrait.vignette));
4017
- }
4018
- if (node.props.bloom) {
4019
- effects.push(
4020
- this.createNode(
4021
- "Bloom",
4022
- typeof node.props.bloom === "object" ? node.props.bloom : { intensity: 1 }
4023
- )
4024
- );
4025
- }
4026
- node.children?.forEach((child) => effects.push(...this.extractPostProcessingNodes(child)));
4027
- return effects;
4028
- }
4029
- mapType(type, props) {
4030
- if (type === "environment") {
4031
- if (props.name && typeof props.name === "string" && ENVIRONMENT_PRESETS[props.name]) {
4032
- Object.assign(props, ENVIRONMENT_PRESETS[props.name]);
4033
- }
4034
- return "Environment";
4035
- }
4036
- if (type === "light") {
4037
- const lightType = props.type || "directional";
4038
- const lightMapping = {
4039
- directional: "directionalLight",
4040
- point: "pointLight",
4041
- spot: "spotLight",
4042
- hemisphere: "hemisphereLight",
4043
- ambient: "ambientLight",
4044
- area: "rectAreaLight"
4045
- };
4046
- return lightMapping[lightType] || "directionalLight";
4047
- }
4048
- if (type === "portal") return "Portal";
4049
- if (type === "sparkles") return "Sparkles";
4050
- if (MESH_TYPES.has(type)) {
4051
- props.hsType = type;
4052
- return "mesh";
4053
- }
4054
- const mapping = {
4055
- ambient_light: "ambientLight",
4056
- model: "gltfModel",
4057
- audio: "positionalAudio",
4058
- composition: "group",
4059
- scale: "group",
4060
- focus: "group",
4061
- spatial_agent: "SpatialAgent",
4062
- spatial_container: "group",
4063
- ui_panel: "UIPanel",
4064
- ui_text: "UIText",
4065
- ui_button: "UIButton",
4066
- ui_slider: "UISlider",
4067
- ui_input: "UIInput",
4068
- ui_image: "UIImage",
4069
- ui_chart: "UIChart",
4070
- ui_gauge: "UIGauge",
4071
- ui_value: "UIValue",
4072
- ui_status_indicator: "UIStatusIndicator",
4073
- tool_slot: "ToolSlot",
4074
- behavior: "group",
4075
- system: "System",
4076
- component: "Component",
4077
- avatar: "Avatar",
4078
- dna: "DNA",
4079
- gaussian_splat: "GaussianSplat",
4080
- splat: "GaussianSplat",
4081
- nerf: "NeRF",
4082
- volumetric_video: "VolumetricVideo"
4083
- };
4084
- return mapping[type] || type;
4085
- }
4086
- compileProperties(node, rawProps) {
4087
- const expandedProps = this.expandSpreads(rawProps);
4088
- const props = { ...expandedProps };
4089
- if (node.position) {
4090
- props.position = [node.position.x, node.position.y, node.position.z];
4091
- }
4092
- if (rawProps.position && Array.isArray(rawProps.position)) {
4093
- props.position = rawProps.position;
4094
- }
4095
- if (node.hologram) {
4096
- const h = node.hologram;
4097
- if (h.color) props.color = h.color;
4098
- if (MESH_TYPES.has(node.type)) {
4099
- props.args = this.getGeometryArgs(node.type, h);
4100
- props.hsType = node.type;
4101
- }
4102
- }
4103
- if (rawProps.scale !== void 0 && !props.scale) {
4104
- props.scale = Array.isArray(rawProps.scale) ? rawProps.scale : [rawProps.scale, rawProps.scale, rawProps.scale];
4105
- }
4106
- if (rawProps.geometry && !props.hsType) {
4107
- props.hsType = rawProps.geometry;
4108
- props.args = this.getGeometryArgs(rawProps.geometry, { size: rawProps.size || 1 });
4109
- }
4110
- if (rawProps.material && typeof rawProps.material === "string" && MATERIAL_PRESETS[rawProps.material]) {
4111
- props.materialProps = {
4112
- ...MATERIAL_PRESETS[rawProps.material],
4113
- ...props.materialProps
4114
- };
4115
- }
4116
- if (node.directives) {
4117
- for (const d of node.directives) {
4118
- if (d.type === "trait") {
4119
- if (d.name === "grabbable") {
4120
- props.castShadow = true;
4121
- props.grabbable = d.config || true;
4122
- if (!props.rigidBody) props.rigidBody = { type: "dynamic" };
4123
- if (!props.collider) props.collider = { type: "auto" };
4124
- } else if (d.name === "animated") {
4125
- props.animated = d.config || true;
4126
- } else if (d.name === "spatial_audio" || d.name === "voice") {
4127
- props.spatial = true;
4128
- } else if (d.name === "networked") {
4129
- props.networked = d.config || true;
4130
- } else if (d.name === "moldable") {
4131
- props.moldable = d.config || true;
4132
- } else if (d.name === "stretchable") {
4133
- props.stretchable = d.config || true;
4134
- } else if (d.name === "ai_driven") {
4135
- props.ai_driven = d.config || true;
4136
- } else if (d.name === "dialogue") {
4137
- props.dialogue = d.config || true;
4138
- } else if (d.name === "gesture") {
4139
- props.gesture = d.config || true;
4140
- } else if (d.name === "haptic") {
4141
- props.haptic = d.config || true;
4142
- } else if (d.name === "avatar_embodiment") {
4143
- props.avatarEmbodiment = d.config || true;
4144
- } else if (d.name === "lip_sync") {
4145
- props.lipSync = d.config || true;
4146
- } else if (d.name === "emotion_directive") {
4147
- props.emotionDirective = d.config || true;
4148
- } else if (d.name === "stt") {
4149
- props.stt = d.config || true;
4150
- } else if (d.name === "tts") {
4151
- props.tts = d.config || true;
4152
- } else if (d.name === "generate") {
4153
- props.generate = d.config;
4154
- } else if (d.name === "skeleton") {
4155
- props.skeleton = d.config || true;
4156
- } else if (d.name === "body") {
4157
- props.body = d.config || true;
4158
- } else if (d.name === "gaussian_splat") {
4159
- props.gaussianSplat = d.config || true;
4160
- } else if (d.name === "nerf") {
4161
- props.nerf = d.config || true;
4162
- } else if (d.name === "volumetric_video") {
4163
- props.volumetricVideo = d.config || true;
4164
- }
4165
- }
4166
- }
4167
- }
4168
- delete props.type;
4169
- delete props.geometry;
4170
- return props;
4171
- }
4172
- applyGraphicsConfig(r3fNode, graphics) {
4173
- if (graphics.material) {
4174
- const m = graphics.material;
4175
- const materialProps = {};
4176
- if (m.preset && MATERIAL_PRESETS[m.preset]) {
4177
- Object.assign(materialProps, MATERIAL_PRESETS[m.preset]);
4178
- }
4179
- if (m.type === "pbr" && m.pbr) {
4180
- if (m.pbr.baseColor) materialProps["color"] = this.mapColor(m.pbr.baseColor);
4181
- if (m.pbr.metallic !== void 0) materialProps["metalness"] = m.pbr.metallic;
4182
- if (m.pbr.roughness !== void 0) materialProps["roughness"] = m.pbr.roughness;
4183
- if (m.pbr.emission) materialProps["emissive"] = this.mapColor(m.pbr.emission);
4184
- if (m.pbr.emissionStrength) materialProps["emissiveIntensity"] = m.pbr.emissionStrength;
4185
- if (m.pbr.clearcoat !== void 0) materialProps["clearcoat"] = m.pbr.clearcoat;
4186
- if (m.pbr.transmission !== void 0) materialProps["transmission"] = m.pbr.transmission;
4187
- if (m.pbr.ior !== void 0) materialProps["ior"] = m.pbr.ior;
4188
- if (m.pbr.iridescence !== void 0) materialProps["iridescence"] = m.pbr.iridescence;
4189
- }
4190
- r3fNode.props.materialProps = { ...r3fNode.props.materialProps, ...materialProps };
4191
- }
4192
- if (graphics.lighting) {
4193
- const l = graphics.lighting;
4194
- if (r3fNode.type.toLowerCase().includes("light")) {
4195
- if (l.shadows) r3fNode.props.castShadow = true;
4196
- if (l.intensity !== void 0) r3fNode.props.intensity = l.intensity;
4197
- if (l.color) r3fNode.props.color = this.mapColor(l.color);
4198
- }
4199
- if (r3fNode.type === "Environment" && l.preset) {
4200
- r3fNode.props.preset = l.preset;
4201
- }
4202
- }
4203
- if (graphics.networked) {
4204
- r3fNode.props.networked = graphics.networked;
4205
- }
4206
- }
4207
- mapColor(c) {
4208
- if (typeof c === "string") return c;
4209
- if (typeof c === "number") return `#${c.toString(16).padStart(6, "0")}`;
4210
- if (c.r !== void 0) {
4211
- const r = c.r > 1 ? c.r : Math.floor(c.r * 255);
4212
- const g = c.g > 1 ? c.g : Math.floor(c.g * 255);
4213
- const b = c.b > 1 ? c.b : Math.floor(c.b * 255);
4214
- return `rgb(${r}, ${g}, ${b})`;
4215
- }
4216
- return "#ffffff";
4217
- }
4218
- getGeometryArgs(type, hologram) {
4219
- const size = hologram.size || 1;
4220
- switch (type) {
4221
- case "sphere":
4222
- case "orb":
4223
- return [size * 0.5, 32, 32];
4224
- case "cube":
4225
- case "box":
4226
- return [size, size, size];
4227
- case "cylinder":
4228
- return [size * 0.5, size * 0.5, size, 32];
4229
- case "pyramid":
4230
- case "cone":
4231
- return [size * 0.5, 0, size, 4];
4232
- case "plane":
4233
- return [size, size];
4234
- case "torus":
4235
- return [size * 0.5, size * 0.15, 16, 32];
4236
- case "ring":
4237
- return [size * 0.3, size * 0.5, 32];
4238
- case "capsule":
4239
- return [size * 0.3, size * 0.5, 4, 16];
4240
- default:
4241
- return [size, size, size];
4242
- }
4243
- }
4244
- };
4245
- }
4246
- });
4247
-
4248
- export { ASTNodePool, ENVIRONMENT_PRESETS, MATERIAL_PRESETS, QUALITY_TIER_SCALES, R3FCompiler, R3FCompiler_exports, UI_COMPONENT_PRESETS, init_ObjectPool, init_R3FCompiler, init_visual, registerAllPresets };
4249
- //# sourceMappingURL=chunk-T36DDXSF.js.map
4250
- //# sourceMappingURL=chunk-T36DDXSF.js.map