sdl-mcp 0.12.2 → 0.12.3

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 (276) hide show
  1. package/README.md +10 -0
  2. package/config/sdlmcp.config.example.json +53 -8
  3. package/config/sdlmcp.config.schema.json +530 -106
  4. package/dist/.tsbuildinfo +1 -1
  5. package/dist/benchmark/external-manifest.d.ts +162 -0
  6. package/dist/benchmark/external-manifest.d.ts.map +1 -0
  7. package/dist/benchmark/external-manifest.js +336 -0
  8. package/dist/benchmark/external-manifest.js.map +1 -0
  9. package/dist/benchmark/external-runner.d.ts +100 -0
  10. package/dist/benchmark/external-runner.d.ts.map +1 -0
  11. package/dist/benchmark/external-runner.js +1171 -0
  12. package/dist/benchmark/external-runner.js.map +1 -0
  13. package/dist/benchmark/output-file.d.ts +3 -0
  14. package/dist/benchmark/output-file.d.ts.map +1 -0
  15. package/dist/benchmark/output-file.js +8 -0
  16. package/dist/benchmark/output-file.js.map +1 -0
  17. package/dist/cli/argParsing.d.ts.map +1 -1
  18. package/dist/cli/argParsing.js +6 -0
  19. package/dist/cli/argParsing.js.map +1 -1
  20. package/dist/cli/commands/benchmark.d.ts.map +1 -1
  21. package/dist/cli/commands/benchmark.js +3 -2
  22. package/dist/cli/commands/benchmark.js.map +1 -1
  23. package/dist/cli/commands/index.d.ts +1 -0
  24. package/dist/cli/commands/index.d.ts.map +1 -1
  25. package/dist/cli/commands/index.js +13 -7
  26. package/dist/cli/commands/index.js.map +1 -1
  27. package/dist/cli/commands/init.d.ts +5 -1
  28. package/dist/cli/commands/init.d.ts.map +1 -1
  29. package/dist/cli/commands/init.js +73 -3
  30. package/dist/cli/commands/init.js.map +1 -1
  31. package/dist/cli/commands/serve.d.ts.map +1 -1
  32. package/dist/cli/commands/serve.js +2 -0
  33. package/dist/cli/commands/serve.js.map +1 -1
  34. package/dist/cli/index.js +2 -0
  35. package/dist/cli/index.js.map +1 -1
  36. package/dist/cli/transport/http.d.ts +1 -35
  37. package/dist/cli/transport/http.d.ts.map +1 -1
  38. package/dist/cli/transport/http.js +151 -175
  39. package/dist/cli/transport/http.js.map +1 -1
  40. package/dist/cli/types.d.ts +1 -0
  41. package/dist/cli/types.d.ts.map +1 -1
  42. package/dist/config/constants.d.ts +30 -0
  43. package/dist/config/constants.d.ts.map +1 -1
  44. package/dist/config/constants.js +30 -0
  45. package/dist/config/constants.js.map +1 -1
  46. package/dist/config/types.d.ts +53 -1
  47. package/dist/config/types.d.ts.map +1 -1
  48. package/dist/config/types.js +62 -14
  49. package/dist/config/types.js.map +1 -1
  50. package/dist/db/ladybug-batching.d.ts +1 -0
  51. package/dist/db/ladybug-batching.d.ts.map +1 -1
  52. package/dist/db/ladybug-batching.js +1 -0
  53. package/dist/db/ladybug-batching.js.map +1 -1
  54. package/dist/db/ladybug-core.d.ts +3 -0
  55. package/dist/db/ladybug-core.d.ts.map +1 -1
  56. package/dist/db/ladybug-core.js +72 -2
  57. package/dist/db/ladybug-core.js.map +1 -1
  58. package/dist/db/ladybug-embeddings.d.ts +6 -1
  59. package/dist/db/ladybug-embeddings.d.ts.map +1 -1
  60. package/dist/db/ladybug-embeddings.js +6 -1
  61. package/dist/db/ladybug-embeddings.js.map +1 -1
  62. package/dist/db/ladybug-file-summaries.d.ts.map +1 -1
  63. package/dist/db/ladybug-file-summaries.js +23 -0
  64. package/dist/db/ladybug-file-summaries.js.map +1 -1
  65. package/dist/db/ladybug-queries.js +1 -1
  66. package/dist/db/ladybug-queries.js.map +1 -1
  67. package/dist/db/migrations/index.d.ts.map +1 -1
  68. package/dist/db/migrations/index.js +2 -0
  69. package/dist/db/migrations/index.js.map +1 -1
  70. package/dist/db/migrations/m007-copy-embeddings-to-symbol.d.ts +5 -9
  71. package/dist/db/migrations/m007-copy-embeddings-to-symbol.d.ts.map +1 -1
  72. package/dist/db/migrations/m007-copy-embeddings-to-symbol.js +24 -126
  73. package/dist/db/migrations/m007-copy-embeddings-to-symbol.js.map +1 -1
  74. package/dist/db/migrations/m021-remediate-symbol-embeddings.d.ts +5 -0
  75. package/dist/db/migrations/m021-remediate-symbol-embeddings.d.ts.map +1 -0
  76. package/dist/db/migrations/m021-remediate-symbol-embeddings.js +7 -0
  77. package/dist/db/migrations/m021-remediate-symbol-embeddings.js.map +1 -0
  78. package/dist/db/migrations/symbol-embedding-remediation.d.ts +57 -0
  79. package/dist/db/migrations/symbol-embedding-remediation.d.ts.map +1 -0
  80. package/dist/db/migrations/symbol-embedding-remediation.js +335 -0
  81. package/dist/db/migrations/symbol-embedding-remediation.js.map +1 -0
  82. package/dist/graph/layout/force-layout.d.ts +4 -0
  83. package/dist/graph/layout/force-layout.d.ts.map +1 -0
  84. package/dist/graph/layout/force-layout.js +127 -0
  85. package/dist/graph/layout/force-layout.js.map +1 -0
  86. package/dist/graph/layout/layout-service.d.ts +37 -0
  87. package/dist/graph/layout/layout-service.d.ts.map +1 -0
  88. package/dist/graph/layout/layout-service.js +172 -0
  89. package/dist/graph/layout/layout-service.js.map +1 -0
  90. package/dist/graph/layout/native-engine.d.ts +9 -0
  91. package/dist/graph/layout/native-engine.d.ts.map +1 -0
  92. package/dist/graph/layout/native-engine.js +59 -0
  93. package/dist/graph/layout/native-engine.js.map +1 -0
  94. package/dist/graph/layout/prng.d.ts +3 -0
  95. package/dist/graph/layout/prng.d.ts.map +1 -0
  96. package/dist/graph/layout/prng.js +19 -0
  97. package/dist/graph/layout/prng.js.map +1 -0
  98. package/dist/graph/layout/serializer.d.ts +3 -0
  99. package/dist/graph/layout/serializer.d.ts.map +1 -0
  100. package/dist/graph/layout/serializer.js +20 -0
  101. package/dist/graph/layout/serializer.js.map +1 -0
  102. package/dist/graph/layout/types.d.ts +30 -0
  103. package/dist/graph/layout/types.d.ts.map +1 -0
  104. package/dist/graph/layout/types.js +2 -0
  105. package/dist/graph/layout/types.js.map +1 -0
  106. package/dist/indexer/embeddings.d.ts +7 -0
  107. package/dist/indexer/embeddings.d.ts.map +1 -1
  108. package/dist/indexer/embeddings.js +44 -4
  109. package/dist/indexer/embeddings.js.map +1 -1
  110. package/dist/indexer/file-summary-embeddings.d.ts +12 -0
  111. package/dist/indexer/file-summary-embeddings.d.ts.map +1 -1
  112. package/dist/indexer/file-summary-embeddings.js +83 -21
  113. package/dist/indexer/file-summary-embeddings.js.map +1 -1
  114. package/dist/indexer/fileWalker.d.ts.map +1 -1
  115. package/dist/indexer/fileWalker.js +2 -1
  116. package/dist/indexer/fileWalker.js.map +1 -1
  117. package/dist/indexer/metrics-updater.d.ts.map +1 -1
  118. package/dist/indexer/metrics-updater.js +27 -4
  119. package/dist/indexer/metrics-updater.js.map +1 -1
  120. package/dist/indexer/watcher.d.ts.map +1 -1
  121. package/dist/indexer/watcher.js +2 -1
  122. package/dist/indexer/watcher.js.map +1 -1
  123. package/dist/mcp/context-response-projection.d.ts.map +1 -1
  124. package/dist/mcp/context-response-projection.js +49 -13
  125. package/dist/mcp/context-response-projection.js.map +1 -1
  126. package/dist/mcp/tools/search-edit/planner.d.ts.map +1 -1
  127. package/dist/mcp/tools/search-edit/planner.js +10 -3
  128. package/dist/mcp/tools/search-edit/planner.js.map +1 -1
  129. package/dist/observability/event-tap.d.ts +2 -1
  130. package/dist/observability/event-tap.d.ts.map +1 -1
  131. package/dist/observability/event-tap.js.map +1 -1
  132. package/dist/observability/service.d.ts +11 -4
  133. package/dist/observability/service.d.ts.map +1 -1
  134. package/dist/observability/service.js +83 -13
  135. package/dist/observability/service.js.map +1 -1
  136. package/dist/observability/types.d.ts +48 -2
  137. package/dist/observability/types.d.ts.map +1 -1
  138. package/dist/ui/.tsbuildinfo +1 -0
  139. package/dist/ui/vendor/fflate.js +2692 -0
  140. package/dist/ui/vendor/jsm/controls/ArcballControls.js +3543 -0
  141. package/dist/ui/vendor/jsm/controls/DragControls.js +452 -0
  142. package/dist/ui/vendor/jsm/controls/FirstPersonControls.js +488 -0
  143. package/dist/ui/vendor/jsm/controls/FlyControls.js +384 -0
  144. package/dist/ui/vendor/jsm/controls/MapControls.js +116 -0
  145. package/dist/ui/vendor/jsm/controls/OrbitControls.js +1963 -0
  146. package/dist/ui/vendor/jsm/controls/PointerLockControls.js +264 -0
  147. package/dist/ui/vendor/jsm/controls/TrackballControls.js +1001 -0
  148. package/dist/ui/vendor/jsm/controls/TransformControls.js +2003 -0
  149. package/dist/ui/vendor/jsm/loaders/3DMLoader.js +1836 -0
  150. package/dist/ui/vendor/jsm/loaders/3MFLoader.js +1621 -0
  151. package/dist/ui/vendor/jsm/loaders/AMFLoader.js +541 -0
  152. package/dist/ui/vendor/jsm/loaders/BVHLoader.js +484 -0
  153. package/dist/ui/vendor/jsm/loaders/ColladaLoader.js +153 -0
  154. package/dist/ui/vendor/jsm/loaders/DDSLoader.js +385 -0
  155. package/dist/ui/vendor/jsm/loaders/DRACOLoader.js +772 -0
  156. package/dist/ui/vendor/jsm/loaders/EXRLoader.js +3395 -0
  157. package/dist/ui/vendor/jsm/loaders/FBXLoader.js +4580 -0
  158. package/dist/ui/vendor/jsm/loaders/FontLoader.js +260 -0
  159. package/dist/ui/vendor/jsm/loaders/GCodeLoader.js +318 -0
  160. package/dist/ui/vendor/jsm/loaders/GLTFLoader.js +4860 -0
  161. package/dist/ui/vendor/jsm/loaders/HDRCubeTextureLoader.js +164 -0
  162. package/dist/ui/vendor/jsm/loaders/HDRLoader.js +463 -0
  163. package/dist/ui/vendor/jsm/loaders/IESLoader.js +379 -0
  164. package/dist/ui/vendor/jsm/loaders/KMZLoader.js +163 -0
  165. package/dist/ui/vendor/jsm/loaders/KTX2Loader.js +1276 -0
  166. package/dist/ui/vendor/jsm/loaders/KTXLoader.js +197 -0
  167. package/dist/ui/vendor/jsm/loaders/LDrawLoader.js +2510 -0
  168. package/dist/ui/vendor/jsm/loaders/LUT3dlLoader.js +205 -0
  169. package/dist/ui/vendor/jsm/loaders/LUTCubeLoader.js +190 -0
  170. package/dist/ui/vendor/jsm/loaders/LUTImageLoader.js +190 -0
  171. package/dist/ui/vendor/jsm/loaders/LWOLoader.js +1051 -0
  172. package/dist/ui/vendor/jsm/loaders/LottieLoader.js +130 -0
  173. package/dist/ui/vendor/jsm/loaders/MD2Loader.js +435 -0
  174. package/dist/ui/vendor/jsm/loaders/MDDLoader.js +147 -0
  175. package/dist/ui/vendor/jsm/loaders/MTLLoader.js +593 -0
  176. package/dist/ui/vendor/jsm/loaders/MaterialXLoader.js +1126 -0
  177. package/dist/ui/vendor/jsm/loaders/NRRDLoader.js +718 -0
  178. package/dist/ui/vendor/jsm/loaders/OBJLoader.js +955 -0
  179. package/dist/ui/vendor/jsm/loaders/PCDLoader.js +620 -0
  180. package/dist/ui/vendor/jsm/loaders/PDBLoader.js +272 -0
  181. package/dist/ui/vendor/jsm/loaders/PLYLoader.js +968 -0
  182. package/dist/ui/vendor/jsm/loaders/PVRLoader.js +270 -0
  183. package/dist/ui/vendor/jsm/loaders/RGBELoader.js +18 -0
  184. package/dist/ui/vendor/jsm/loaders/STLLoader.js +421 -0
  185. package/dist/ui/vendor/jsm/loaders/SVGLoader.js +3319 -0
  186. package/dist/ui/vendor/jsm/loaders/TDSLoader.js +1142 -0
  187. package/dist/ui/vendor/jsm/loaders/TGALoader.js +538 -0
  188. package/dist/ui/vendor/jsm/loaders/TIFFLoader.js +59 -0
  189. package/dist/ui/vendor/jsm/loaders/TTFLoader.js +261 -0
  190. package/dist/ui/vendor/jsm/loaders/USDLoader.js +303 -0
  191. package/dist/ui/vendor/jsm/loaders/USDZLoader.js +16 -0
  192. package/dist/ui/vendor/jsm/loaders/UltraHDRLoader.js +755 -0
  193. package/dist/ui/vendor/jsm/loaders/VOXLoader.js +919 -0
  194. package/dist/ui/vendor/jsm/loaders/VRMLLoader.js +3646 -0
  195. package/dist/ui/vendor/jsm/loaders/VTKLoader.js +1293 -0
  196. package/dist/ui/vendor/jsm/loaders/XYZLoader.js +143 -0
  197. package/dist/ui/vendor/jsm/loaders/collada/ColladaComposer.js +3044 -0
  198. package/dist/ui/vendor/jsm/loaders/collada/ColladaParser.js +1977 -0
  199. package/dist/ui/vendor/jsm/loaders/lwo/IFFParser.js +1217 -0
  200. package/dist/ui/vendor/jsm/loaders/lwo/LWO2Parser.js +414 -0
  201. package/dist/ui/vendor/jsm/loaders/lwo/LWO3Parser.js +373 -0
  202. package/dist/ui/vendor/jsm/loaders/usd/USDAParser.js +901 -0
  203. package/dist/ui/vendor/jsm/loaders/usd/USDCParser.js +1878 -0
  204. package/dist/ui/vendor/jsm/loaders/usd/USDComposer.js +4627 -0
  205. package/dist/ui/vendor/jsm/utils/BufferGeometryUtils.js +1501 -0
  206. package/dist/ui/vendor/jsm/utils/CameraUtils.js +82 -0
  207. package/dist/ui/vendor/jsm/utils/ColorUtils.js +76 -0
  208. package/dist/ui/vendor/jsm/utils/GeometryCompressionUtils.js +547 -0
  209. package/dist/ui/vendor/jsm/utils/GeometryUtils.js +226 -0
  210. package/dist/ui/vendor/jsm/utils/LDrawUtils.js +211 -0
  211. package/dist/ui/vendor/jsm/utils/SceneOptimizer.js +458 -0
  212. package/dist/ui/vendor/jsm/utils/SceneUtils.js +363 -0
  213. package/dist/ui/vendor/jsm/utils/ShadowMapViewer.js +244 -0
  214. package/dist/ui/vendor/jsm/utils/ShadowMapViewerGPU.js +233 -0
  215. package/dist/ui/vendor/jsm/utils/SkeletonUtils.js +496 -0
  216. package/dist/ui/vendor/jsm/utils/SortUtils.js +175 -0
  217. package/dist/ui/vendor/jsm/utils/UVsDebug.js +173 -0
  218. package/dist/ui/vendor/jsm/utils/WebGLTextureUtils.js +115 -0
  219. package/dist/ui/vendor/jsm/utils/WebGPUTextureUtils.js +81 -0
  220. package/dist/ui/vendor/jsm/utils/WorkerPool.js +167 -0
  221. package/dist/ui/vendor/three.core.min.js +6 -0
  222. package/dist/ui/vendor/three.module.min.js +6 -0
  223. package/dist/ui/viewer/ambient.js +39 -0
  224. package/dist/ui/viewer/api.js +93 -0
  225. package/dist/ui/viewer/chrome.js +36 -0
  226. package/dist/ui/viewer/edges.js +33 -0
  227. package/dist/ui/viewer/index.html +32 -0
  228. package/dist/ui/viewer/inspector.js +23 -0
  229. package/dist/ui/viewer/lenses/activity.js +24 -0
  230. package/dist/ui/viewer/lenses/community.js +5 -0
  231. package/dist/ui/viewer/lenses/edges.js +4 -0
  232. package/dist/ui/viewer/lenses/impact.js +6 -0
  233. package/dist/ui/viewer/lenses/search.js +69 -0
  234. package/dist/ui/viewer/lod.js +100 -0
  235. package/dist/ui/viewer/main.js +92 -0
  236. package/dist/ui/viewer/picking.js +45 -0
  237. package/dist/ui/viewer/scene.js +85 -0
  238. package/dist/ui/viewer/skins/default-skin.js +15 -0
  239. package/dist/ui/viewer/skins/loader.js +44 -0
  240. package/dist/ui/viewer/skins/manifest-schema.js +30 -0
  241. package/dist/ui/viewer/state.js +44 -0
  242. package/dist/ui/viewer/theme.js +23 -0
  243. package/dist/ui/viewer/universe.js +151 -0
  244. package/dist/ui/viewer/viewer.css +85 -0
  245. package/dist/util/safeRegex.d.ts.map +1 -1
  246. package/dist/util/safeRegex.js +221 -68
  247. package/dist/util/safeRegex.js.map +1 -1
  248. package/dist/viewer/legacy-graph.d.ts +40 -0
  249. package/dist/viewer/legacy-graph.d.ts.map +1 -0
  250. package/dist/viewer/legacy-graph.js +152 -0
  251. package/dist/viewer/legacy-graph.js.map +1 -0
  252. package/dist/viewer/routes.d.ts +10 -0
  253. package/dist/viewer/routes.d.ts.map +1 -0
  254. package/dist/viewer/routes.js +221 -0
  255. package/dist/viewer/routes.js.map +1 -0
  256. package/dist/viewer/service.d.ts +44 -0
  257. package/dist/viewer/service.d.ts.map +1 -0
  258. package/dist/viewer/service.js +160 -0
  259. package/dist/viewer/service.js.map +1 -0
  260. package/dist/viewer/types.d.ts +63 -0
  261. package/dist/viewer/types.d.ts.map +1 -0
  262. package/dist/viewer/types.js +2 -0
  263. package/dist/viewer/types.js.map +1 -0
  264. package/dist/viewer/viewer-config.d.ts +12 -0
  265. package/dist/viewer/viewer-config.d.ts.map +1 -0
  266. package/dist/viewer/viewer-config.js +36 -0
  267. package/dist/viewer/viewer-config.js.map +1 -0
  268. package/package.json +18 -9
  269. package/templates/SDL.md +19 -0
  270. package/templates/claude-code.json +8 -43
  271. package/dist/ui/graph.css +0 -108
  272. package/dist/ui/graph.d.ts +0 -2
  273. package/dist/ui/graph.d.ts.map +0 -1
  274. package/dist/ui/graph.html +0 -52
  275. package/dist/ui/graph.js +0 -259
  276. package/dist/ui/graph.js.map +0 -1
