three-usd-robot 0.11.0 → 0.13.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.
- package/README.md +32 -280
- package/dist/MeshBinding-B_8RhuQE.d.ts +288 -0
- package/dist/{ThreeUsdRobot-BxnCluuK.d.ts → ThreeUsdRobot-X1zbpRZo.d.ts} +38 -8
- package/dist/{ThreeUsdRobotLoader-C-E9uwEe.d.ts → ThreeUsdRobotLoader-u3d1yoLM.d.ts} +11 -3
- package/dist/{buildKinematicTree-BCySuZZn.d.ts → buildKinematicTree-Q9JOjAjM.d.ts} +17 -3
- package/dist/bytes-CxGRGry_.d.ts +14 -0
- package/dist/{chunk-BCRRXGNB.js → chunk-5ZPHZ5ZH.js} +81 -6
- package/dist/chunk-5ZPHZ5ZH.js.map +1 -0
- package/dist/{chunk-AXPMXEQC.js → chunk-FUVHAORT.js} +77 -717
- package/dist/chunk-FUVHAORT.js.map +1 -0
- package/dist/{chunk-5SVRTKS4.js → chunk-GRJGPHLW.js} +18 -11
- package/dist/chunk-GRJGPHLW.js.map +1 -0
- package/dist/chunk-JGIVJXBU.js +54 -0
- package/dist/chunk-JGIVJXBU.js.map +1 -0
- package/dist/{chunk-ENWFOYHU.js → chunk-JN2QPDB3.js} +101 -14
- package/dist/chunk-JN2QPDB3.js.map +1 -0
- package/dist/chunk-PPPRB6KE.js +963 -0
- package/dist/chunk-PPPRB6KE.js.map +1 -0
- package/dist/{chunk-LDO5FKQS.js → chunk-YGJ23CG3.js} +4 -53
- package/dist/chunk-YGJ23CG3.js.map +1 -0
- package/dist/core.d.ts +8 -65
- package/dist/core.js +5 -3
- package/dist/extras.d.ts +2 -2
- package/dist/helpers.d.ts +2 -2
- package/dist/helpers.js +3 -2
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts +22 -263
- package/dist/index.js +35 -9
- package/dist/index.js.map +1 -1
- package/dist/nodes.d.ts +49 -0
- package/dist/nodes.js +439 -0
- package/dist/nodes.js.map +1 -0
- package/dist/parseMdl-vfzBGoMr.d.ts +87 -0
- package/dist/react.d.ts +6 -4
- package/dist/react.js +6 -4
- package/dist/react.js.map +1 -1
- package/package.json +6 -2
- package/dist/bytes-MOJ2oN-u.d.ts +0 -42
- package/dist/chunk-5SVRTKS4.js.map +0 -1
- package/dist/chunk-AXPMXEQC.js.map +0 -1
- package/dist/chunk-BCRRXGNB.js.map +0 -1
- package/dist/chunk-ENWFOYHU.js.map +0 -1
- package/dist/chunk-LDO5FKQS.js.map +0 -1
package/dist/nodes.js
ADDED
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
import { findBoundSurfaceShader, MTLX_STANDARD_SURFACE, readMtlxImage } from './chunk-PPPRB6KE.js';
|
|
2
|
+
import './chunk-JGIVJXBU.js';
|
|
3
|
+
import * as TSL from 'three/tsl';
|
|
4
|
+
import { MeshPhysicalNodeMaterial } from 'three/webgpu';
|
|
5
|
+
|
|
6
|
+
// src/nodes/loadMaterialXDocument.ts
|
|
7
|
+
async function loadMaterialXDocument(url, manager) {
|
|
8
|
+
const { MaterialXLoader } = await import('three/addons/loaders/MaterialXLoader.js');
|
|
9
|
+
const { materials } = await new MaterialXLoader(manager).loadAsync(url);
|
|
10
|
+
return materials;
|
|
11
|
+
}
|
|
12
|
+
function createMaterialXNodeFactory(options = {}) {
|
|
13
|
+
return (prim, stage) => {
|
|
14
|
+
const shader = findBoundSurfaceShader(stage, prim);
|
|
15
|
+
if (!shader || shader.GetAttribute("info:id").Get() !== MTLX_STANDARD_SURFACE) return null;
|
|
16
|
+
try {
|
|
17
|
+
return buildStandardSurfaceNodeMaterial(shader, options.textureProvider);
|
|
18
|
+
} catch (error) {
|
|
19
|
+
if (error instanceof UnsupportedMtlxNodeError) {
|
|
20
|
+
options.onWarn?.(
|
|
21
|
+
`${prim.GetPath()}: ${error.message}; falling back to the parameter mapping`
|
|
22
|
+
);
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
var UnsupportedMtlxNodeError = class extends Error {
|
|
30
|
+
};
|
|
31
|
+
function buildStandardSurfaceNodeMaterial(shader, textureProvider) {
|
|
32
|
+
const ctx = {
|
|
33
|
+
stage: shader.GetStage(),
|
|
34
|
+
textures: textureProvider,
|
|
35
|
+
cache: /* @__PURE__ */ new Map()
|
|
36
|
+
};
|
|
37
|
+
const input = (name) => inputValue(shader, name, ctx, 0);
|
|
38
|
+
const material = new MeshPhysicalNodeMaterial();
|
|
39
|
+
const base = input("base");
|
|
40
|
+
const baseColor = input("base_color");
|
|
41
|
+
if (baseColor) {
|
|
42
|
+
material.colorNode = base ? TSL.mul(base.node, baseColor.node) : baseColor.node;
|
|
43
|
+
} else if (base) {
|
|
44
|
+
material.colorNode = TSL.mul(base.node, TSL.color(0.8, 0.8, 0.8));
|
|
45
|
+
}
|
|
46
|
+
const metalness = input("metalness");
|
|
47
|
+
if (metalness) material.metalnessNode = toFloat(metalness);
|
|
48
|
+
const roughness = input("specular_roughness");
|
|
49
|
+
if (roughness) material.roughnessNode = toFloat(roughness);
|
|
50
|
+
const ior = input("specular_IOR");
|
|
51
|
+
if (ior) material.iorNode = toFloat(ior);
|
|
52
|
+
const transmission = input("transmission");
|
|
53
|
+
if (transmission) material.transmissionNode = toFloat(transmission);
|
|
54
|
+
const coat = input("coat");
|
|
55
|
+
if (coat) material.clearcoatNode = toFloat(coat);
|
|
56
|
+
const coatRoughness = input("coat_roughness");
|
|
57
|
+
if (coatRoughness) material.clearcoatRoughnessNode = toFloat(coatRoughness);
|
|
58
|
+
const emission = input("emission");
|
|
59
|
+
if (emission) {
|
|
60
|
+
const emissionColor = input("emission_color");
|
|
61
|
+
material.emissiveNode = emissionColor ? TSL.mul(emission.node, emissionColor.node) : emission.node;
|
|
62
|
+
}
|
|
63
|
+
const opacity = input("opacity");
|
|
64
|
+
if (opacity) {
|
|
65
|
+
material.opacityNode = toFloat(opacity);
|
|
66
|
+
material.transparent = true;
|
|
67
|
+
}
|
|
68
|
+
const normal = input("normal");
|
|
69
|
+
if (normal) material.normalNode = normal.node;
|
|
70
|
+
return material;
|
|
71
|
+
}
|
|
72
|
+
function toFloat(value) {
|
|
73
|
+
const n = value.node;
|
|
74
|
+
if (value.size === 1) return n;
|
|
75
|
+
if (value.size === 2) return TSL.add(n.x, n.y).div(2);
|
|
76
|
+
if (value.size === 3) return TSL.add(n.x, n.y, n.z).div(3);
|
|
77
|
+
return TSL.add(n.x, n.y, n.z, n.w).div(4);
|
|
78
|
+
}
|
|
79
|
+
function inputValue(prim, name, ctx, depth) {
|
|
80
|
+
const attr = prim.GetAttribute(`inputs:${name}`);
|
|
81
|
+
const connection = attr.GetConnections()[0];
|
|
82
|
+
if (connection) {
|
|
83
|
+
const [path, output] = splitConnection(connection);
|
|
84
|
+
const source = ctx.stage.GetPrimAtPath(path);
|
|
85
|
+
if (!source) throw new UnsupportedMtlxNodeError(`unresolvable connection "${connection}"`);
|
|
86
|
+
return nodeValue(source, output, ctx, depth + 1);
|
|
87
|
+
}
|
|
88
|
+
const value = attr.Get();
|
|
89
|
+
if (value === void 0) return null;
|
|
90
|
+
return constantValue(value, attr.GetTypeName());
|
|
91
|
+
}
|
|
92
|
+
function splitConnection(connection) {
|
|
93
|
+
const dot2 = connection.indexOf(".");
|
|
94
|
+
if (dot2 < 0) return [connection, "out"];
|
|
95
|
+
return [connection.slice(0, dot2), connection.slice(dot2 + 1).replace(/^outputs:/, "")];
|
|
96
|
+
}
|
|
97
|
+
function constantValue(value, typeName) {
|
|
98
|
+
if (typeof value === "number") return { node: TSL.float(value), size: 1 };
|
|
99
|
+
if (typeof value === "boolean") return { node: TSL.float(value ? 1 : 0), size: 1 };
|
|
100
|
+
if (Array.isArray(value) && value.every((n) => typeof n === "number")) {
|
|
101
|
+
const [x = 0, y = 0, z = 0, w = 0] = value;
|
|
102
|
+
if (value.length === 2) return { node: TSL.vec2(x, y), size: 2 };
|
|
103
|
+
if (value.length === 3) {
|
|
104
|
+
const isColor = typeName.toLowerCase().includes("color");
|
|
105
|
+
return { node: isColor ? TSL.color(x, y, z) : TSL.vec3(x, y, z), size: 3 };
|
|
106
|
+
}
|
|
107
|
+
if (value.length === 4) return { node: TSL.vec4(x, y, z, w), size: 4 };
|
|
108
|
+
}
|
|
109
|
+
throw new UnsupportedMtlxNodeError(`unsupported constant value type "${typeName}"`);
|
|
110
|
+
}
|
|
111
|
+
var TYPE_SIZE = {
|
|
112
|
+
float: 1,
|
|
113
|
+
integer: 1,
|
|
114
|
+
boolean: 1,
|
|
115
|
+
vector2: 2,
|
|
116
|
+
vector2FA: 2,
|
|
117
|
+
color3: 3,
|
|
118
|
+
color3FA: 3,
|
|
119
|
+
vector3: 3,
|
|
120
|
+
vector3FA: 3,
|
|
121
|
+
color4: 4,
|
|
122
|
+
color4FA: 4,
|
|
123
|
+
vector4: 4,
|
|
124
|
+
vector4FA: 4
|
|
125
|
+
};
|
|
126
|
+
function parseNodeId(id) {
|
|
127
|
+
const body = id.startsWith("ND_") ? id.slice(3) : id;
|
|
128
|
+
const cut = body.lastIndexOf("_");
|
|
129
|
+
if (cut > 0) {
|
|
130
|
+
const type = body.slice(cut + 1);
|
|
131
|
+
const size = TYPE_SIZE[type];
|
|
132
|
+
if (size) return { op: body.slice(0, cut), size, type };
|
|
133
|
+
}
|
|
134
|
+
return { op: body, size: 1, type: "float" };
|
|
135
|
+
}
|
|
136
|
+
var UNARY = {
|
|
137
|
+
absval: TSL.abs,
|
|
138
|
+
floor: TSL.floor,
|
|
139
|
+
ceil: TSL.ceil,
|
|
140
|
+
sin: TSL.sin,
|
|
141
|
+
cos: TSL.cos,
|
|
142
|
+
tan: TSL.tan,
|
|
143
|
+
exp: TSL.exp,
|
|
144
|
+
ln: TSL.log,
|
|
145
|
+
sqrt: TSL.sqrt,
|
|
146
|
+
sign: TSL.sign,
|
|
147
|
+
normalize: TSL.normalize
|
|
148
|
+
};
|
|
149
|
+
var BINARY = {
|
|
150
|
+
add: { fn: TSL.add, neutral: 0 },
|
|
151
|
+
subtract: { fn: TSL.sub, neutral: 0 },
|
|
152
|
+
multiply: { fn: TSL.mul, neutral: 1 },
|
|
153
|
+
divide: { fn: TSL.div, neutral: 1 },
|
|
154
|
+
power: { fn: TSL.pow, neutral: 1 },
|
|
155
|
+
modulo: { fn: TSL.mod, neutral: 1 },
|
|
156
|
+
min: { fn: TSL.min, neutral: 0 },
|
|
157
|
+
max: { fn: TSL.max, neutral: 0 }
|
|
158
|
+
};
|
|
159
|
+
var COMPONENTS = ["x", "y", "z", "w"];
|
|
160
|
+
var OUTPUT_COMPONENT = {
|
|
161
|
+
outx: 0,
|
|
162
|
+
outy: 1,
|
|
163
|
+
outz: 2,
|
|
164
|
+
outw: 3,
|
|
165
|
+
outr: 0,
|
|
166
|
+
outg: 1,
|
|
167
|
+
outb: 2,
|
|
168
|
+
outa: 3
|
|
169
|
+
};
|
|
170
|
+
function component(node, index) {
|
|
171
|
+
return node[COMPONENTS[Math.max(0, Math.min(index, 3))]];
|
|
172
|
+
}
|
|
173
|
+
var MAX_NODE_DEPTH = 16;
|
|
174
|
+
function nodeValue(node, output, ctx, depth) {
|
|
175
|
+
const key = `${node.GetPath()}.${output}`;
|
|
176
|
+
const cached = ctx.cache.get(key);
|
|
177
|
+
if (cached) return cached;
|
|
178
|
+
if (depth > MAX_NODE_DEPTH) {
|
|
179
|
+
throw new UnsupportedMtlxNodeError(`graph too deep at ${node.GetPath()} (cycle?)`);
|
|
180
|
+
}
|
|
181
|
+
const value = convertNode(node, output, ctx, depth);
|
|
182
|
+
ctx.cache.set(key, value);
|
|
183
|
+
return value;
|
|
184
|
+
}
|
|
185
|
+
function convertNode(node, output, ctx, depth) {
|
|
186
|
+
const id = node.GetAttribute("info:id").Get();
|
|
187
|
+
if (typeof id !== "string") {
|
|
188
|
+
throw new UnsupportedMtlxNodeError(`${node.GetPath()} has no info:id`);
|
|
189
|
+
}
|
|
190
|
+
const { op, size, type } = parseNodeId(id);
|
|
191
|
+
const opt = (name) => inputValue(node, name, ctx, depth);
|
|
192
|
+
const req = (name) => {
|
|
193
|
+
const value = opt(name);
|
|
194
|
+
if (!value) throw new UnsupportedMtlxNodeError(`node "${id}" is missing input "${name}"`);
|
|
195
|
+
return value;
|
|
196
|
+
};
|
|
197
|
+
const scalar = (name, fallback) => opt(name) ?? { node: TSL.float(fallback), size: 1 };
|
|
198
|
+
if (op === "image" || op === "tiledimage") {
|
|
199
|
+
return imageValue(node, op === "tiledimage", size, type, ctx, depth);
|
|
200
|
+
}
|
|
201
|
+
const unary = UNARY[op];
|
|
202
|
+
if (unary) {
|
|
203
|
+
const in_ = req("in");
|
|
204
|
+
return { node: unary(in_.node), size: in_.size };
|
|
205
|
+
}
|
|
206
|
+
const binary = BINARY[op];
|
|
207
|
+
if (binary) {
|
|
208
|
+
const in1 = req("in1");
|
|
209
|
+
const in2 = scalar("in2", binary.neutral);
|
|
210
|
+
return { node: binary.fn(in1.node, in2.node), size: maxSize(in1, in2) };
|
|
211
|
+
}
|
|
212
|
+
switch (op) {
|
|
213
|
+
case "invert": {
|
|
214
|
+
const in_ = req("in");
|
|
215
|
+
return { node: TSL.sub(scalar("amount", 1).node, in_.node), size: in_.size };
|
|
216
|
+
}
|
|
217
|
+
case "magnitude":
|
|
218
|
+
return { node: TSL.length(req("in").node), size: 1 };
|
|
219
|
+
case "dotproduct":
|
|
220
|
+
return { node: TSL.dot(req("in1").node, req("in2").node), size: 1 };
|
|
221
|
+
case "crossproduct":
|
|
222
|
+
return { node: TSL.cross(req("in1").node, req("in2").node), size: 3 };
|
|
223
|
+
case "clamp": {
|
|
224
|
+
const in_ = req("in");
|
|
225
|
+
const node2 = TSL.clamp(in_.node, scalar("low", 0).node, scalar("high", 1).node);
|
|
226
|
+
return { node: node2, size: in_.size };
|
|
227
|
+
}
|
|
228
|
+
case "mix": {
|
|
229
|
+
const bg = scalar("bg", 0);
|
|
230
|
+
const fg = scalar("fg", 0);
|
|
231
|
+
return { node: TSL.mix(bg.node, fg.node, scalar("mix", 0).node), size: maxSize(bg, fg) };
|
|
232
|
+
}
|
|
233
|
+
case "smoothstep": {
|
|
234
|
+
const in_ = req("in");
|
|
235
|
+
const node2 = TSL.smoothstep(scalar("low", 0).node, scalar("high", 1).node, in_.node);
|
|
236
|
+
return { node: node2, size: in_.size };
|
|
237
|
+
}
|
|
238
|
+
case "remap": {
|
|
239
|
+
const in_ = req("in");
|
|
240
|
+
const node2 = TSL.remap(
|
|
241
|
+
in_.node,
|
|
242
|
+
scalar("inlow", 0).node,
|
|
243
|
+
scalar("inhigh", 1).node,
|
|
244
|
+
scalar("outlow", 0).node,
|
|
245
|
+
scalar("outhigh", 1).node
|
|
246
|
+
);
|
|
247
|
+
return { node: node2, size: in_.size };
|
|
248
|
+
}
|
|
249
|
+
case "ifgreater": {
|
|
250
|
+
const in1 = req("in1");
|
|
251
|
+
const in2 = scalar("in2", 0);
|
|
252
|
+
const cond = TSL.greaterThan(scalar("value1", 1).node, scalar("value2", 0).node);
|
|
253
|
+
return { node: TSL.select(cond, in1.node, in2.node), size: maxSize(in1, in2) };
|
|
254
|
+
}
|
|
255
|
+
// ---- ramps & splits
|
|
256
|
+
case "ramplr":
|
|
257
|
+
case "ramptb": {
|
|
258
|
+
const l = scalar(op === "ramplr" ? "valuel" : "valuet", 0);
|
|
259
|
+
const r = scalar(op === "ramplr" ? "valuer" : "valueb", 0);
|
|
260
|
+
const fn = op === "ramplr" ? TSL.mx_ramplr : TSL.mx_ramptb;
|
|
261
|
+
return { node: fn(l.node, r.node, texcoordOf(node, ctx, depth)), size: maxSize(l, r) };
|
|
262
|
+
}
|
|
263
|
+
case "splitlr":
|
|
264
|
+
case "splittb": {
|
|
265
|
+
const l = scalar(op === "splitlr" ? "valuel" : "valuet", 0);
|
|
266
|
+
const r = scalar(op === "splitlr" ? "valuer" : "valueb", 0);
|
|
267
|
+
const fn = op === "splitlr" ? TSL.mx_splitlr : TSL.mx_splittb;
|
|
268
|
+
const split = fn(l.node, r.node, scalar("center", 0.5).node, texcoordOf(node, ctx, depth));
|
|
269
|
+
return { node: split, size: maxSize(l, r) };
|
|
270
|
+
}
|
|
271
|
+
// ---- noise
|
|
272
|
+
case "noise2d":
|
|
273
|
+
case "noise3d": {
|
|
274
|
+
const coord = opt("texcoord")?.node ?? opt("position")?.node ?? (op === "noise2d" ? TSL.uv() : TSL.positionLocal);
|
|
275
|
+
const amplitude = scalar("amplitude", 1).node;
|
|
276
|
+
const pivot = scalar("pivot", 0).node;
|
|
277
|
+
if (size === 1) return { node: TSL.mx_noise_float(coord, amplitude, pivot), size: 1 };
|
|
278
|
+
if (size === 4) return { node: TSL.mx_noise_vec4(coord, amplitude, pivot), size: 4 };
|
|
279
|
+
const vec3Noise = TSL.mx_noise_vec3(coord, amplitude, pivot);
|
|
280
|
+
return size === 2 ? { node: vec3Noise.xy, size: 2 } : { node: vec3Noise, size: 3 };
|
|
281
|
+
}
|
|
282
|
+
case "fractal3d": {
|
|
283
|
+
const position = opt("position")?.node ?? TSL.positionLocal;
|
|
284
|
+
const octaves = scalar("octaves", 3).node;
|
|
285
|
+
const lacunarity = scalar("lacunarity", 2).node;
|
|
286
|
+
const diminish = scalar("diminish", 0.5).node;
|
|
287
|
+
const amplitude = scalar("amplitude", 1).node;
|
|
288
|
+
const fn = size === 1 ? TSL.mx_fractal_noise_float : size === 2 ? TSL.mx_fractal_noise_vec2 : size === 4 ? TSL.mx_fractal_noise_vec4 : TSL.mx_fractal_noise_vec3;
|
|
289
|
+
return { node: fn(position, octaves, lacunarity, diminish, amplitude), size };
|
|
290
|
+
}
|
|
291
|
+
case "cellnoise2d":
|
|
292
|
+
case "cellnoise3d":
|
|
293
|
+
return { node: TSL.mx_cell_noise_float(texcoordOf(node, ctx, depth)), size: 1 };
|
|
294
|
+
case "worleynoise2d":
|
|
295
|
+
case "worleynoise3d": {
|
|
296
|
+
const coord = texcoordOf(node, ctx, depth);
|
|
297
|
+
const jitter = scalar("jitter", 1).node;
|
|
298
|
+
const fn = size === 2 ? TSL.mx_worley_noise_vec2 : size === 3 ? TSL.mx_worley_noise_vec3 : TSL.mx_worley_noise_float;
|
|
299
|
+
return { node: fn(coord, jitter), size: size === 2 || size === 3 ? size : 1 };
|
|
300
|
+
}
|
|
301
|
+
// ---- color
|
|
302
|
+
case "hsvtorgb":
|
|
303
|
+
return { node: TSL.mx_hsvtorgb(req("in").node), size: 3 };
|
|
304
|
+
case "rgbtohsv":
|
|
305
|
+
return { node: TSL.mx_rgbtohsv(req("in").node), size: 3 };
|
|
306
|
+
case "luminance":
|
|
307
|
+
return { node: TSL.luminance(req("in").node), size: 1 };
|
|
308
|
+
case "saturate": {
|
|
309
|
+
const in_ = req("in");
|
|
310
|
+
return { node: TSL.saturation(in_.node, scalar("amount", 1).node), size: in_.size };
|
|
311
|
+
}
|
|
312
|
+
case "contrast": {
|
|
313
|
+
const in_ = req("in");
|
|
314
|
+
const node2 = TSL.mx_contrast(in_.node, scalar("amount", 1).node, scalar("pivot", 0.5).node);
|
|
315
|
+
return { node: node2, size: in_.size };
|
|
316
|
+
}
|
|
317
|
+
// ---- geometry & time
|
|
318
|
+
case "texcoord":
|
|
319
|
+
return { node: TSL.uv(intInput(node, "index")), size: 2 };
|
|
320
|
+
case "geompropvalue": {
|
|
321
|
+
const geomprop = node.GetAttribute("inputs:geomprop").Get();
|
|
322
|
+
const match = typeof geomprop === "string" ? /^st(\d*)$/.exec(geomprop) : null;
|
|
323
|
+
if (!match) {
|
|
324
|
+
throw new UnsupportedMtlxNodeError(`geomprop "${String(geomprop)}" has no TSL mapping`);
|
|
325
|
+
}
|
|
326
|
+
return { node: TSL.uv(match[1] ? Number(match[1]) : 0), size: 2 };
|
|
327
|
+
}
|
|
328
|
+
case "position":
|
|
329
|
+
return {
|
|
330
|
+
node: node.GetAttribute("inputs:space").Get() === "world" ? TSL.positionWorld : TSL.positionLocal,
|
|
331
|
+
size: 3
|
|
332
|
+
};
|
|
333
|
+
case "normal":
|
|
334
|
+
return {
|
|
335
|
+
node: node.GetAttribute("inputs:space").Get() === "world" ? TSL.normalWorld : TSL.normalLocal,
|
|
336
|
+
size: 3
|
|
337
|
+
};
|
|
338
|
+
case "time":
|
|
339
|
+
return { node: TSL.time, size: 1 };
|
|
340
|
+
// ---- plumbing
|
|
341
|
+
case "constant":
|
|
342
|
+
return req("value");
|
|
343
|
+
case "dot":
|
|
344
|
+
return req("in");
|
|
345
|
+
case "combine2":
|
|
346
|
+
return { node: TSL.vec2(req("in1").node, req("in2").node), size: 2 };
|
|
347
|
+
case "combine3": {
|
|
348
|
+
const node3 = TSL.vec3(req("in1").node, req("in2").node, req("in3").node);
|
|
349
|
+
return { node: node3, size: 3 };
|
|
350
|
+
}
|
|
351
|
+
case "combine4": {
|
|
352
|
+
const node4 = TSL.vec4(req("in1").node, req("in2").node, req("in3").node, req("in4").node);
|
|
353
|
+
return { node: node4, size: 4 };
|
|
354
|
+
}
|
|
355
|
+
case "extract":
|
|
356
|
+
return { node: component(req("in").node, intInput(node, "index")), size: 1 };
|
|
357
|
+
case "separate2":
|
|
358
|
+
case "separate3":
|
|
359
|
+
case "separate4":
|
|
360
|
+
return { node: component(req("in").node, OUTPUT_COMPONENT[output] ?? 0), size: 1 };
|
|
361
|
+
case "normalmap": {
|
|
362
|
+
const in_ = req("in");
|
|
363
|
+
const scale = opt("scale");
|
|
364
|
+
const scaleNode = scale ? scale.size === 1 ? TSL.vec2(scale.node, scale.node) : scale.node : void 0;
|
|
365
|
+
return {
|
|
366
|
+
node: scaleNode ? TSL.normalMap(in_.node, scaleNode) : TSL.normalMap(in_.node),
|
|
367
|
+
size: 3
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
if (op.startsWith("convert")) {
|
|
372
|
+
return resize(req("in"), size);
|
|
373
|
+
}
|
|
374
|
+
throw new UnsupportedMtlxNodeError(`MaterialX node "${id}" has no TSL conversion`);
|
|
375
|
+
}
|
|
376
|
+
function maxSize(a, b) {
|
|
377
|
+
return a.size >= b.size ? a.size : b.size;
|
|
378
|
+
}
|
|
379
|
+
function intInput(node, name) {
|
|
380
|
+
const value = node.GetAttribute(`inputs:${name}`).Get();
|
|
381
|
+
return typeof value === "number" ? value : 0;
|
|
382
|
+
}
|
|
383
|
+
function resize(value, size) {
|
|
384
|
+
if (value.size === size) return value;
|
|
385
|
+
const n = value.node;
|
|
386
|
+
if (size === 1) return { node: value.size === 1 ? n : n.x, size: 1 };
|
|
387
|
+
if (value.size === 1) {
|
|
388
|
+
const node = size === 2 ? TSL.vec2(n, n) : size === 3 ? TSL.vec3(n, n, n) : TSL.vec4(n, n, n, n);
|
|
389
|
+
return { node, size };
|
|
390
|
+
}
|
|
391
|
+
if (size === 2) return { node: n.xy, size: 2 };
|
|
392
|
+
if (size === 3) return { node: value.size === 4 ? n.xyz : TSL.vec3(n.x, n.y, 0), size: 3 };
|
|
393
|
+
return { node: TSL.vec4(resize(value, 3).node, 1), size: 4 };
|
|
394
|
+
}
|
|
395
|
+
function texcoordOf(node, ctx, depth) {
|
|
396
|
+
return inputValue(node, "texcoord", ctx, depth)?.node ?? TSL.uv();
|
|
397
|
+
}
|
|
398
|
+
function imageValue(node, tiled, size, type, ctx, depth) {
|
|
399
|
+
const rt = readMtlxImage(node, tiled);
|
|
400
|
+
if (!rt) throw new UnsupportedMtlxNodeError(`image node ${node.GetPath()} authors no file`);
|
|
401
|
+
if (!ctx.textures) {
|
|
402
|
+
throw new UnsupportedMtlxNodeError(`no texture provider for "${rt.path}"`);
|
|
403
|
+
}
|
|
404
|
+
let channel = rt.uvChannel;
|
|
405
|
+
if (rt.uvSet !== void 0) {
|
|
406
|
+
const match = /^st(\d*)$/.exec(rt.uvSet);
|
|
407
|
+
if (!match) {
|
|
408
|
+
throw new UnsupportedMtlxNodeError(`UV set "${rt.uvSet}" needs mesh primvar resolution`);
|
|
409
|
+
}
|
|
410
|
+
channel = match[1] ? Number(match[1]) : 0;
|
|
411
|
+
}
|
|
412
|
+
const texture2 = ctx.textures(rt.path, {
|
|
413
|
+
colorSpace: type.startsWith("color") ? "srgb" : "linear",
|
|
414
|
+
...rt.wrapS ? { wrapS: rt.wrapS } : {},
|
|
415
|
+
...rt.wrapT ? { wrapT: rt.wrapT } : {},
|
|
416
|
+
...rt.transform ? { transform: rt.transform } : {},
|
|
417
|
+
...channel ? { channel } : {}
|
|
418
|
+
});
|
|
419
|
+
if (!texture2) throw new UnsupportedMtlxNodeError(`texture "${rt.path}" failed to load`);
|
|
420
|
+
let uvNode;
|
|
421
|
+
const connection = node.GetAttribute("inputs:texcoord").GetConnections()[0];
|
|
422
|
+
if (connection) {
|
|
423
|
+
const [path, output] = splitConnection(connection);
|
|
424
|
+
const source = ctx.stage.GetPrimAtPath(path);
|
|
425
|
+
const sourceId = source?.GetAttribute("info:id").Get();
|
|
426
|
+
if (source && typeof sourceId === "string" && !sourceId.startsWith("ND_texcoord_") && !sourceId.startsWith("ND_geompropvalue_")) {
|
|
427
|
+
uvNode = nodeValue(source, output, ctx, depth + 1).node;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
const sample = uvNode ? TSL.texture(texture2, uvNode) : TSL.texture(texture2);
|
|
431
|
+
if (size === 1) return { node: sample.r, size: 1 };
|
|
432
|
+
if (size === 2) return { node: sample.xy, size: 2 };
|
|
433
|
+
if (size === 4) return { node: sample.rgba, size: 4 };
|
|
434
|
+
return { node: sample.rgb, size: 3 };
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
export { buildStandardSurfaceNodeMaterial, createMaterialXNodeFactory, loadMaterialXDocument };
|
|
438
|
+
//# sourceMappingURL=nodes.js.map
|
|
439
|
+
//# sourceMappingURL=nodes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/nodes/loadMaterialXDocument.ts","../src/nodes/materialXNodeFactory.ts"],"names":["dot","node","texture"],"mappings":"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","file":"nodes.js","sourcesContent":["import type { LoadingManager } from \"three\";\nimport type { MeshPhysicalNodeMaterial } from \"three/webgpu\";\n\n/**\n * Load an external `.mtlx` document with three's official `MaterialXLoader`\n * (`three/addons`) — the delegation path for UsdMtlx-style file references,\n * which this library does not parse (M22). Returns the document's surface\n * materials by name, ready to assign to meshes (WebGPURenderer required).\n * The loader is imported on demand so bundles only pay for it when used.\n */\nexport async function loadMaterialXDocument(\n url: string,\n manager?: LoadingManager,\n): Promise<Record<string, MeshPhysicalNodeMaterial>> {\n const { MaterialXLoader } = await import(\"three/addons/loaders/MaterialXLoader.js\");\n const { materials } = await new MaterialXLoader(manager).loadAsync(url);\n return materials;\n}\n","/**\n * MaterialX → TSL conversion (M22): executes natively-authored UsdShade\n * `ND_*` shader graphs — the procedural nodes the M21 parameter mapping can\n * only warn about — by building a three.js `MeshPhysicalNodeMaterial`\n * (WebGPURenderer). Plugs into the core through the `materialFactory` hook;\n * any node outside the conversion table makes the factory return `null` with\n * a warning, so the material falls back to the M21 parameter mapping. MDL\n * remains out of scope (a language, not a graph — executing it needs an MDL\n * SDK-class compiler).\n */\n\nimport * as TSL from \"three/tsl\";\nimport type { ShaderNodeObject } from \"three/tsl\";\nimport { MeshPhysicalNodeMaterial, type Node } from \"three/webgpu\";\nimport { findBoundSurfaceShader } from \"../three/MaterialBinding.js\";\nimport { MTLX_STANDARD_SURFACE, readMtlxImage } from \"../three/MaterialXBinding.js\";\nimport type { MaterialFactory } from \"../three/MeshBinding.js\";\nimport type { TextureProvider } from \"../three/TextureBinding.js\";\nimport type { Prim } from \"../usd/Prim.js\";\nimport type { Stage } from \"../usd/Stage.js\";\n\nexport type MaterialXNodeFactoryOptions = {\n /** Resolves image-node asset paths to `THREE.Texture` (reuse the core provider). */\n textureProvider?: TextureProvider;\n /** Receives diagnostics: graphs that fall back to the M21 parameter mapping. */\n onWarn?: (message: string) => void;\n};\n\n/**\n * A {@link MaterialFactory} that converts `ND_standard_surface_surfaceshader`\n * networks to TSL node materials. Returns `null` (⇒ the default `UsdShade`\n * resolution) for every other material, and — with a warning — for graphs\n * containing nodes outside the conversion table.\n */\nexport function createMaterialXNodeFactory(\n options: MaterialXNodeFactoryOptions = {},\n): MaterialFactory {\n return (prim, stage) => {\n const shader = findBoundSurfaceShader(stage, prim);\n if (!shader || shader.GetAttribute(\"info:id\").Get() !== MTLX_STANDARD_SURFACE) return null;\n try {\n return buildStandardSurfaceNodeMaterial(shader, options.textureProvider);\n } catch (error) {\n if (error instanceof UnsupportedMtlxNodeError) {\n options.onWarn?.(\n `${prim.GetPath()}: ${error.message}; falling back to the parameter mapping`,\n );\n return null;\n }\n throw error;\n }\n };\n}\n\n/** A TSL node plus its component count (drives broadcasts and conversions). */\ntype TslNode = ShaderNodeObject<Node>;\ntype Size = 1 | 2 | 3 | 4;\ntype TslValue = { node: TslNode; size: Size };\n\n/** Walking hit a node/input the conversion table cannot express. */\nclass UnsupportedMtlxNodeError extends Error {}\n\ntype BuildContext = {\n stage: Stage;\n textures: TextureProvider | undefined;\n /** Converted node outputs by `path.output` — preserves shared subgraphs. */\n cache: Map<string, TslValue>;\n};\n\n/**\n * Convert one `ND_standard_surface_surfaceshader` prim into a\n * `MeshPhysicalNodeMaterial`. Only authored inputs are mapped (unauthored ⇒\n * three.js defaults, matching the M21 rule); throws\n * `UnsupportedMtlxNodeError` when the graph leaves the conversion table.\n */\nexport function buildStandardSurfaceNodeMaterial(\n shader: Prim,\n textureProvider?: TextureProvider,\n): MeshPhysicalNodeMaterial {\n const ctx: BuildContext = {\n stage: shader.GetStage(),\n textures: textureProvider,\n cache: new Map(),\n };\n const input = (name: string) => inputValue(shader, name, ctx, 0);\n const material = new MeshPhysicalNodeMaterial();\n\n // `base × base_color` → color (nodedef default base_color is 0.8 gray).\n const base = input(\"base\");\n const baseColor = input(\"base_color\");\n if (baseColor) {\n material.colorNode = base ? TSL.mul(base.node, baseColor.node) : baseColor.node;\n } else if (base) {\n material.colorNode = TSL.mul(base.node, TSL.color(0.8, 0.8, 0.8));\n }\n\n const metalness = input(\"metalness\");\n if (metalness) material.metalnessNode = toFloat(metalness);\n const roughness = input(\"specular_roughness\");\n if (roughness) material.roughnessNode = toFloat(roughness);\n const ior = input(\"specular_IOR\");\n if (ior) material.iorNode = toFloat(ior);\n const transmission = input(\"transmission\");\n if (transmission) material.transmissionNode = toFloat(transmission);\n const coat = input(\"coat\");\n if (coat) material.clearcoatNode = toFloat(coat);\n const coatRoughness = input(\"coat_roughness\");\n if (coatRoughness) material.clearcoatRoughnessNode = toFloat(coatRoughness);\n\n const emission = input(\"emission\");\n if (emission) {\n const emissionColor = input(\"emission_color\");\n material.emissiveNode = emissionColor\n ? TSL.mul(emission.node, emissionColor.node)\n : emission.node;\n }\n\n const opacity = input(\"opacity\");\n if (opacity) {\n material.opacityNode = toFloat(opacity);\n material.transparent = true;\n }\n\n const normal = input(\"normal\");\n if (normal) material.normalNode = normal.node;\n\n return material;\n}\n\n/** Scalar view of a value — vectors average their components (color3 opacity). */\nfunction toFloat(value: TslValue): TslNode {\n const n = value.node;\n if (value.size === 1) return n;\n if (value.size === 2) return TSL.add(n.x, n.y).div(2);\n if (value.size === 3) return TSL.add(n.x, n.y, n.z).div(3);\n return TSL.add(n.x, n.y, n.z, n.w).div(4);\n}\n\n/** Resolve `inputs:<name>` — a connected node (recursively) or an authored constant. */\nfunction inputValue(prim: Prim, name: string, ctx: BuildContext, depth: number): TslValue | null {\n const attr = prim.GetAttribute(`inputs:${name}`);\n const connection = attr.GetConnections()[0];\n if (connection) {\n const [path, output] = splitConnection(connection);\n const source = ctx.stage.GetPrimAtPath(path);\n if (!source) throw new UnsupportedMtlxNodeError(`unresolvable connection \"${connection}\"`);\n return nodeValue(source, output, ctx, depth + 1);\n }\n const value = attr.Get();\n if (value === undefined) return null;\n return constantValue(value, attr.GetTypeName());\n}\n\nfunction splitConnection(connection: string): [string, string] {\n const dot = connection.indexOf(\".\");\n if (dot < 0) return [connection, \"out\"];\n return [connection.slice(0, dot), connection.slice(dot + 1).replace(/^outputs:/, \"\")];\n}\n\n/** An authored USD value as a TSL constant (`color3f` → `color`, else vectors). */\nfunction constantValue(value: unknown, typeName: string): TslValue {\n if (typeof value === \"number\") return { node: TSL.float(value), size: 1 };\n if (typeof value === \"boolean\") return { node: TSL.float(value ? 1 : 0), size: 1 };\n if (Array.isArray(value) && value.every((n) => typeof n === \"number\")) {\n const [x = 0, y = 0, z = 0, w = 0] = value as number[];\n if (value.length === 2) return { node: TSL.vec2(x, y), size: 2 };\n if (value.length === 3) {\n const isColor = typeName.toLowerCase().includes(\"color\");\n return { node: isColor ? TSL.color(x, y, z) : TSL.vec3(x, y, z), size: 3 };\n }\n if (value.length === 4) return { node: TSL.vec4(x, y, z, w), size: 4 };\n }\n throw new UnsupportedMtlxNodeError(`unsupported constant value type \"${typeName}\"`);\n}\n\n/** Component counts by MaterialX type suffix (incl. the `*FA` mixed variants). */\nconst TYPE_SIZE: Record<string, Size> = {\n float: 1,\n integer: 1,\n boolean: 1,\n vector2: 2,\n vector2FA: 2,\n color3: 3,\n color3FA: 3,\n vector3: 3,\n vector3FA: 3,\n color4: 4,\n color4FA: 4,\n vector4: 4,\n vector4FA: 4,\n};\n\n/** `ND_noise2d_color3` → op `noise2d`, size 3, type token `color3`. */\nfunction parseNodeId(id: string): { op: string; size: Size; type: string } {\n const body = id.startsWith(\"ND_\") ? id.slice(3) : id;\n const cut = body.lastIndexOf(\"_\");\n if (cut > 0) {\n const type = body.slice(cut + 1);\n const size = TYPE_SIZE[type];\n if (size) return { op: body.slice(0, cut), size, type };\n }\n return { op: body, size: 1, type: \"float\" };\n}\n\nconst UNARY: Record<string, (n: TslNode) => TslNode> = {\n absval: TSL.abs,\n floor: TSL.floor,\n ceil: TSL.ceil,\n sin: TSL.sin,\n cos: TSL.cos,\n tan: TSL.tan,\n exp: TSL.exp,\n ln: TSL.log,\n sqrt: TSL.sqrt,\n sign: TSL.sign,\n normalize: TSL.normalize,\n};\n\nconst BINARY: Record<string, { fn: (a: TslNode, b: TslNode) => TslNode; neutral: number }> = {\n add: { fn: TSL.add, neutral: 0 },\n subtract: { fn: TSL.sub, neutral: 0 },\n multiply: { fn: TSL.mul, neutral: 1 },\n divide: { fn: TSL.div, neutral: 1 },\n power: { fn: TSL.pow, neutral: 1 },\n modulo: { fn: TSL.mod, neutral: 1 },\n min: { fn: TSL.min, neutral: 0 },\n max: { fn: TSL.max, neutral: 0 },\n};\n\nconst COMPONENTS = [\"x\", \"y\", \"z\", \"w\"] as const;\n/** `outx`/`outr` → 0, `outy`/`outg` → 1, … (separate-node output names). */\nconst OUTPUT_COMPONENT: Record<string, number> = {\n outx: 0,\n outy: 1,\n outz: 2,\n outw: 3,\n outr: 0,\n outg: 1,\n outb: 2,\n outa: 3,\n};\n\nfunction component(node: TslNode, index: number): TslNode {\n return node[COMPONENTS[Math.max(0, Math.min(index, 3))] as \"x\"];\n}\n\n/** Recursion guard — real MaterialX graphs are shallow; cycles are authoring errors. */\nconst MAX_NODE_DEPTH = 16;\n\n/** Convert one MaterialX node prim's `output` into a TSL value (cached). */\nfunction nodeValue(node: Prim, output: string, ctx: BuildContext, depth: number): TslValue {\n const key = `${node.GetPath()}.${output}`;\n const cached = ctx.cache.get(key);\n if (cached) return cached;\n if (depth > MAX_NODE_DEPTH) {\n throw new UnsupportedMtlxNodeError(`graph too deep at ${node.GetPath()} (cycle?)`);\n }\n const value = convertNode(node, output, ctx, depth);\n ctx.cache.set(key, value);\n return value;\n}\n\nfunction convertNode(node: Prim, output: string, ctx: BuildContext, depth: number): TslValue {\n const id = node.GetAttribute(\"info:id\").Get();\n if (typeof id !== \"string\") {\n throw new UnsupportedMtlxNodeError(`${node.GetPath()} has no info:id`);\n }\n const { op, size, type } = parseNodeId(id);\n const opt = (name: string) => inputValue(node, name, ctx, depth);\n const req = (name: string) => {\n const value = opt(name);\n if (!value) throw new UnsupportedMtlxNodeError(`node \"${id}\" is missing input \"${name}\"`);\n return value;\n };\n const scalar = (name: string, fallback: number) =>\n opt(name) ?? { node: TSL.float(fallback), size: 1 as Size };\n\n // ---- images (procedural UV warps ride the texcoord connection)\n if (op === \"image\" || op === \"tiledimage\") {\n return imageValue(node, op === \"tiledimage\", size, type, ctx, depth);\n }\n\n // ---- math\n const unary = UNARY[op];\n if (unary) {\n const in_ = req(\"in\");\n return { node: unary(in_.node), size: in_.size };\n }\n const binary = BINARY[op];\n if (binary) {\n const in1 = req(\"in1\");\n const in2 = scalar(\"in2\", binary.neutral);\n return { node: binary.fn(in1.node, in2.node), size: maxSize(in1, in2) };\n }\n switch (op) {\n case \"invert\": {\n const in_ = req(\"in\");\n return { node: TSL.sub(scalar(\"amount\", 1).node, in_.node), size: in_.size };\n }\n case \"magnitude\":\n return { node: TSL.length(req(\"in\").node), size: 1 };\n case \"dotproduct\":\n return { node: TSL.dot(req(\"in1\").node, req(\"in2\").node), size: 1 };\n case \"crossproduct\":\n return { node: TSL.cross(req(\"in1\").node, req(\"in2\").node), size: 3 };\n case \"clamp\": {\n const in_ = req(\"in\");\n const node = TSL.clamp(in_.node, scalar(\"low\", 0).node, scalar(\"high\", 1).node);\n return { node, size: in_.size };\n }\n case \"mix\": {\n const bg = scalar(\"bg\", 0);\n const fg = scalar(\"fg\", 0);\n // MaterialX mix: out = fg×mix + bg×(1−mix) ⇒ TSL mix(bg, fg, t).\n return { node: TSL.mix(bg.node, fg.node, scalar(\"mix\", 0).node), size: maxSize(bg, fg) };\n }\n case \"smoothstep\": {\n const in_ = req(\"in\");\n const node = TSL.smoothstep(scalar(\"low\", 0).node, scalar(\"high\", 1).node, in_.node);\n return { node, size: in_.size };\n }\n case \"remap\": {\n const in_ = req(\"in\");\n const node = TSL.remap(\n in_.node,\n scalar(\"inlow\", 0).node,\n scalar(\"inhigh\", 1).node,\n scalar(\"outlow\", 0).node,\n scalar(\"outhigh\", 1).node,\n );\n return { node, size: in_.size };\n }\n case \"ifgreater\": {\n const in1 = req(\"in1\");\n const in2 = scalar(\"in2\", 0);\n const cond = TSL.greaterThan(scalar(\"value1\", 1).node, scalar(\"value2\", 0).node);\n return { node: TSL.select(cond, in1.node, in2.node), size: maxSize(in1, in2) };\n }\n\n // ---- ramps & splits\n case \"ramplr\":\n case \"ramptb\": {\n const l = scalar(op === \"ramplr\" ? \"valuel\" : \"valuet\", 0);\n const r = scalar(op === \"ramplr\" ? \"valuer\" : \"valueb\", 0);\n const fn = op === \"ramplr\" ? TSL.mx_ramplr : TSL.mx_ramptb;\n return { node: fn(l.node, r.node, texcoordOf(node, ctx, depth)), size: maxSize(l, r) };\n }\n case \"splitlr\":\n case \"splittb\": {\n const l = scalar(op === \"splitlr\" ? \"valuel\" : \"valuet\", 0);\n const r = scalar(op === \"splitlr\" ? \"valuer\" : \"valueb\", 0);\n const fn = op === \"splitlr\" ? TSL.mx_splitlr : TSL.mx_splittb;\n const split = fn(l.node, r.node, scalar(\"center\", 0.5).node, texcoordOf(node, ctx, depth));\n return { node: split, size: maxSize(l, r) };\n }\n\n // ---- noise\n case \"noise2d\":\n case \"noise3d\": {\n const coord =\n opt(\"texcoord\")?.node ??\n opt(\"position\")?.node ??\n (op === \"noise2d\" ? TSL.uv() : TSL.positionLocal);\n const amplitude = scalar(\"amplitude\", 1).node;\n const pivot = scalar(\"pivot\", 0).node;\n if (size === 1) return { node: TSL.mx_noise_float(coord, amplitude, pivot), size: 1 };\n if (size === 4) return { node: TSL.mx_noise_vec4(coord, amplitude, pivot), size: 4 };\n const vec3Noise = TSL.mx_noise_vec3(coord, amplitude, pivot);\n return size === 2 ? { node: vec3Noise.xy, size: 2 } : { node: vec3Noise, size: 3 };\n }\n case \"fractal3d\": {\n const position = opt(\"position\")?.node ?? TSL.positionLocal;\n const octaves = scalar(\"octaves\", 3).node;\n const lacunarity = scalar(\"lacunarity\", 2).node;\n const diminish = scalar(\"diminish\", 0.5).node;\n const amplitude = scalar(\"amplitude\", 1).node;\n const fn =\n size === 1\n ? TSL.mx_fractal_noise_float\n : size === 2\n ? TSL.mx_fractal_noise_vec2\n : size === 4\n ? TSL.mx_fractal_noise_vec4\n : TSL.mx_fractal_noise_vec3;\n return { node: fn(position, octaves, lacunarity, diminish, amplitude), size };\n }\n case \"cellnoise2d\":\n case \"cellnoise3d\":\n return { node: TSL.mx_cell_noise_float(texcoordOf(node, ctx, depth)), size: 1 };\n case \"worleynoise2d\":\n case \"worleynoise3d\": {\n const coord = texcoordOf(node, ctx, depth);\n const jitter = scalar(\"jitter\", 1).node;\n const fn =\n size === 2\n ? TSL.mx_worley_noise_vec2\n : size === 3\n ? TSL.mx_worley_noise_vec3\n : TSL.mx_worley_noise_float;\n return { node: fn(coord, jitter), size: size === 2 || size === 3 ? size : 1 };\n }\n\n // ---- color\n case \"hsvtorgb\":\n return { node: TSL.mx_hsvtorgb(req(\"in\").node), size: 3 };\n case \"rgbtohsv\":\n return { node: TSL.mx_rgbtohsv(req(\"in\").node), size: 3 };\n case \"luminance\":\n return { node: TSL.luminance(req(\"in\").node), size: 1 };\n case \"saturate\": {\n const in_ = req(\"in\");\n return { node: TSL.saturation(in_.node, scalar(\"amount\", 1).node), size: in_.size };\n }\n case \"contrast\": {\n const in_ = req(\"in\");\n const node = TSL.mx_contrast(in_.node, scalar(\"amount\", 1).node, scalar(\"pivot\", 0.5).node);\n return { node, size: in_.size };\n }\n\n // ---- geometry & time\n case \"texcoord\":\n return { node: TSL.uv(intInput(node, \"index\")), size: 2 };\n case \"geompropvalue\": {\n const geomprop = node.GetAttribute(\"inputs:geomprop\").Get();\n const match = typeof geomprop === \"string\" ? /^st(\\d*)$/.exec(geomprop) : null;\n if (!match) {\n throw new UnsupportedMtlxNodeError(`geomprop \"${String(geomprop)}\" has no TSL mapping`);\n }\n return { node: TSL.uv(match[1] ? Number(match[1]) : 0), size: 2 };\n }\n case \"position\":\n return {\n node:\n node.GetAttribute(\"inputs:space\").Get() === \"world\"\n ? TSL.positionWorld\n : TSL.positionLocal,\n size: 3,\n };\n case \"normal\":\n return {\n node:\n node.GetAttribute(\"inputs:space\").Get() === \"world\" ? TSL.normalWorld : TSL.normalLocal,\n size: 3,\n };\n case \"time\":\n return { node: TSL.time, size: 1 };\n\n // ---- plumbing\n case \"constant\":\n return req(\"value\");\n case \"dot\":\n return req(\"in\");\n case \"combine2\":\n return { node: TSL.vec2(req(\"in1\").node, req(\"in2\").node), size: 2 };\n case \"combine3\": {\n const node3 = TSL.vec3(req(\"in1\").node, req(\"in2\").node, req(\"in3\").node);\n return { node: node3, size: 3 };\n }\n case \"combine4\": {\n const node4 = TSL.vec4(req(\"in1\").node, req(\"in2\").node, req(\"in3\").node, req(\"in4\").node);\n return { node: node4, size: 4 };\n }\n case \"extract\":\n return { node: component(req(\"in\").node, intInput(node, \"index\")), size: 1 };\n case \"separate2\":\n case \"separate3\":\n case \"separate4\":\n return { node: component(req(\"in\").node, OUTPUT_COMPONENT[output] ?? 0), size: 1 };\n case \"normalmap\": {\n const in_ = req(\"in\");\n const scale = opt(\"scale\");\n const scaleNode = scale\n ? scale.size === 1\n ? TSL.vec2(scale.node, scale.node)\n : scale.node\n : undefined;\n return {\n node: scaleNode ? TSL.normalMap(in_.node, scaleNode) : TSL.normalMap(in_.node),\n size: 3,\n };\n }\n default:\n break;\n }\n if (op.startsWith(\"convert\")) {\n return resize(req(\"in\"), size);\n }\n throw new UnsupportedMtlxNodeError(`MaterialX node \"${id}\" has no TSL conversion`);\n}\n\nfunction maxSize(a: TslValue, b: TslValue): Size {\n return (a.size >= b.size ? a.size : b.size) as Size;\n}\n\nfunction intInput(node: Prim, name: string): number {\n const value = node.GetAttribute(`inputs:${name}`).Get();\n return typeof value === \"number\" ? value : 0;\n}\n\n/** Change a value's component count (broadcast scalars, pad with 0 / alpha 1). */\nfunction resize(value: TslValue, size: Size): TslValue {\n if (value.size === size) return value;\n const n = value.node;\n if (size === 1) return { node: value.size === 1 ? n : n.x, size: 1 };\n if (value.size === 1) {\n const node =\n size === 2 ? TSL.vec2(n, n) : size === 3 ? TSL.vec3(n, n, n) : TSL.vec4(n, n, n, n);\n return { node, size };\n }\n if (size === 2) return { node: n.xy, size: 2 };\n if (size === 3) return { node: value.size === 4 ? n.xyz : TSL.vec3(n.x, n.y, 0), size: 3 };\n return { node: TSL.vec4(resize(value, 3).node, 1), size: 4 };\n}\n\n/** An image node's `texcoord` input as a TSL coord (default `uv()`). */\nfunction texcoordOf(node: Prim, ctx: BuildContext, depth: number): TslNode {\n return inputValue(node, \"texcoord\", ctx, depth)?.node ?? TSL.uv();\n}\n\n/**\n * `ND_image_*` / `ND_tiledimage_*` → a TSL texture sample. Static sampler\n * state (wrap, uvtiling, texcoord index) reuses the M21 reader and the core\n * texture provider; a *computed* `texcoord` connection becomes the sample's\n * uv node — the procedural-warp case the parameter mapping cannot express.\n */\nfunction imageValue(\n node: Prim,\n tiled: boolean,\n size: Size,\n type: string,\n ctx: BuildContext,\n depth: number,\n): TslValue {\n const rt = readMtlxImage(node, tiled);\n if (!rt) throw new UnsupportedMtlxNodeError(`image node ${node.GetPath()} authors no file`);\n if (!ctx.textures) {\n throw new UnsupportedMtlxNodeError(`no texture provider for \"${rt.path}\"`);\n }\n let channel = rt.uvChannel;\n if (rt.uvSet !== undefined) {\n // Without the mesh at hand, primvar names resolve like the geompropvalue\n // node: `st`/`stN` → channel N; anything else needs the parameter mapping.\n const match = /^st(\\d*)$/.exec(rt.uvSet);\n if (!match) {\n throw new UnsupportedMtlxNodeError(`UV set \"${rt.uvSet}\" needs mesh primvar resolution`);\n }\n channel = match[1] ? Number(match[1]) : 0;\n }\n const texture = ctx.textures(rt.path, {\n colorSpace: type.startsWith(\"color\") ? \"srgb\" : \"linear\",\n ...(rt.wrapS ? { wrapS: rt.wrapS } : {}),\n ...(rt.wrapT ? { wrapT: rt.wrapT } : {}),\n ...(rt.transform ? { transform: rt.transform } : {}),\n ...(channel ? { channel } : {}),\n });\n if (!texture) throw new UnsupportedMtlxNodeError(`texture \"${rt.path}\" failed to load`);\n\n // A texcoord connection to anything but the static UV readers is a\n // computed coordinate — feed it to the sampler as the uv node.\n let uvNode: TslNode | undefined;\n const connection = node.GetAttribute(\"inputs:texcoord\").GetConnections()[0];\n if (connection) {\n const [path, output] = splitConnection(connection);\n const source = ctx.stage.GetPrimAtPath(path);\n const sourceId = source?.GetAttribute(\"info:id\").Get();\n if (\n source &&\n typeof sourceId === \"string\" &&\n !sourceId.startsWith(\"ND_texcoord_\") &&\n !sourceId.startsWith(\"ND_geompropvalue_\")\n ) {\n uvNode = nodeValue(source, output, ctx, depth + 1).node;\n }\n }\n const sample = uvNode ? TSL.texture(texture, uvNode) : TSL.texture(texture);\n if (size === 1) return { node: sample.r, size: 1 };\n if (size === 2) return { node: sample.xy, size: 2 };\n if (size === 4) return { node: sample.rgba, size: 4 };\n return { node: sample.rgb, size: 3 };\n}\n"]}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves USD asset paths (from references / payloads / sublayers) to URLs and
|
|
3
|
+
* fetches their text. Composition (`composition.ts`) is I/O-agnostic and goes
|
|
4
|
+
* through an {@link AssetResolver}, so the same engine works in the browser, in
|
|
5
|
+
* Node, or against an in-memory file map in tests.
|
|
6
|
+
*/
|
|
7
|
+
interface AssetResolver {
|
|
8
|
+
/** Resolve an authored asset path against the layer's base URL to an absolute key. */
|
|
9
|
+
resolve(assetPath: string, baseUrl: string): string;
|
|
10
|
+
/** Fetch the text of a resolved asset; rejects if it cannot be read. */
|
|
11
|
+
fetchText(url: string): Promise<string>;
|
|
12
|
+
/** Fetch the raw bytes of a resolved asset (for binary USDC / USDZ). Optional. */
|
|
13
|
+
fetchBytes?(url: string): Promise<Uint8Array>;
|
|
14
|
+
}
|
|
15
|
+
/** URL-based resolver using the global `fetch` (browser / Node 18+). */
|
|
16
|
+
declare class DefaultAssetResolver implements AssetResolver {
|
|
17
|
+
resolve(assetPath: string, baseUrl: string): string;
|
|
18
|
+
fetchText(url: string): Promise<string>;
|
|
19
|
+
fetchBytes(url: string): Promise<Uint8Array>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Resolver over an in-memory `{ path: contents }` map (text or bytes), with
|
|
23
|
+
* posix-style joins. Useful for tests and bundled assets.
|
|
24
|
+
*/
|
|
25
|
+
declare function createMemoryResolver(files: Record<string, string | Uint8Array>): AssetResolver;
|
|
26
|
+
/** Resolve `rel` against `baseUrl` using posix semantics, normalizing `.`/`..`. */
|
|
27
|
+
declare function joinPosix(baseUrl: string, rel: string): string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Minimal `.mdl` **declaration** parser (M20) — reads material signatures, not
|
|
31
|
+
* the MDL language.
|
|
32
|
+
*
|
|
33
|
+
* USD stores only the *overridden* inputs of an MDL shader; every other
|
|
34
|
+
* parameter value lives in the referenced `.mdl` module. Two declaration
|
|
35
|
+
* shapes carry the values we can recover without executing MDL:
|
|
36
|
+
*
|
|
37
|
+
* - parameter defaults —
|
|
38
|
+
* `export material OmniPBR(color diffuse_color_constant = color(0.2), …)`
|
|
39
|
+
* - wrapper materials (the usual shape of per-asset `Materials/*.mdl`) —
|
|
40
|
+
* `export material Steel(*) = OmniPBR::OmniPBR(diffuse_color_constant: color(…), …);`
|
|
41
|
+
*
|
|
42
|
+
* Only literal values are extracted: numbers, bools, strings, `color(…)` /
|
|
43
|
+
* `floatN(…)` vectors, and `texture_2d("path", ::tex::gamma_*)`. Defaults that
|
|
44
|
+
* are expressions, function calls, or cross-module references are skipped, as
|
|
45
|
+
* are comments and `[[ … ]]` annotation blocks. Executing MDL stays out of
|
|
46
|
+
* scope — this is a fidelity aid, not an interpreter.
|
|
47
|
+
*/
|
|
48
|
+
/** A literal value read from an MDL declaration. */
|
|
49
|
+
type MdlValue = number | boolean | string | number[] | MdlTextureValue;
|
|
50
|
+
/** A `texture_2d("path", ::tex::gamma_*)` literal. */
|
|
51
|
+
interface MdlTextureValue {
|
|
52
|
+
/** Path as written in the module — relative paths anchor at the `.mdl` file. */
|
|
53
|
+
assetPath: string;
|
|
54
|
+
/** From the gamma argument: `gamma_srgb` → `"sRGB"`, `gamma_linear` → `"raw"`. */
|
|
55
|
+
sourceColorSpace?: "sRGB" | "raw";
|
|
56
|
+
}
|
|
57
|
+
/** Narrow an {@link MdlValue} to a texture literal. */
|
|
58
|
+
declare function isMdlTexture(value: MdlValue | undefined): value is MdlTextureValue;
|
|
59
|
+
/** One `export material` declaration. */
|
|
60
|
+
interface MdlMaterialDecl {
|
|
61
|
+
name: string;
|
|
62
|
+
/** Literal defaults from the declaration's own parameter list (empty for `(*)`). */
|
|
63
|
+
defaults: Map<string, MdlValue>;
|
|
64
|
+
/** Base material of the wrapper form `X(…) = Base(args…)` (last `::` segment). */
|
|
65
|
+
base?: string;
|
|
66
|
+
/** Literal named arguments of the wrapper's base call. */
|
|
67
|
+
args: Map<string, MdlValue>;
|
|
68
|
+
}
|
|
69
|
+
/** The exported material declarations of one `.mdl` file. */
|
|
70
|
+
interface MdlModule {
|
|
71
|
+
materials: Map<string, MdlMaterialDecl>;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Look up the parsed module for an authored `info:mdl:sourceAsset` path.
|
|
75
|
+
* Returning `undefined` means "module unavailable" — resolution then falls
|
|
76
|
+
* back to authored USD inputs alone.
|
|
77
|
+
*/
|
|
78
|
+
type MdlModuleProvider = (assetPath: string) => MdlModule | undefined;
|
|
79
|
+
/** Parse the `export material` declarations of an `.mdl` module's source text. */
|
|
80
|
+
declare function parseMdl(text: string): MdlModule;
|
|
81
|
+
/**
|
|
82
|
+
* Evaluate one MDL literal expression, or `undefined` for anything beyond the
|
|
83
|
+
* supported literal subset (identifiers, arithmetic, function calls, …).
|
|
84
|
+
*/
|
|
85
|
+
declare function parseMdlLiteral(src: string): MdlValue | undefined;
|
|
86
|
+
|
|
87
|
+
export { type AssetResolver as A, DefaultAssetResolver as D, type MdlMaterialDecl as M, type MdlModule as a, type MdlModuleProvider as b, type MdlTextureValue as c, type MdlValue as d, createMemoryResolver as e, parseMdlLiteral as f, isMdlTexture as i, joinPosix as j, parseMdl as p };
|
package/dist/react.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import * as _react_three_fiber from '@react-three/fiber';
|
|
2
2
|
import { ThreeElements } from '@react-three/fiber';
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { T as ThreeUsdRobot } from './ThreeUsdRobot-
|
|
5
|
-
import { T as ThreeUsdRobotLoaderOptions } from './ThreeUsdRobotLoader-
|
|
4
|
+
import { T as ThreeUsdRobot } from './ThreeUsdRobot-X1zbpRZo.js';
|
|
5
|
+
import { T as ThreeUsdRobotLoaderOptions } from './ThreeUsdRobotLoader-u3d1yoLM.js';
|
|
6
6
|
import 'three';
|
|
7
|
-
import './buildKinematicTree-
|
|
8
|
-
import './
|
|
7
|
+
import './buildKinematicTree-Q9JOjAjM.js';
|
|
8
|
+
import './parseMdl-vfzBGoMr.js';
|
|
9
|
+
import './bytes-CxGRGry_.js';
|
|
10
|
+
import './MeshBinding-B_8RhuQE.js';
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* Load a robot for use under `<Suspense>`. Throws the load promise until ready
|