@@ -0,0 +1,1126 @@
1
+ import {
2
+ FileLoader, Loader, ImageBitmapLoader, Texture, RepeatWrapping, MeshBasicNodeMaterial,
3
+ MeshPhysicalNodeMaterial, DoubleSide,
4
+ } from 'three/webgpu';
5
+
6
+ import {
7
+ float, bool, int, vec2, vec3, vec4, color, texture,
8
+ positionLocal, positionWorld, uv, vertexColor,
9
+ normalLocal, normalWorld, tangentLocal, tangentWorld,
10
+ mul, abs, sign, floor, ceil, round, sin, cos, tan,
11
+ asin, acos, sqrt, exp, clamp, min, max, normalize, length, dot, cross, normalMap,
12
+ remap, smoothstep, luminance, mx_rgbtohsv, mx_hsvtorgb,
13
+ mix, saturation, transpose, determinant, inverse, log, reflect, refract, element,
14
+ mx_ramplr, mx_ramptb, mx_splitlr, mx_splittb,
15
+ mx_fractal_noise_float, mx_noise_float, mx_cell_noise_float, mx_worley_noise_float,
16
+ mx_transform_uv,
17
+ mx_safepower, mx_contrast,
18
+ mx_srgb_texture_to_lin_rec709,
19
+ mx_add, mx_atan2, mx_divide, mx_modulo, mx_multiply, mx_power, mx_subtract,
20
+ mx_timer, mx_frame, mat3, mx_ramp4,
21
+ mx_invert, mx_ifgreater, mx_ifgreatereq, mx_ifequal, distance,
22
+ mx_separate, mx_place2d, mx_rotate2d, mx_rotate3d, mx_heighttonormal,
23
+ mx_unifiednoise2d, mx_unifiednoise3d
24
+ } from 'three/tsl';
25
+
26
+ const colorSpaceLib = {
27
+ mx_srgb_texture_to_lin_rec709
28
+ };
29
+
30
+ class MXElement {
31
+
32
+ constructor( name, nodeFunc, params = [] ) {
33
+
34
+ this.name = name;
35
+ this.nodeFunc = nodeFunc;
36
+ this.params = params;
37
+
38
+ }
39
+
40
+ }
41
+
42
+ // Ref: https://github.com/mrdoob/three.js/issues/24674
43
+
44
+ // Enhanced separate node to support multi-output referencing (outx, outy, outz, outw)
45
+
46
+ // Type/arity-aware MaterialX node wrappers
47
+
48
+ const MXElements = [
49
+
50
+ // << Math >>
51
+ new MXElement( 'add', mx_add, [ 'in1', 'in2' ] ),
52
+ new MXElement( 'subtract', mx_subtract, [ 'in1', 'in2' ] ),
53
+ new MXElement( 'multiply', mx_multiply, [ 'in1', 'in2' ] ),
54
+ new MXElement( 'divide', mx_divide, [ 'in1', 'in2' ] ),
55
+ new MXElement( 'modulo', mx_modulo, [ 'in1', 'in2' ] ),
56
+ new MXElement( 'absval', abs, [ 'in1', 'in2' ] ),
57
+ new MXElement( 'sign', sign, [ 'in1', 'in2' ] ),
58
+ new MXElement( 'floor', floor, [ 'in1', 'in2' ] ),
59
+ new MXElement( 'ceil', ceil, [ 'in1', 'in2' ] ),
60
+ new MXElement( 'round', round, [ 'in1', 'in2' ] ),
61
+ new MXElement( 'power', mx_power, [ 'in1', 'in2' ] ),
62
+ new MXElement( 'sin', sin, [ 'in' ] ),
63
+ new MXElement( 'cos', cos, [ 'in' ] ),
64
+ new MXElement( 'tan', tan, [ 'in' ] ),
65
+ new MXElement( 'asin', asin, [ 'in' ] ),
66
+ new MXElement( 'acos', acos, [ 'in' ] ),
67
+ new MXElement( 'atan2', mx_atan2, [ 'in1', 'in2' ] ),
68
+ new MXElement( 'sqrt', sqrt, [ 'in' ] ),
69
+ new MXElement( 'ln', log, [ 'in' ] ),
70
+ new MXElement( 'exp', exp, [ 'in' ] ),
71
+ new MXElement( 'clamp', clamp, [ 'in', 'low', 'high' ] ),
72
+ new MXElement( 'min', min, [ 'in1', 'in2' ] ),
73
+ new MXElement( 'max', max, [ 'in1', 'in2' ] ),
74
+ new MXElement( 'normalize', normalize, [ 'in' ] ),
75
+ new MXElement( 'magnitude', length, [ 'in1', 'in2' ] ),
76
+ new MXElement( 'dotproduct', dot, [ 'in1', 'in2' ] ),
77
+ new MXElement( 'crossproduct', cross, [ 'in' ] ),
78
+ new MXElement( 'distance', distance, [ 'in1', 'in2' ] ),
79
+ new MXElement( 'invert', mx_invert, [ 'in', 'amount' ] ),
80
+ //new MtlXElement( 'transformpoint', ... ),
81
+ //new MtlXElement( 'transformvector', ... ),
82
+ //new MtlXElement( 'transformnormal', ... ),
83
+ new MXElement( 'transformmatrix', mul, [ 'in1', 'in2' ] ),
84
+ new MXElement( 'normalmap', normalMap, [ 'in', 'scale' ] ),
85
+ new MXElement( 'transpose', transpose, [ 'in' ] ),
86
+ new MXElement( 'determinant', determinant, [ 'in' ] ),
87
+ new MXElement( 'invertmatrix', inverse, [ 'in' ] ),
88
+ new MXElement( 'creatematrix', mat3, [ 'in1', 'in2', 'in3' ] ),
89
+ //new MtlXElement( 'rotate2d', rotateUV, [ 'in', radians( 'amount' )** ] ),
90
+ //new MtlXElement( 'rotate3d', ... ),
91
+ //new MtlXElement( 'arrayappend', ... ),
92
+ //new MtlXElement( 'dot', ... ),
93
+
94
+ new MXElement( 'length', length, [ 'in' ] ),
95
+ new MXElement( 'crossproduct', cross, [ 'in1', 'in2' ] ),
96
+ new MXElement( 'floor', floor, [ 'in' ] ),
97
+ new MXElement( 'ceil', ceil, [ 'in' ] ),
98
+
99
+ // << Adjustment >>
100
+ new MXElement( 'remap', remap, [ 'in', 'inlow', 'inhigh', 'outlow', 'outhigh' ] ),
101
+ new MXElement( 'smoothstep', smoothstep, [ 'in', 'low', 'high' ] ),
102
+ //new MtlXElement( 'curveadjust', ... ),
103
+ //new MtlXElement( 'curvelookup', ... ),
104
+ new MXElement( 'luminance', luminance, [ 'in', 'lumacoeffs' ] ),
105
+ new MXElement( 'rgbtohsv', mx_rgbtohsv, [ 'in' ] ),
106
+ new MXElement( 'hsvtorgb', mx_hsvtorgb, [ 'in' ] ),
107
+
108
+ // << Mix >>
109
+ new MXElement( 'mix', mix, [ 'bg', 'fg', 'mix' ] ),
110
+
111
+ // << Channel >>
112
+ new MXElement( 'combine2', vec2, [ 'in1', 'in2' ] ),
113
+ new MXElement( 'combine3', vec3, [ 'in1', 'in2', 'in3' ] ),
114
+ new MXElement( 'combine4', vec4, [ 'in1', 'in2', 'in3', 'in4' ] ),
115
+
116
+ // << Procedural >>
117
+ new MXElement( 'ramplr', mx_ramplr, [ 'valuel', 'valuer', 'texcoord' ] ),
118
+ new MXElement( 'ramptb', mx_ramptb, [ 'valuet', 'valueb', 'texcoord' ] ),
119
+ new MXElement( 'ramp4', mx_ramp4, [ 'valuetl', 'valuetr', 'valuebl', 'valuebr', 'texcoord' ] ),
120
+ new MXElement( 'splitlr', mx_splitlr, [ 'valuel', 'valuer', 'texcoord' ] ),
121
+ new MXElement( 'splittb', mx_splittb, [ 'valuet', 'valueb', 'texcoord' ] ),
122
+ new MXElement( 'noise2d', mx_noise_float, [ 'texcoord', 'amplitude', 'pivot' ] ),
123
+ new MXElement( 'noise3d', mx_noise_float, [ 'texcoord', 'amplitude', 'pivot' ] ),
124
+ new MXElement( 'fractal3d', mx_fractal_noise_float, [ 'position', 'octaves', 'lacunarity', 'diminish', 'amplitude' ] ),
125
+ new MXElement( 'cellnoise2d', mx_cell_noise_float, [ 'texcoord' ] ),
126
+ new MXElement( 'cellnoise3d', mx_cell_noise_float, [ 'texcoord' ] ),
127
+ new MXElement( 'worleynoise2d', mx_worley_noise_float, [ 'texcoord', 'jitter' ] ),
128
+ new MXElement( 'worleynoise3d', mx_worley_noise_float, [ 'texcoord', 'jitter' ] ),
129
+ new MXElement( 'unifiednoise2d', mx_unifiednoise2d, [ 'type', 'texcoord', 'freq', 'offset', 'jitter', 'outmin', 'outmax', 'clampoutput', 'octaves', 'lacunarity', 'diminish' ] ),
130
+ new MXElement( 'unifiednoise3d', mx_unifiednoise3d, [ 'type', 'texcoord', 'freq', 'offset', 'jitter', 'outmin', 'outmax', 'clampoutput', 'octaves', 'lacunarity', 'diminish' ] ),
131
+ // << Supplemental >>
132
+ //new MtlXElement( 'tiledimage', ... ),
133
+ //new MtlXElement( 'triplanarprojection', triplanarTextures, [ 'filex', 'filey', 'filez' ] ),
134
+ //new MtlXElement( 'ramp4', ... ),
135
+ new MXElement( 'place2d', mx_place2d, [ 'texcoord', 'pivot', 'scale', 'rotate', 'offset', 'operationorder' ] ),
136
+ new MXElement( 'safepower', mx_safepower, [ 'in1', 'in2' ] ),
137
+ new MXElement( 'contrast', mx_contrast, [ 'in', 'amount', 'pivot' ] ),
138
+ //new MtlXElement( 'hsvadjust', ... ),
139
+ new MXElement( 'saturate', saturation, [ 'in', 'amount' ] ),
140
+ new MXElement( 'extract', element, [ 'in', 'index' ] ),
141
+ new MXElement( 'separate2', mx_separate, [ 'in' ] ),
142
+ new MXElement( 'separate3', mx_separate, [ 'in' ] ),
143
+ new MXElement( 'separate4', mx_separate, [ 'in' ] ),
144
+ new MXElement( 'reflect', reflect, [ 'in', 'normal' ] ),
145
+ new MXElement( 'refract', refract, [ 'in', 'normal', 'ior' ] ),
146
+
147
+ new MXElement( 'time', mx_timer ),
148
+ new MXElement( 'frame', mx_frame ),
149
+ new MXElement( 'ifgreater', mx_ifgreater, [ 'value1', 'value2', 'in1', 'in2' ] ),
150
+ new MXElement( 'ifgreatereq', mx_ifgreatereq, [ 'value1', 'value2', 'in1', 'in2' ] ),
151
+ new MXElement( 'ifequal', mx_ifequal, [ 'value1', 'value2', 'in1', 'in2' ] ),
152
+
153
+ // Placeholder implementations for unsupported nodes
154
+ new MXElement( 'rotate2d', mx_rotate2d, [ 'in', 'amount' ] ),
155
+ new MXElement( 'rotate3d', mx_rotate3d, [ 'in', 'amount', 'axis' ] ),
156
+ new MXElement( 'heighttonormal', mx_heighttonormal, [ 'in', 'scale', 'texcoord' ] ),
157
+
158
+ ];
159
+
160
+ const MtlXLibrary = {};
161
+ MXElements.forEach( element => MtlXLibrary[ element.name ] = element );
162
+
163
+ /**
164
+ * A loader for the MaterialX format.
165
+ *
166
+ * The node materials loaded with this loader can only be used with {@link WebGPURenderer}.
167
+ *
168
+ * ```js
169
+ * const loader = new MaterialXLoader().setPath( SAMPLE_PATH );
170
+ * const materials = await loader.loadAsync( 'standard_surface_brass_tiled.mtlx' );
171
+ * ```
172
+ *
173
+ * @augments Loader
174
+ * @three_import import { MaterialXLoader } from 'three/addons/loaders/MaterialXLoader.js';
175
+ */
176
+ class MaterialXLoader extends Loader {
177
+
178
+ /**
179
+ * Constructs a new MaterialX loader.
180
+ *
181
+ * @param {LoadingManager} [manager] - The loading manager.
182
+ */
183
+ constructor( manager ) {
184
+
185
+ super( manager );
186
+
187
+ }
188
+
189
+ /**
190
+ * Starts loading from the given URL and passes the loaded MaterialX asset
191
+ * to the `onLoad()` callback.
192
+ *
193
+ * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
194
+ * @param {function(Object<string,NodeMaterial>)} onLoad - Executed when the loading process has been finished.
195
+ * @param {onProgressCallback} onProgress - Executed while the loading is in progress.
196
+ * @param {onErrorCallback} onError - Executed when errors occur.
197
+ * @return {MaterialXLoader} A reference to this loader.
198
+ */
199
+ load( url, onLoad, onProgress, onError ) {
200
+
201
+ const _onError = function ( e ) {
202
+
203
+ if ( onError ) {
204
+
205
+ onError( e );
206
+
207
+ } else {
208
+
209
+ console.error( e );
210
+
211
+ }
212
+
213
+ };
214
+
215
+ new FileLoader( this.manager )
216
+ .setPath( this.path )
217
+ .load( url, async ( text ) => {
218
+
219
+ try {
220
+
221
+ onLoad( this.parse( text ) );
222
+
223
+ } catch ( e ) {
224
+
225
+ _onError( e );
226
+
227
+ }
228
+
229
+ }, onProgress, _onError );
230
+
231
+ return this;
232
+
233
+ }
234
+
235
+ /**
236
+ * Parses the given MaterialX data and returns the resulting materials.
237
+ *
238
+ * Supported standard_surface inputs:
239
+ * - base, base_color: Base color/albedo
240
+ * - opacity: Alpha/transparency
241
+ * - specular_roughness: Surface roughness
242
+ * - metalness: Metallic property
243
+ * - specular: Specular reflection intensity
244
+ * - specular_color: Specular reflection color
245
+ * - ior: Index of refraction
246
+ * - specular_anisotropy, specular_rotation: Anisotropic reflection
247
+ * - transmission, transmission_color: Transmission properties
248
+ * - thin_film_thickness, thin_film_ior: Thin film interference
249
+ * - sheen, sheen_color, sheen_roughness: Sheen properties
250
+ * - normal: Normal map
251
+ * - coat, coat_roughness, coat_color: Clearcoat properties
252
+ * - emission, emissionColor: Emission properties
253
+ *
254
+ * @param {string} text - The raw MaterialX data as a string.
255
+ * @return {Object<string,NodeMaterial>} A dictionary holding the parse node materials.
256
+ */
257
+ parse( text ) {
258
+
259
+ return new MaterialX( this.manager, this.path ).parse( text );
260
+
261
+ }
262
+
263
+ }
264
+
265
+ class MaterialXNode {
266
+
267
+ constructor( materialX, nodeXML, nodePath = '' ) {
268
+
269
+ if ( ! materialX || typeof materialX !== 'object' ) {
270
+
271
+ console.warn( 'MaterialXNode: materialX argument is not an object!', { materialX, nodeXML, nodePath } );
272
+
273
+ }
274
+
275
+ this.materialX = materialX;
276
+ this.nodeXML = nodeXML;
277
+ this.nodePath = nodePath ? nodePath + '/' + this.name : this.name;
278
+
279
+ this.parent = null;
280
+
281
+ this.node = null;
282
+
283
+ this.children = [];
284
+
285
+ }
286
+
287
+ get element() {
288
+
289
+ return this.nodeXML.nodeName;
290
+
291
+ }
292
+
293
+ get nodeGraph() {
294
+
295
+ return this.getAttribute( 'nodegraph' );
296
+
297
+ }
298
+
299
+ get nodeName() {
300
+
301
+ return this.getAttribute( 'nodename' );
302
+
303
+ }
304
+
305
+ get interfaceName() {
306
+
307
+ return this.getAttribute( 'interfacename' );
308
+
309
+ }
310
+
311
+ get output() {
312
+
313
+ return this.getAttribute( 'output' );
314
+
315
+ }
316
+
317
+ get name() {
318
+
319
+ return this.getAttribute( 'name' );
320
+
321
+ }
322
+
323
+ get type() {
324
+
325
+ return this.getAttribute( 'type' );
326
+
327
+ }
328
+
329
+ get value() {
330
+
331
+ return this.getAttribute( 'value' );
332
+
333
+ }
334
+
335
+ getNodeGraph() {
336
+
337
+ let nodeX = this;
338
+
339
+ while ( nodeX !== null ) {
340
+
341
+ if ( nodeX.element === 'nodegraph' ) {
342
+
343
+ break;
344
+
345
+ }
346
+
347
+ nodeX = nodeX.parent;
348
+
349
+ }
350
+
351
+ return nodeX;
352
+
353
+ }
354
+
355
+ getRoot() {
356
+
357
+ let nodeX = this;
358
+
359
+ while ( nodeX.parent !== null ) {
360
+
361
+ nodeX = nodeX.parent;
362
+
363
+ }
364
+
365
+ return nodeX;
366
+
367
+ }
368
+
369
+ get referencePath() {
370
+
371
+ let referencePath = null;
372
+
373
+ if ( this.nodeGraph !== null && this.output !== null ) {
374
+
375
+ referencePath = this.nodeGraph + '/' + this.output;
376
+
377
+ } else if ( this.nodeName !== null || this.interfaceName !== null ) {
378
+
379
+ referencePath = this.getNodeGraph().nodePath + '/' + ( this.nodeName || this.interfaceName );
380
+
381
+ }
382
+
383
+ return referencePath;
384
+
385
+ }
386
+
387
+ get hasReference() {
388
+
389
+ return this.referencePath !== null;
390
+
391
+ }
392
+
393
+ get isConst() {
394
+
395
+ return this.element === 'input' && this.value !== null && this.type !== 'filename';
396
+
397
+ }
398
+
399
+ getColorSpaceNode() {
400
+
401
+ const csSource = this.getAttribute( 'colorspace' );
402
+ const csTarget = this.getRoot().getAttribute( 'colorspace' );
403
+
404
+ const nodeName = `mx_${ csSource }_to_${ csTarget }`;
405
+
406
+ return colorSpaceLib[ nodeName ];
407
+
408
+ }
409
+
410
+ getTexture() {
411
+
412
+ const filePrefix = this.getRecursiveAttribute( 'fileprefix' ) || '';
413
+ const uri = filePrefix + this.value;
414
+
415
+ if ( this.materialX.textureCache.has( uri ) ) {
416
+
417
+ return this.materialX.textureCache.get( uri );
418
+
419
+ }
420
+
421
+ let loader = this.materialX.textureLoader;
422
+
423
+ if ( uri ) {
424
+
425
+ const handler = this.materialX.manager.getHandler( uri );
426
+ if ( handler !== null ) loader = handler;
427
+
428
+ }
429
+
430
+ const texture = new Texture();
431
+ texture.wrapS = texture.wrapT = RepeatWrapping;
432
+
433
+ this.materialX.textureCache.set( uri, texture );
434
+
435
+ loader.load( uri, function ( imageBitmap ) {
436
+
437
+ texture.image = imageBitmap;
438
+ texture.needsUpdate = true;
439
+
440
+ } );
441
+
442
+ return texture;
443
+
444
+ }
445
+
446
+ getClassFromType( type ) {
447
+
448
+ let nodeClass = null;
449
+
450
+ if ( type === 'integer' ) nodeClass = int;
451
+ else if ( type === 'float' ) nodeClass = float;
452
+ else if ( type === 'vector2' ) nodeClass = vec2;
453
+ else if ( type === 'vector3' ) nodeClass = vec3;
454
+ else if ( type === 'vector4' || type === 'color4' ) nodeClass = vec4;
455
+ else if ( type === 'color3' ) nodeClass = color;
456
+ else if ( type === 'boolean' ) nodeClass = bool;
457
+
458
+ return nodeClass;
459
+
460
+ }
461
+
462
+ getNode( out = null ) {
463
+
464
+ let node = this.node;
465
+
466
+ if ( node !== null && out === null ) {
467
+
468
+ return node;
469
+
470
+ }
471
+
472
+ // Handle <input name="texcoord" type="vector2" ... />
473
+ if (
474
+ this.element === 'input' &&
475
+ this.name === 'texcoord' &&
476
+ this.type === 'vector2'
477
+ ) {
478
+
479
+ // Try to get index from defaultgeomprop (e.g., "UV0" => 0)
480
+ let index = 0;
481
+ const defaultGeomProp = this.getAttribute( 'defaultgeomprop' );
482
+ if ( defaultGeomProp && /^UV(\d+)$/.test( defaultGeomProp ) ) {
483
+
484
+ index = parseInt( defaultGeomProp.match( /^UV(\d+)$/ )[ 1 ], 10 );
485
+
486
+ }
487
+
488
+ node = uv( index );
489
+
490
+ }
491
+
492
+ // Multi-output support for separate/separate3
493
+ if (
494
+ ( this.element === 'separate3' || this.element === 'separate2' || this.element === 'separate4' ) &&
495
+ out && typeof out === 'string' && out.startsWith( 'out' )
496
+ ) {
497
+
498
+ const inNode = this.getNodeByName( 'in' );
499
+ return mx_separate( inNode, out );
500
+
501
+ }
502
+
503
+ //
504
+
505
+ const type = this.type;
506
+
507
+ if ( this.isConst ) {
508
+
509
+ const nodeClass = this.getClassFromType( type );
510
+
511
+ node = nodeClass( ...this.getVector() );
512
+
513
+ } else if ( this.hasReference ) {
514
+
515
+ if ( this.element === 'output' && this.output && out === null ) {
516
+
517
+ out = this.output;
518
+
519
+ }
520
+
521
+ node = this.materialX.getMaterialXNode( this.referencePath ).getNode( out );
522
+
523
+ } else {
524
+
525
+ const element = this.element;
526
+
527
+ if ( element === 'convert' ) {
528
+
529
+ const nodeClass = this.getClassFromType( type );
530
+
531
+ node = nodeClass( this.getNodeByName( 'in' ) );
532
+
533
+ } else if ( element === 'constant' ) {
534
+
535
+ node = this.getNodeByName( 'value' );
536
+
537
+ } else if ( element === 'position' ) {
538
+
539
+ const space = this.getAttribute( 'space' );
540
+ node = space === 'world' ? positionWorld : positionLocal;
541
+
542
+ } else if ( element === 'normal' ) {
543
+
544
+ const space = this.getAttribute( 'space' );
545
+ node = space === 'world' ? normalWorld : normalLocal;
546
+
547
+ } else if ( element === 'tangent' ) {
548
+
549
+ const space = this.getAttribute( 'space' );
550
+ node = space === 'world' ? tangentWorld : tangentLocal;
551
+
552
+ } else if ( element === 'texcoord' ) {
553
+
554
+ const indexNode = this.getChildByName( 'index' );
555
+ const index = indexNode ? parseInt( indexNode.value ) : 0;
556
+
557
+ node = uv( index );
558
+
559
+ } else if ( element === 'geomcolor' ) {
560
+
561
+ const indexNode = this.getChildByName( 'index' );
562
+ const index = indexNode ? parseInt( indexNode.value ) : 0;
563
+
564
+ node = vertexColor( index );
565
+
566
+ } else if ( element === 'tiledimage' ) {
567
+
568
+ const file = this.getChildByName( 'file' );
569
+
570
+ const textureFile = file.getTexture();
571
+ const uvTiling = mx_transform_uv( ...this.getNodesByNames( [ 'uvtiling', 'uvoffset' ] ) );
572
+
573
+ node = texture( textureFile, uvTiling );
574
+
575
+ const colorSpaceNode = file.getColorSpaceNode();
576
+
577
+ if ( colorSpaceNode ) {
578
+
579
+ node = colorSpaceNode( node );
580
+
581
+ }
582
+
583
+ } else if ( element === 'image' ) {
584
+
585
+ const file = this.getChildByName( 'file' );
586
+ const uvNode = this.getNodeByName( 'texcoord' );
587
+
588
+ const textureFile = file.getTexture();
589
+
590
+ node = texture( textureFile, uvNode );
591
+
592
+ const colorSpaceNode = file.getColorSpaceNode();
593
+
594
+ if ( colorSpaceNode ) {
595
+
596
+ node = colorSpaceNode( node );
597
+
598
+ }
599
+
600
+ } else if ( MtlXLibrary[ element ] !== undefined ) {
601
+
602
+ const nodeElement = MtlXLibrary[ element ];
603
+
604
+ if ( ! nodeElement ) {
605
+
606
+ throw new Error( `THREE.MaterialXLoader: Unexpected node ${ new XMLSerializer().serializeToString( this.nodeXML ) }.` );
607
+
608
+ }
609
+
610
+ if ( ! nodeElement.nodeFunc ) {
611
+
612
+ throw new Error( `THREE.MaterialXLoader: Unexpected node 2 ${ new XMLSerializer().serializeToString( this.nodeXML ) }.` );
613
+
614
+ }
615
+
616
+ if ( out !== null ) {
617
+
618
+ node = nodeElement.nodeFunc( ...this.getNodesByNames( ...nodeElement.params ), out );
619
+
620
+ } else {
621
+
622
+ node = nodeElement.nodeFunc( ...this.getNodesByNames( ...nodeElement.params ) );
623
+
624
+ }
625
+
626
+ }
627
+
628
+ }
629
+
630
+ //
631
+
632
+ if ( node === null ) {
633
+
634
+ console.warn( `THREE.MaterialXLoader: Unexpected node ${ new XMLSerializer().serializeToString( this.nodeXML ) }.` );
635
+
636
+ node = float( 0 );
637
+
638
+ }
639
+
640
+ //
641
+
642
+ const nodeToTypeClass = this.getClassFromType( type );
643
+
644
+ if ( nodeToTypeClass !== null ) {
645
+
646
+ node = nodeToTypeClass( node );
647
+
648
+ } else {
649
+
650
+ console.warn( `THREE.MaterialXLoader: Unexpected node ${ new XMLSerializer().serializeToString( this.nodeXML ) }.` );
651
+ node = float( 0 );
652
+
653
+ }
654
+
655
+ node.name = this.name;
656
+
657
+ this.node = node;
658
+
659
+ return node;
660
+
661
+ }
662
+
663
+ getChildByName( name ) {
664
+
665
+ for ( const input of this.children ) {
666
+
667
+ if ( input.name === name ) {
668
+
669
+ return input;
670
+
671
+ }
672
+
673
+ }
674
+
675
+ }
676
+
677
+ getNodes() {
678
+
679
+ const nodes = {};
680
+
681
+ for ( const input of this.children ) {
682
+
683
+ const node = input.getNode();
684
+
685
+ nodes[ node.name ] = node;
686
+
687
+ }
688
+
689
+ return nodes;
690
+
691
+ }
692
+
693
+ getNodeByName( name ) {
694
+
695
+ const child = this.getChildByName( name );
696
+
697
+ return child ? child.getNode( child.output ) : undefined;
698
+
699
+ }
700
+
701
+ getNodesByNames( ...names ) {
702
+
703
+ const nodes = [];
704
+
705
+ for ( const name of names ) {
706
+
707
+ const node = this.getNodeByName( name );
708
+
709
+ if ( node ) nodes.push( node );
710
+
711
+ }
712
+
713
+ return nodes;
714
+
715
+ }
716
+
717
+ getValue() {
718
+
719
+ return this.value.trim();
720
+
721
+ }
722
+
723
+ getVector() {
724
+
725
+ const vector = [];
726
+
727
+ for ( const val of this.getValue().split( /[,|\s]/ ) ) {
728
+
729
+ if ( val !== '' ) {
730
+
731
+ vector.push( Number( val.trim() ) );
732
+
733
+ }
734
+
735
+ }
736
+
737
+ return vector;
738
+
739
+ }
740
+
741
+ getAttribute( name ) {
742
+
743
+ return this.nodeXML.getAttribute( name );
744
+
745
+ }
746
+
747
+ getRecursiveAttribute( name ) {
748
+
749
+ let attribute = this.nodeXML.getAttribute( name );
750
+
751
+ if ( attribute === null && this.parent !== null ) {
752
+
753
+ attribute = this.parent.getRecursiveAttribute( name );
754
+
755
+ }
756
+
757
+ return attribute;
758
+
759
+ }
760
+
761
+ setStandardSurfaceToGltfPBR( material ) {
762
+
763
+ const inputs = this.getNodes();
764
+
765
+ //
766
+
767
+ let colorNode = null;
768
+
769
+ if ( inputs.base && inputs.base_color ) colorNode = mul( inputs.base, inputs.base_color );
770
+ else if ( inputs.base ) colorNode = inputs.base;
771
+ else if ( inputs.base_color ) colorNode = inputs.base_color;
772
+
773
+ //
774
+
775
+ let opacityNode = null;
776
+
777
+ if ( inputs.opacity ) opacityNode = inputs.opacity;
778
+
779
+ //
780
+
781
+ let roughnessNode = null;
782
+
783
+ if ( inputs.specular_roughness ) roughnessNode = inputs.specular_roughness;
784
+
785
+ //
786
+
787
+ let metalnessNode = null;
788
+
789
+ if ( inputs.metalness ) metalnessNode = inputs.metalness;
790
+
791
+ //
792
+
793
+ let specularIntensityNode = null;
794
+
795
+ if ( inputs.specular ) specularIntensityNode = inputs.specular;
796
+
797
+ //
798
+
799
+ let specularColorNode = null;
800
+
801
+ if ( inputs.specular_color ) specularColorNode = inputs.specular_color;
802
+
803
+ //
804
+
805
+ let iorNode = null;
806
+
807
+ if ( inputs.ior ) iorNode = inputs.ior;
808
+
809
+ //
810
+
811
+ let anisotropyNode = null;
812
+ let anisotropyRotationNode = null;
813
+
814
+ if ( inputs.specular_anisotropy ) anisotropyNode = inputs.specular_anisotropy;
815
+ if ( inputs.specular_rotation ) anisotropyRotationNode = inputs.specular_rotation;
816
+
817
+ //
818
+
819
+ let transmissionNode = null;
820
+ let transmissionColorNode = null;
821
+
822
+ if ( inputs.transmission ) transmissionNode = inputs.transmission;
823
+ if ( inputs.transmission_color ) transmissionColorNode = inputs.transmission_color;
824
+
825
+ //
826
+
827
+ let thinFilmThicknessNode = null;
828
+ let thinFilmIorNode = null;
829
+
830
+ if ( inputs.thin_film_thickness ) thinFilmThicknessNode = inputs.thin_film_thickness;
831
+
832
+ if ( inputs.thin_film_ior ) {
833
+
834
+ // Clamp IOR to valid range for Three.js (1.0 to 2.333)
835
+ thinFilmIorNode = clamp( inputs.thin_film_ior, float( 1.0 ), float( 2.333 ) );
836
+
837
+ }
838
+
839
+ //
840
+
841
+ let sheenNode = null;
842
+ let sheenColorNode = null;
843
+ let sheenRoughnessNode = null;
844
+
845
+ if ( inputs.sheen ) sheenNode = inputs.sheen;
846
+ if ( inputs.sheen_color ) sheenColorNode = inputs.sheen_color;
847
+ if ( inputs.sheen_roughness ) sheenRoughnessNode = inputs.sheen_roughness;
848
+
849
+ //
850
+
851
+ let clearcoatNode = null;
852
+ let clearcoatRoughnessNode = null;
853
+
854
+ if ( inputs.coat ) clearcoatNode = inputs.coat;
855
+ if ( inputs.coat_roughness ) clearcoatRoughnessNode = inputs.coat_roughness;
856
+
857
+ if ( inputs.coat_color ) {
858
+
859
+ colorNode = colorNode ? mul( colorNode, inputs.coat_color ) : colorNode;
860
+
861
+ }
862
+
863
+ //
864
+
865
+ let normalNode = null;
866
+
867
+ if ( inputs.normal ) normalNode = inputs.normal;
868
+
869
+ //
870
+
871
+ let emissiveNode = null;
872
+
873
+ if ( inputs.emission ) emissiveNode = inputs.emission;
874
+ if ( inputs.emissionColor ) {
875
+
876
+ emissiveNode = emissiveNode ? mul( emissiveNode, inputs.emissionColor ) : emissiveNode;
877
+
878
+ }
879
+
880
+ //
881
+
882
+ material.colorNode = colorNode || color( 0.8, 0.8, 0.8 );
883
+ material.opacityNode = opacityNode || float( 1.0 );
884
+ material.roughnessNode = roughnessNode || float( 0.2 );
885
+ material.metalnessNode = metalnessNode || float( 0 );
886
+ material.specularIntensityNode = specularIntensityNode || float( 0.5 );
887
+ material.specularColorNode = specularColorNode || color( 1.0, 1.0, 1.0 );
888
+ material.iorNode = iorNode || float( 1.5 );
889
+
890
+ if ( anisotropyNode !== null ) {
891
+
892
+ material.anisotropyNode = anisotropyNode;
893
+ material.anisotropyRotationNode = anisotropyRotationNode || float( 0 );
894
+
895
+ }
896
+
897
+ if ( transmissionNode !== null ) {
898
+
899
+ material.transmissionNode = transmissionNode;
900
+ material.transmissionColorNode = transmissionColorNode || color( 1.0, 1.0, 1.0 );
901
+
902
+ }
903
+
904
+ material.thinFilmThicknessNode = thinFilmThicknessNode || float( 0 );
905
+ material.thinFilmIorNode = thinFilmIorNode || float( 1.5 );
906
+
907
+ if ( sheenNode !== null ) {
908
+
909
+ material.sheenNode = sheenNode;
910
+ material.sheenColorNode = sheenColorNode || color( 1.0, 1.0, 1.0 );
911
+ material.sheenRoughnessNode = sheenRoughnessNode || float( 0.5 );
912
+
913
+ }
914
+
915
+ if ( clearcoatNode !== null ) {
916
+
917
+ material.clearcoatNode = clearcoatNode;
918
+ material.clearcoatRoughnessNode = clearcoatRoughnessNode || float( 0 );
919
+
920
+ }
921
+
922
+ if ( normalNode ) material.normalNode = normalNode;
923
+ if ( emissiveNode ) material.emissiveNode = emissiveNode;
924
+
925
+ // Auto-enable iridescence when thin film parameters are present
926
+ if ( thinFilmThicknessNode && thinFilmThicknessNode.value !== undefined && thinFilmThicknessNode.value > 0 ) {
927
+
928
+ material.iridescence = 1.0;
929
+
930
+ }
931
+
932
+ if ( opacityNode !== null ) {
933
+
934
+ material.transparent = true;
935
+
936
+ }
937
+
938
+ if ( transmissionNode !== null ) {
939
+
940
+ material.side = DoubleSide;
941
+ material.transparent = true;
942
+
943
+ }
944
+
945
+ }
946
+
947
+ /*setGltfPBR( material ) {
948
+
949
+ const inputs = this.getNodes();
950
+
951
+ console.log( inputs );
952
+
953
+ }*/
954
+
955
+ setMaterial( material ) {
956
+
957
+ const element = this.element;
958
+
959
+ if ( element === 'gltf_pbr' ) {
960
+
961
+ //this.setGltfPBR( material );
962
+
963
+ } else if ( element === 'standard_surface' ) {
964
+
965
+ this.setStandardSurfaceToGltfPBR( material );
966
+
967
+ }
968
+
969
+ }
970
+
971
+ toBasicMaterial() {
972
+
973
+ const material = new MeshBasicNodeMaterial();
974
+ material.name = this.name;
975
+
976
+ for ( const nodeX of this.children.toReversed() ) {
977
+
978
+ if ( nodeX.name === 'out' ) {
979
+
980
+ material.colorNode = nodeX.getNode();
981
+
982
+ break;
983
+
984
+ }
985
+
986
+ }
987
+
988
+ return material;
989
+
990
+ }
991
+
992
+ toPhysicalMaterial() {
993
+
994
+ const material = new MeshPhysicalNodeMaterial();
995
+ material.name = this.name;
996
+
997
+ for ( const nodeX of this.children ) {
998
+
999
+ const shaderProperties = this.materialX.getMaterialXNode( nodeX.nodeName );
1000
+ shaderProperties.setMaterial( material );
1001
+
1002
+ }
1003
+
1004
+ return material;
1005
+
1006
+ }
1007
+
1008
+ toMaterials() {
1009
+
1010
+ const materials = {};
1011
+
1012
+ let isUnlit = true;
1013
+
1014
+ for ( const nodeX of this.children ) {
1015
+
1016
+ if ( nodeX.element === 'surfacematerial' ) {
1017
+
1018
+ const material = nodeX.toPhysicalMaterial();
1019
+
1020
+ materials[ material.name ] = material;
1021
+
1022
+ isUnlit = false;
1023
+
1024
+ }
1025
+
1026
+ }
1027
+
1028
+ if ( isUnlit ) {
1029
+
1030
+ for ( const nodeX of this.children ) {
1031
+
1032
+ if ( nodeX.element === 'nodegraph' ) {
1033
+
1034
+ const material = nodeX.toBasicMaterial();
1035
+
1036
+ materials[ material.name ] = material;
1037
+
1038
+ }
1039
+
1040
+ }
1041
+
1042
+ }
1043
+
1044
+ return materials;
1045
+
1046
+ }
1047
+
1048
+ add( materialXNode ) {
1049
+
1050
+ materialXNode.parent = this;
1051
+
1052
+ this.children.push( materialXNode );
1053
+
1054
+ }
1055
+
1056
+ }
1057
+
1058
+ class MaterialX {
1059
+
1060
+ constructor( manager, path ) {
1061
+
1062
+ this.manager = manager;
1063
+ this.path = path;
1064
+ this.resourcePath = '';
1065
+
1066
+ this.nodesXLib = new Map();
1067
+ //this.nodesXRefLib = new WeakMap();
1068
+
1069
+ this.textureLoader = new ImageBitmapLoader( manager );
1070
+ this.textureLoader.setOptions( { imageOrientation: 'flipY' } );
1071
+
1072
+ this.textureCache = new Map();
1073
+
1074
+ }
1075
+
1076
+ addMaterialXNode( materialXNode ) {
1077
+
1078
+ this.nodesXLib.set( materialXNode.nodePath, materialXNode );
1079
+
1080
+ }
1081
+
1082
+ /*getMaterialXNodeFromXML( xmlNode ) {
1083
+
1084
+ return this.nodesXRefLib.get( xmlNode );
1085
+
1086
+ }*/
1087
+
1088
+ getMaterialXNode( ...names ) {
1089
+
1090
+ return this.nodesXLib.get( names.join( '/' ) );
1091
+
1092
+ }
1093
+
1094
+ parseNode( nodeXML, nodePath = '' ) {
1095
+
1096
+ const materialXNode = new MaterialXNode( this, nodeXML, nodePath );
1097
+ if ( materialXNode.nodePath ) this.addMaterialXNode( materialXNode );
1098
+
1099
+ for ( const childNodeXML of nodeXML.children ) {
1100
+
1101
+ const childMXNode = this.parseNode( childNodeXML, materialXNode.nodePath );
1102
+ materialXNode.add( childMXNode );
1103
+
1104
+ }
1105
+
1106
+ return materialXNode;
1107
+
1108
+ }
1109
+
1110
+ parse( text ) {
1111
+
1112
+ const rootXML = new DOMParser().parseFromString( text, 'application/xml' ).documentElement;
1113
+
1114
+ this.textureLoader.setPath( this.path );
1115
+
1116
+ //
1117
+
1118
+ const materials = this.parseNode( rootXML ).toMaterials();
1119
+
1120
+ return { materials };
1121
+
1122
+ }
1123
+
1124
+ }
1125
+
1126
+ export { MaterialXLoader };