three-usd-robot 0.9.0 → 0.11.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 +76 -7
- package/dist/ThreeUsdRobot-BxnCluuK.d.ts +347 -0
- package/dist/{ThreeUsdRobotLoader-DYtvelif.d.ts → ThreeUsdRobotLoader-C-E9uwEe.d.ts} +15 -2
- package/dist/{buildKinematicTree-DQ4Vr4sJ.d.ts → buildKinematicTree-BCySuZZn.d.ts} +4 -0
- package/dist/chunk-5SVRTKS4.js +966 -0
- package/dist/chunk-5SVRTKS4.js.map +1 -0
- package/dist/{chunk-2UD32EGU.js → chunk-AXPMXEQC.js} +1005 -175
- package/dist/chunk-AXPMXEQC.js.map +1 -0
- package/dist/{chunk-TE4MPP5Q.js → chunk-BCRRXGNB.js} +4 -4
- package/dist/{chunk-TE4MPP5Q.js.map → chunk-BCRRXGNB.js.map} +1 -1
- package/dist/chunk-ENWFOYHU.js +701 -0
- package/dist/chunk-ENWFOYHU.js.map +1 -0
- package/dist/{chunk-IYKPVUZ2.js → chunk-LDO5FKQS.js} +39 -3
- package/dist/chunk-LDO5FKQS.js.map +1 -0
- package/dist/core.d.ts +173 -5
- package/dist/core.js +3 -3
- package/dist/extras.d.ts +2 -2
- package/dist/helpers.d.ts +2 -2
- package/dist/helpers.js +2 -2
- package/dist/index.d.ts +101 -17
- package/dist/index.js +8 -8
- package/dist/react.d.ts +3 -3
- package/dist/react.js +4 -4
- package/package.json +1 -1
- package/dist/ThreeUsdRobot-BAh-48DD.d.ts +0 -185
- package/dist/chunk-2UD32EGU.js.map +0 -1
- package/dist/chunk-IYKPVUZ2.js.map +0 -1
- package/dist/chunk-WROYLUSS.js +0 -393
- package/dist/chunk-WROYLUSS.js.map +0 -1
- package/dist/chunk-XEXFGL7R.js +0 -529
- package/dist/chunk-XEXFGL7R.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Quat, multiply, makeTranslation, makeRotationFromQuat, identity4, invert, makeEuler, DEG2RAD, makeRotationZ, makeRotationY, makeRotationX, fromUsdMatrix, makeScale,
|
|
1
|
+
import { Quat, multiply, makeTranslation, makeRotationFromQuat, identity4, invert, makeEuler, DEG2RAD, makeRotationZ, makeRotationY, makeRotationX, fromUsdMatrix, makeScale, RAD2DEG, AssetPath, UsdMatrix } from './chunk-LDO5FKQS.js';
|
|
2
2
|
import { unzipSync } from 'fflate';
|
|
3
3
|
|
|
4
4
|
// src/schemas/usdGeom.ts
|
|
@@ -21,8 +21,22 @@ var SOLID_GPRIM_TYPES = /* @__PURE__ */ new Set([
|
|
|
21
21
|
function isSolidGprim(prim) {
|
|
22
22
|
return SOLID_GPRIM_TYPES.has(prim.GetTypeName());
|
|
23
23
|
}
|
|
24
|
+
function isPoints(prim) {
|
|
25
|
+
return prim.GetTypeName() === "Points";
|
|
26
|
+
}
|
|
27
|
+
function isBasisCurves(prim) {
|
|
28
|
+
return prim.GetTypeName() === "BasisCurves";
|
|
29
|
+
}
|
|
30
|
+
var UNSUPPORTED_GPRIM_TYPES = /* @__PURE__ */ new Set([
|
|
31
|
+
"NurbsCurves",
|
|
32
|
+
"HermiteCurves",
|
|
33
|
+
"NurbsPatch"
|
|
34
|
+
]);
|
|
35
|
+
function isUnsupportedGprim(prim) {
|
|
36
|
+
return UNSUPPORTED_GPRIM_TYPES.has(prim.GetTypeName());
|
|
37
|
+
}
|
|
24
38
|
function isRenderableGprim(prim) {
|
|
25
|
-
return isMesh(prim) || isSolidGprim(prim);
|
|
39
|
+
return isMesh(prim) || isSolidGprim(prim) || isPoints(prim) || isBasisCurves(prim);
|
|
26
40
|
}
|
|
27
41
|
function getPurpose(prim) {
|
|
28
42
|
const v = prim.GetAttribute("purpose").Get();
|
|
@@ -268,105 +282,634 @@ function asMatrix(v, where) {
|
|
|
268
282
|
throw new Error(`${where}: expected a matrix`);
|
|
269
283
|
}
|
|
270
284
|
|
|
285
|
+
// src/usd/AssetResolver.ts
|
|
286
|
+
var DefaultAssetResolver = class {
|
|
287
|
+
resolve(assetPath, baseUrl) {
|
|
288
|
+
try {
|
|
289
|
+
return new URL(assetPath, baseUrl || void 0).href;
|
|
290
|
+
} catch {
|
|
291
|
+
return joinPosix(baseUrl, assetPath);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
async fetchText(url) {
|
|
295
|
+
const res = await fetch(url);
|
|
296
|
+
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
|
|
297
|
+
return res.text();
|
|
298
|
+
}
|
|
299
|
+
async fetchBytes(url) {
|
|
300
|
+
const res = await fetch(url);
|
|
301
|
+
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
|
|
302
|
+
return new Uint8Array(await res.arrayBuffer());
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
function createMemoryResolver(files) {
|
|
306
|
+
const decoder = new TextDecoder();
|
|
307
|
+
const encoder = new TextEncoder();
|
|
308
|
+
return {
|
|
309
|
+
resolve(assetPath, baseUrl) {
|
|
310
|
+
return joinPosix(baseUrl, assetPath);
|
|
311
|
+
},
|
|
312
|
+
fetchText(url) {
|
|
313
|
+
const v = files[url];
|
|
314
|
+
if (v === void 0) return Promise.reject(new Error(`asset not found: ${url}`));
|
|
315
|
+
return Promise.resolve(typeof v === "string" ? v : decoder.decode(v));
|
|
316
|
+
},
|
|
317
|
+
fetchBytes(url) {
|
|
318
|
+
const v = files[url];
|
|
319
|
+
if (v === void 0) return Promise.reject(new Error(`asset not found: ${url}`));
|
|
320
|
+
return Promise.resolve(typeof v === "string" ? encoder.encode(v) : v);
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
function joinPosix(baseUrl, rel) {
|
|
325
|
+
if (rel.startsWith("/")) return normalizePosix(rel);
|
|
326
|
+
const dir = baseUrl.slice(0, baseUrl.lastIndexOf("/") + 1);
|
|
327
|
+
return normalizePosix(dir + rel);
|
|
328
|
+
}
|
|
329
|
+
function normalizePosix(path) {
|
|
330
|
+
const isAbsolute = path.startsWith("/");
|
|
331
|
+
const out = [];
|
|
332
|
+
for (const part of path.split("/")) {
|
|
333
|
+
if (part === "" || part === ".") continue;
|
|
334
|
+
if (part === "..") out.pop();
|
|
335
|
+
else out.push(part);
|
|
336
|
+
}
|
|
337
|
+
return (isAbsolute ? "/" : "") + out.join("/");
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// src/usd/mdl/parseMdl.ts
|
|
341
|
+
function isMdlTexture(value) {
|
|
342
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && "assetPath" in value;
|
|
343
|
+
}
|
|
344
|
+
function parseMdl(text) {
|
|
345
|
+
const src = stripNoise(text);
|
|
346
|
+
const materials = /* @__PURE__ */ new Map();
|
|
347
|
+
const declRe = /\bexport\s+material\s+([A-Za-z_]\w*)\s*\(/g;
|
|
348
|
+
let match = declRe.exec(src);
|
|
349
|
+
while (match) {
|
|
350
|
+
const open = match.index + match[0].length - 1;
|
|
351
|
+
const close = matchParen(src, open);
|
|
352
|
+
if (close === -1) break;
|
|
353
|
+
const decl = {
|
|
354
|
+
name: match[1],
|
|
355
|
+
defaults: parseParamDefaults(src.slice(open + 1, close - 1)),
|
|
356
|
+
args: /* @__PURE__ */ new Map()
|
|
357
|
+
};
|
|
358
|
+
let next = close;
|
|
359
|
+
let i = close;
|
|
360
|
+
while (i < src.length && /\s/.test(src[i])) i++;
|
|
361
|
+
if (src[i] === "=") {
|
|
362
|
+
const end = statementEnd(src, i + 1);
|
|
363
|
+
const body = parseWrapperBody(src.slice(i + 1, end));
|
|
364
|
+
if (body.base) decl.base = body.base;
|
|
365
|
+
decl.args = body.args;
|
|
366
|
+
next = end;
|
|
367
|
+
}
|
|
368
|
+
materials.set(decl.name, decl);
|
|
369
|
+
declRe.lastIndex = next;
|
|
370
|
+
match = declRe.exec(src);
|
|
371
|
+
}
|
|
372
|
+
return { materials };
|
|
373
|
+
}
|
|
374
|
+
var NUMBER_RE = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?[fFdD]?$/;
|
|
375
|
+
var CALL_RE = /^(?:::)?([A-Za-z_]\w*(?:::[A-Za-z_]\w*)*)\s*\(/;
|
|
376
|
+
var VECTOR_RE = /^(?:color|(?:float|double|int)([234]))$/;
|
|
377
|
+
var IDENTIFIER_RE = /^[A-Za-z_]\w*$/;
|
|
378
|
+
function parseMdlLiteral(src) {
|
|
379
|
+
const s = src.trim();
|
|
380
|
+
if (s === "true") return true;
|
|
381
|
+
if (s === "false") return false;
|
|
382
|
+
if (NUMBER_RE.test(s)) return Number.parseFloat(s.replace(/[fFdD]$/, ""));
|
|
383
|
+
if (s.startsWith('"')) {
|
|
384
|
+
if (skipString(s, 0) !== s.length) return void 0;
|
|
385
|
+
return s.slice(1, -1).replace(/\\(.)/g, "$1");
|
|
386
|
+
}
|
|
387
|
+
const call = CALL_RE.exec(s);
|
|
388
|
+
if (!call) return void 0;
|
|
389
|
+
const open = call[0].length - 1;
|
|
390
|
+
if (matchParen(s, open) !== s.length) return void 0;
|
|
391
|
+
const name = call[1].split("::").pop();
|
|
392
|
+
const args = splitTopLevel(s.slice(open + 1, s.length - 1), ",").map((a) => a.trim()).filter((a) => a.length > 0);
|
|
393
|
+
if (name === "texture_2d") {
|
|
394
|
+
const path = args[0] === void 0 ? void 0 : parseMdlLiteral(args[0]);
|
|
395
|
+
if (typeof path !== "string" || path.length === 0) return void 0;
|
|
396
|
+
const texture = { assetPath: path };
|
|
397
|
+
const gamma = args.slice(1).join(",");
|
|
398
|
+
if (gamma.includes("gamma_srgb")) texture.sourceColorSpace = "sRGB";
|
|
399
|
+
else if (gamma.includes("gamma_linear")) texture.sourceColorSpace = "raw";
|
|
400
|
+
return texture;
|
|
401
|
+
}
|
|
402
|
+
const vector = VECTOR_RE.exec(name);
|
|
403
|
+
if (vector) {
|
|
404
|
+
const width = vector[1] ? Number(vector[1]) : 3;
|
|
405
|
+
const values = args.map((a) => parseMdlLiteral(a));
|
|
406
|
+
if (values.length === 0 || !values.every((v) => typeof v === "number")) return void 0;
|
|
407
|
+
if (values.length === 1) return new Array(width).fill(values[0]);
|
|
408
|
+
return values.length === width ? values : void 0;
|
|
409
|
+
}
|
|
410
|
+
return void 0;
|
|
411
|
+
}
|
|
412
|
+
function parseParamDefaults(src) {
|
|
413
|
+
const defaults = /* @__PURE__ */ new Map();
|
|
414
|
+
const body = src.trim();
|
|
415
|
+
if (body === "" || body === "*") return defaults;
|
|
416
|
+
for (const param of splitTopLevel(src, ",")) {
|
|
417
|
+
const assign = topLevelAssign(param);
|
|
418
|
+
if (assign === -1) continue;
|
|
419
|
+
const name = param.slice(0, assign).trim().split(/\s+/).pop();
|
|
420
|
+
if (!name || !IDENTIFIER_RE.test(name)) continue;
|
|
421
|
+
const value = parseMdlLiteral(param.slice(assign + 1));
|
|
422
|
+
if (value !== void 0) defaults.set(name, value);
|
|
423
|
+
}
|
|
424
|
+
return defaults;
|
|
425
|
+
}
|
|
426
|
+
function parseWrapperBody(src) {
|
|
427
|
+
const args = /* @__PURE__ */ new Map();
|
|
428
|
+
const body = src.trim();
|
|
429
|
+
const call = CALL_RE.exec(body);
|
|
430
|
+
if (!call) return { args };
|
|
431
|
+
const open = call[0].length - 1;
|
|
432
|
+
if (matchParen(body, open) !== body.length) return { args };
|
|
433
|
+
const base = call[1].split("::").pop();
|
|
434
|
+
if (base === "material") return { args };
|
|
435
|
+
for (const arg of splitTopLevel(body.slice(open + 1, body.length - 1), ",")) {
|
|
436
|
+
const colon = topLevelColon(arg);
|
|
437
|
+
if (colon === -1) continue;
|
|
438
|
+
const name = arg.slice(0, colon).trim();
|
|
439
|
+
if (!IDENTIFIER_RE.test(name)) continue;
|
|
440
|
+
const value = parseMdlLiteral(arg.slice(colon + 1));
|
|
441
|
+
if (value !== void 0) args.set(name, value);
|
|
442
|
+
}
|
|
443
|
+
return { base, args };
|
|
444
|
+
}
|
|
445
|
+
function stripNoise(src) {
|
|
446
|
+
let out = "";
|
|
447
|
+
let i = 0;
|
|
448
|
+
while (i < src.length) {
|
|
449
|
+
const c = src[i];
|
|
450
|
+
if (c === '"') {
|
|
451
|
+
const end = skipString(src, i);
|
|
452
|
+
out += src.slice(i, end);
|
|
453
|
+
i = end;
|
|
454
|
+
} else if (c === "/" && src[i + 1] === "/") {
|
|
455
|
+
while (i < src.length && src[i] !== "\n") i++;
|
|
456
|
+
} else if (c === "/" && src[i + 1] === "*") {
|
|
457
|
+
const end = src.indexOf("*/", i + 2);
|
|
458
|
+
i = end === -1 ? src.length : end + 2;
|
|
459
|
+
out += " ";
|
|
460
|
+
} else if (c === "[" && src[i + 1] === "[") {
|
|
461
|
+
i = skipAnnotation(src, i);
|
|
462
|
+
out += " ";
|
|
463
|
+
} else {
|
|
464
|
+
out += c;
|
|
465
|
+
i++;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return out;
|
|
469
|
+
}
|
|
470
|
+
function skipString(src, i) {
|
|
471
|
+
let j = i + 1;
|
|
472
|
+
while (j < src.length) {
|
|
473
|
+
if (src[j] === "\\") j += 2;
|
|
474
|
+
else if (src[j] === '"') return j + 1;
|
|
475
|
+
else j++;
|
|
476
|
+
}
|
|
477
|
+
return j;
|
|
478
|
+
}
|
|
479
|
+
function skipAnnotation(src, i) {
|
|
480
|
+
let depth = 0;
|
|
481
|
+
let j = i;
|
|
482
|
+
while (j < src.length) {
|
|
483
|
+
if (src[j] === '"') {
|
|
484
|
+
j = skipString(src, j);
|
|
485
|
+
} else if (src[j] === "[" && src[j + 1] === "[") {
|
|
486
|
+
depth++;
|
|
487
|
+
j += 2;
|
|
488
|
+
} else if (src[j] === "]" && src[j + 1] === "]") {
|
|
489
|
+
depth--;
|
|
490
|
+
j += 2;
|
|
491
|
+
if (depth === 0) return j;
|
|
492
|
+
} else {
|
|
493
|
+
j++;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
return j;
|
|
497
|
+
}
|
|
498
|
+
function matchParen(src, open) {
|
|
499
|
+
let depth = 0;
|
|
500
|
+
let i = open;
|
|
501
|
+
while (i < src.length) {
|
|
502
|
+
const c = src[i];
|
|
503
|
+
if (c === '"') {
|
|
504
|
+
i = skipString(src, i);
|
|
505
|
+
continue;
|
|
506
|
+
}
|
|
507
|
+
if (c === "(") depth++;
|
|
508
|
+
else if (c === ")") {
|
|
509
|
+
depth--;
|
|
510
|
+
if (depth === 0) return i + 1;
|
|
511
|
+
}
|
|
512
|
+
i++;
|
|
513
|
+
}
|
|
514
|
+
return -1;
|
|
515
|
+
}
|
|
516
|
+
function isOpener(c) {
|
|
517
|
+
return c === "(" || c === "[" || c === "{";
|
|
518
|
+
}
|
|
519
|
+
function isCloser(c) {
|
|
520
|
+
return c === ")" || c === "]" || c === "}";
|
|
521
|
+
}
|
|
522
|
+
function splitTopLevel(src, separator) {
|
|
523
|
+
const parts = [];
|
|
524
|
+
let depth = 0;
|
|
525
|
+
let start = 0;
|
|
526
|
+
let i = 0;
|
|
527
|
+
while (i < src.length) {
|
|
528
|
+
const c = src[i];
|
|
529
|
+
if (c === '"') {
|
|
530
|
+
i = skipString(src, i);
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
if (isOpener(c)) depth++;
|
|
534
|
+
else if (isCloser(c)) depth--;
|
|
535
|
+
else if (c === separator && depth === 0) {
|
|
536
|
+
parts.push(src.slice(start, i));
|
|
537
|
+
start = i + 1;
|
|
538
|
+
}
|
|
539
|
+
i++;
|
|
540
|
+
}
|
|
541
|
+
parts.push(src.slice(start));
|
|
542
|
+
return parts;
|
|
543
|
+
}
|
|
544
|
+
function statementEnd(src, from) {
|
|
545
|
+
let depth = 0;
|
|
546
|
+
let i = from;
|
|
547
|
+
while (i < src.length) {
|
|
548
|
+
const c = src[i];
|
|
549
|
+
if (c === '"') {
|
|
550
|
+
i = skipString(src, i);
|
|
551
|
+
continue;
|
|
552
|
+
}
|
|
553
|
+
if (isOpener(c)) depth++;
|
|
554
|
+
else if (isCloser(c)) depth--;
|
|
555
|
+
else if (c === ";" && depth === 0) return i;
|
|
556
|
+
i++;
|
|
557
|
+
}
|
|
558
|
+
return src.length;
|
|
559
|
+
}
|
|
560
|
+
function topLevelAssign(src) {
|
|
561
|
+
let depth = 0;
|
|
562
|
+
let i = 0;
|
|
563
|
+
while (i < src.length) {
|
|
564
|
+
const c = src[i];
|
|
565
|
+
if (c === '"') {
|
|
566
|
+
i = skipString(src, i);
|
|
567
|
+
continue;
|
|
568
|
+
}
|
|
569
|
+
if (isOpener(c)) depth++;
|
|
570
|
+
else if (isCloser(c)) depth--;
|
|
571
|
+
else if (c === "=" && depth === 0 && src[i + 1] !== "=" && !"<>!=".includes(src[i - 1] ?? "")) {
|
|
572
|
+
return i;
|
|
573
|
+
}
|
|
574
|
+
i++;
|
|
575
|
+
}
|
|
576
|
+
return -1;
|
|
577
|
+
}
|
|
578
|
+
function topLevelColon(src) {
|
|
579
|
+
let depth = 0;
|
|
580
|
+
let i = 0;
|
|
581
|
+
while (i < src.length) {
|
|
582
|
+
const c = src[i];
|
|
583
|
+
if (c === '"') {
|
|
584
|
+
i = skipString(src, i);
|
|
585
|
+
continue;
|
|
586
|
+
}
|
|
587
|
+
if (isOpener(c)) depth++;
|
|
588
|
+
else if (isCloser(c)) depth--;
|
|
589
|
+
else if (c === ":" && depth === 0) {
|
|
590
|
+
if (src[i + 1] === ":") {
|
|
591
|
+
i += 2;
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
return i;
|
|
595
|
+
}
|
|
596
|
+
i++;
|
|
597
|
+
}
|
|
598
|
+
return -1;
|
|
599
|
+
}
|
|
600
|
+
|
|
271
601
|
// src/three/MaterialBinding.ts
|
|
272
602
|
var DIFFUSE_INPUTS = [
|
|
273
|
-
"
|
|
603
|
+
"diffuseColor",
|
|
274
604
|
// UsdPreviewSurface
|
|
275
|
-
"
|
|
605
|
+
"diffuse_color_constant",
|
|
276
606
|
// OmniPBR
|
|
277
|
-
"
|
|
278
|
-
"
|
|
279
|
-
"
|
|
607
|
+
"diffuse_tint",
|
|
608
|
+
"base_color",
|
|
609
|
+
"baseColor"
|
|
280
610
|
];
|
|
281
|
-
var OPACITY_INPUTS = ["
|
|
282
|
-
var OPACITY_THRESHOLD_INPUTS = ["
|
|
283
|
-
var METALLIC_INPUTS = ["
|
|
284
|
-
var ROUGHNESS_INPUTS = ["
|
|
285
|
-
var EMISSIVE_INPUTS = ["
|
|
611
|
+
var OPACITY_INPUTS = ["opacity", "opacity_constant"];
|
|
612
|
+
var OPACITY_THRESHOLD_INPUTS = ["opacityThreshold", "opacity_threshold"];
|
|
613
|
+
var METALLIC_INPUTS = ["metallic", "metallic_constant"];
|
|
614
|
+
var ROUGHNESS_INPUTS = ["roughness", "reflection_roughness_constant"];
|
|
615
|
+
var EMISSIVE_INPUTS = ["emissiveColor", "emissive_color"];
|
|
286
616
|
var SURFACE_OUTPUTS = ["outputs:surface", "outputs:mdl:surface"];
|
|
287
617
|
var TEXTURE_LOOKUPS = {
|
|
288
618
|
color: {
|
|
289
|
-
surface: ["
|
|
290
|
-
direct: ["
|
|
619
|
+
surface: ["diffuseColor"],
|
|
620
|
+
direct: ["diffuse_texture", "diffuse_color_texture", "glass_color_texture"]
|
|
291
621
|
},
|
|
292
622
|
opacity: {
|
|
293
|
-
surface: ["
|
|
294
|
-
direct: ["
|
|
623
|
+
surface: ["opacity"],
|
|
624
|
+
direct: ["opacity_texture", "opacity_color_texture"]
|
|
295
625
|
},
|
|
296
626
|
normal: {
|
|
297
|
-
surface: ["
|
|
298
|
-
direct: ["
|
|
627
|
+
surface: ["normal"],
|
|
628
|
+
direct: ["normalmap_texture", "normal_texture", "normal_map_texture"]
|
|
299
629
|
},
|
|
300
630
|
roughness: {
|
|
301
|
-
surface: ["
|
|
302
|
-
direct: ["
|
|
631
|
+
surface: ["roughness"],
|
|
632
|
+
direct: ["reflectionroughness_texture", "roughness_texture"]
|
|
303
633
|
},
|
|
304
634
|
metalness: {
|
|
305
|
-
surface: ["
|
|
306
|
-
direct: ["
|
|
635
|
+
surface: ["metallic"],
|
|
636
|
+
direct: ["metallic_texture"]
|
|
307
637
|
},
|
|
308
638
|
occlusion: {
|
|
309
|
-
surface: ["
|
|
310
|
-
direct: ["
|
|
639
|
+
surface: ["occlusion"],
|
|
640
|
+
direct: ["ao_texture", "occlusion_texture"]
|
|
311
641
|
},
|
|
312
642
|
emissive: {
|
|
313
|
-
surface: ["
|
|
314
|
-
direct: ["
|
|
643
|
+
surface: ["emissiveColor"],
|
|
644
|
+
direct: ["emissive_color_texture", "emissive_mask_texture"]
|
|
315
645
|
}
|
|
316
646
|
};
|
|
317
|
-
function resolveBoundMaterial(stage, prim) {
|
|
647
|
+
function resolveBoundMaterial(stage, prim, options = {}) {
|
|
318
648
|
const materialPath = findBinding(prim);
|
|
319
649
|
if (!materialPath) return void 0;
|
|
320
650
|
const material = stage.GetPrimAtPath(materialPath);
|
|
321
651
|
if (!material) return void 0;
|
|
322
652
|
const shader = findSurfaceShader(material);
|
|
323
653
|
if (!shader) return void 0;
|
|
654
|
+
const mdlSource = readMdlShaderSource(shader, options.mdl);
|
|
655
|
+
if (mdlSource && !mdlSource.family) {
|
|
656
|
+
options.onWarn?.(
|
|
657
|
+
`${material.GetPath()}: unknown MDL material "${mdlSource.id}" (${mdlSource.assetPath}); applying the best-effort OmniPBR mapping`
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
const sv = { shader };
|
|
661
|
+
if (mdlSource?.values) sv.mdl = mdlSource.values;
|
|
662
|
+
if (mdlSource) sv.mdlAssetPath = mdlSource.assetPath;
|
|
324
663
|
const result = { name: material.GetName() };
|
|
325
|
-
const color = firstColor(
|
|
664
|
+
const color = firstColor(sv, DIFFUSE_INPUTS);
|
|
326
665
|
if (color) result.color = color;
|
|
327
|
-
const opacity = firstNumber(
|
|
666
|
+
const opacity = firstNumber(sv, OPACITY_INPUTS);
|
|
328
667
|
if (opacity !== void 0) result.opacity = opacity;
|
|
329
|
-
const opacityThreshold = firstNumber(
|
|
668
|
+
const opacityThreshold = firstNumber(sv, OPACITY_THRESHOLD_INPUTS);
|
|
330
669
|
if (opacityThreshold !== void 0) result.opacityThreshold = opacityThreshold;
|
|
331
|
-
const metalness = firstNumber(
|
|
670
|
+
const metalness = firstNumber(sv, METALLIC_INPUTS);
|
|
332
671
|
if (metalness !== void 0) result.metalness = metalness;
|
|
333
|
-
const roughness = firstNumber(
|
|
672
|
+
const roughness = firstNumber(sv, ROUGHNESS_INPUTS);
|
|
334
673
|
if (roughness !== void 0) result.roughness = roughness;
|
|
335
|
-
const emissive = firstColor(
|
|
336
|
-
if (emissive &&
|
|
674
|
+
const emissive = firstColor(sv, EMISSIVE_INPUTS);
|
|
675
|
+
if (emissive && svBoolean(sv, "enable_emission") !== false) {
|
|
337
676
|
result.emissiveColor = emissive;
|
|
338
|
-
|
|
339
|
-
|
|
677
|
+
const intensity = svNumber(sv, "emissive_intensity");
|
|
678
|
+
if (intensity !== void 0) result.emissiveIntensity = intensity;
|
|
679
|
+
}
|
|
680
|
+
const ior = svNumber(sv, "ior");
|
|
681
|
+
if (ior !== void 0) result.ior = ior;
|
|
682
|
+
const clearcoat = svNumber(sv, "clearcoat");
|
|
683
|
+
if (clearcoat !== void 0) result.clearcoat = clearcoat;
|
|
684
|
+
const clearcoatRoughness = svNumber(sv, "clearcoatRoughness");
|
|
685
|
+
if (clearcoatRoughness !== void 0) result.clearcoatRoughness = clearcoatRoughness;
|
|
686
|
+
if (svNumber(sv, "useSpecularWorkflow") === 1) {
|
|
687
|
+
const specular = svColor(sv, "specularColor");
|
|
688
|
+
if (specular) result.specularColor = specular;
|
|
689
|
+
}
|
|
690
|
+
const colorTex = findTexture(sv, TEXTURE_LOOKUPS.color);
|
|
340
691
|
if (colorTex !== void 0) result.colorTexture = colorTex;
|
|
341
|
-
const opacityTex = findTexture(
|
|
692
|
+
const opacityTex = findTexture(sv, TEXTURE_LOOKUPS.opacity);
|
|
342
693
|
if (opacityTex !== void 0) result.opacityTexture = opacityTex;
|
|
343
|
-
const normal = findTexture(
|
|
694
|
+
const normal = findTexture(sv, TEXTURE_LOOKUPS.normal);
|
|
344
695
|
if (normal !== void 0) result.normalTexture = normal;
|
|
345
|
-
const roughTex = findTexture(
|
|
696
|
+
const roughTex = findTexture(sv, TEXTURE_LOOKUPS.roughness);
|
|
346
697
|
if (roughTex !== void 0) result.roughnessTexture = roughTex;
|
|
347
|
-
const metalTex = findTexture(
|
|
698
|
+
const metalTex = findTexture(sv, TEXTURE_LOOKUPS.metalness);
|
|
348
699
|
if (metalTex !== void 0) result.metalnessTexture = metalTex;
|
|
349
|
-
const aoTex = findTexture(
|
|
700
|
+
const aoTex = findTexture(sv, TEXTURE_LOOKUPS.occlusion);
|
|
350
701
|
if (aoTex !== void 0) result.occlusionTexture = aoTex;
|
|
351
|
-
const emissiveTex = findTexture(
|
|
702
|
+
const emissiveTex = findTexture(sv, TEXTURE_LOOKUPS.emissive);
|
|
352
703
|
if (emissiveTex !== void 0) result.emissiveTexture = emissiveTex;
|
|
704
|
+
const orm = directTexture(sv, "ORM_texture") ?? mdlValueTexture(sv, "ORM_texture");
|
|
705
|
+
if (svBoolean(sv, "enable_ORM_texture") === true && orm) {
|
|
706
|
+
result.occlusionTexture = { ...orm, outputChannel: "r" };
|
|
707
|
+
result.roughnessTexture = { ...orm, outputChannel: "g" };
|
|
708
|
+
result.metalnessTexture = { ...orm, outputChannel: "b" };
|
|
709
|
+
}
|
|
710
|
+
switch (mdlSource?.family) {
|
|
711
|
+
case "glass":
|
|
712
|
+
readOmniGlass(sv, result);
|
|
713
|
+
break;
|
|
714
|
+
case "clearcoat":
|
|
715
|
+
readOmniClearCoat(sv, result);
|
|
716
|
+
break;
|
|
717
|
+
case "surface":
|
|
718
|
+
readOmniSurface(sv, result);
|
|
719
|
+
break;
|
|
720
|
+
}
|
|
353
721
|
return result;
|
|
354
722
|
}
|
|
355
|
-
function
|
|
723
|
+
function classifyOmniMdl(name) {
|
|
724
|
+
if (!name) return void 0;
|
|
725
|
+
if (name.startsWith("OmniGlass")) return "glass";
|
|
726
|
+
if (name.startsWith("OmniPBR_ClearCoat")) return "clearcoat";
|
|
727
|
+
if (name.startsWith("OmniPBR")) return "pbr";
|
|
728
|
+
if (name.startsWith("OmniSurface")) return "surface";
|
|
729
|
+
return void 0;
|
|
730
|
+
}
|
|
731
|
+
function readMdlShaderSource(shader, provider) {
|
|
732
|
+
const asset = shader.GetAttribute("info:mdl:sourceAsset").Get();
|
|
733
|
+
if (!(asset instanceof AssetPath) || !asset.path) return void 0;
|
|
734
|
+
const sub = shader.GetAttribute("info:mdl:sourceAsset:subIdentifier").Get();
|
|
735
|
+
const stem = (asset.path.split("/").pop() ?? "").replace(/\.mdl$/i, "");
|
|
736
|
+
const id = typeof sub === "string" && sub.length > 0 ? sub : stem;
|
|
737
|
+
const decl = provider?.(asset.path)?.materials.get(id);
|
|
738
|
+
const family = classifyOmniMdl(decl?.base) ?? classifyOmniMdl(id) ?? classifyOmniMdl(stem);
|
|
739
|
+
const source = { assetPath: asset.path, id };
|
|
740
|
+
if (family) source.family = family;
|
|
741
|
+
if (decl && (decl.defaults.size > 0 || decl.args.size > 0)) {
|
|
742
|
+
source.values = new Map([...decl.defaults, ...decl.args]);
|
|
743
|
+
}
|
|
744
|
+
return source;
|
|
745
|
+
}
|
|
746
|
+
function readOmniGlass(sv, result) {
|
|
747
|
+
result.transmission = 1;
|
|
748
|
+
result.metalness = 0;
|
|
749
|
+
result.color = svColor(sv, "glass_color") ?? [1, 1, 1];
|
|
750
|
+
result.ior = svNumber(sv, "glass_ior") ?? 1.491;
|
|
751
|
+
result.roughness = svNumber(sv, "frosting_roughness") ?? 0;
|
|
752
|
+
const depth = svNumber(sv, "depth");
|
|
753
|
+
if (svBoolean(sv, "thin_walled") !== true && depth !== void 0) result.thickness = depth;
|
|
754
|
+
const cutout = svNumber(sv, "cutout_opacity");
|
|
755
|
+
if (cutout !== void 0 && cutout < 1) result.opacity = cutout;
|
|
756
|
+
}
|
|
757
|
+
function readOmniClearCoat(sv, result) {
|
|
758
|
+
if (svBoolean(sv, "enable_clearcoat") === false) return;
|
|
759
|
+
result.clearcoat = 1;
|
|
760
|
+
const roughness = svNumber(sv, "clearcoat_reflection_roughness");
|
|
761
|
+
if (roughness !== void 0) result.clearcoatRoughness = roughness;
|
|
762
|
+
const normal = directTexture(sv, "clearcoat_normalmap_texture") ?? mdlValueTexture(sv, "clearcoat_normalmap_texture");
|
|
763
|
+
if (normal && svBoolean(sv, "enable_clearcoat_normalmap_texture") !== false) {
|
|
764
|
+
result.clearcoatNormalTexture = normal;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
function readOmniSurface(sv, result) {
|
|
768
|
+
const color = svColor(sv, "diffuse_reflection_color");
|
|
769
|
+
if (color) result.color = color;
|
|
770
|
+
const metalness = svNumber(sv, "metalness");
|
|
771
|
+
if (metalness !== void 0) result.metalness = metalness;
|
|
772
|
+
const roughness = svNumber(sv, "specular_reflection_roughness");
|
|
773
|
+
if (roughness !== void 0) result.roughness = roughness;
|
|
774
|
+
const ior = svNumber(sv, "specular_reflection_ior");
|
|
775
|
+
if (ior !== void 0) result.ior = ior;
|
|
776
|
+
const coat = svNumber(sv, "coat_weight");
|
|
777
|
+
if (coat !== void 0 && coat > 0) {
|
|
778
|
+
result.clearcoat = coat;
|
|
779
|
+
const coatRoughness = svNumber(sv, "coat_roughness");
|
|
780
|
+
if (coatRoughness !== void 0) result.clearcoatRoughness = coatRoughness;
|
|
781
|
+
}
|
|
782
|
+
const emissionWeight = svNumber(sv, "emission_weight");
|
|
783
|
+
const emissionColor = svColor(sv, "emission_color");
|
|
784
|
+
if (emissionWeight !== void 0 && emissionWeight > 0 && emissionColor) {
|
|
785
|
+
result.emissiveColor = emissionColor;
|
|
786
|
+
result.emissiveIntensity = emissionWeight;
|
|
787
|
+
}
|
|
788
|
+
if (svBoolean(sv, "enable_opacity") === true) {
|
|
789
|
+
const opacity = svNumber(sv, "geometry_opacity");
|
|
790
|
+
if (opacity !== void 0) result.opacity = opacity;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
function authored(sv, name) {
|
|
794
|
+
return sv.shader.GetAttribute(`inputs:${name}`).Get();
|
|
795
|
+
}
|
|
796
|
+
function asNumber2(v) {
|
|
797
|
+
return typeof v === "number" ? v : void 0;
|
|
798
|
+
}
|
|
799
|
+
function asBoolean(v) {
|
|
800
|
+
return typeof v === "boolean" ? v : void 0;
|
|
801
|
+
}
|
|
802
|
+
function asVec(v, length) {
|
|
803
|
+
if (Array.isArray(v) && v.length >= length && v.every((n) => typeof n === "number")) {
|
|
804
|
+
return v.slice(0, length);
|
|
805
|
+
}
|
|
806
|
+
return void 0;
|
|
807
|
+
}
|
|
808
|
+
function svNumber(sv, name) {
|
|
809
|
+
return asNumber2(authored(sv, name)) ?? asNumber2(sv.mdl?.get(name));
|
|
810
|
+
}
|
|
811
|
+
function svBoolean(sv, name) {
|
|
812
|
+
return asBoolean(authored(sv, name)) ?? asBoolean(sv.mdl?.get(name));
|
|
813
|
+
}
|
|
814
|
+
function svColor(sv, name) {
|
|
815
|
+
const v = asVec(authored(sv, name), 3) ?? asVec(sv.mdl?.get(name), 3);
|
|
816
|
+
return v ? v : void 0;
|
|
817
|
+
}
|
|
818
|
+
function svVec2(sv, name) {
|
|
819
|
+
const v = asVec(authored(sv, name), 2) ?? asVec(sv.mdl?.get(name), 2);
|
|
820
|
+
return v ? v : void 0;
|
|
821
|
+
}
|
|
822
|
+
function firstNumber(sv, names) {
|
|
823
|
+
for (const name of names) {
|
|
824
|
+
const v = asNumber2(authored(sv, name));
|
|
825
|
+
if (v !== void 0) return v;
|
|
826
|
+
}
|
|
827
|
+
for (const name of names) {
|
|
828
|
+
const v = asNumber2(sv.mdl?.get(name));
|
|
829
|
+
if (v !== void 0) return v;
|
|
830
|
+
}
|
|
831
|
+
return void 0;
|
|
832
|
+
}
|
|
833
|
+
function firstColor(sv, names) {
|
|
834
|
+
for (const name of names) {
|
|
835
|
+
const v = asVec(authored(sv, name), 3);
|
|
836
|
+
if (v) return v;
|
|
837
|
+
}
|
|
838
|
+
for (const name of names) {
|
|
839
|
+
const v = asVec(sv.mdl?.get(name), 3);
|
|
840
|
+
if (v) return v;
|
|
841
|
+
}
|
|
842
|
+
return void 0;
|
|
843
|
+
}
|
|
844
|
+
function directTexture(sv, name) {
|
|
845
|
+
const v = authored(sv, name);
|
|
846
|
+
if (v instanceof AssetPath && v.path) return withMdlTransform(sv, { path: v.path });
|
|
847
|
+
return void 0;
|
|
848
|
+
}
|
|
849
|
+
function mdlValueTexture(sv, name) {
|
|
850
|
+
const v = sv.mdl?.get(name);
|
|
851
|
+
if (!isMdlTexture(v)) return void 0;
|
|
852
|
+
const texture = { path: resolveMdlRelative(sv.mdlAssetPath, v.assetPath) };
|
|
853
|
+
if (v.sourceColorSpace) texture.sourceColorSpace = v.sourceColorSpace;
|
|
854
|
+
return withMdlTransform(sv, texture);
|
|
855
|
+
}
|
|
856
|
+
function resolveMdlRelative(modulePath, path) {
|
|
857
|
+
if (!modulePath || path.startsWith("/") || /^[a-z][a-z0-9+.-]*:/i.test(path)) return path;
|
|
858
|
+
return joinPosix(modulePath, path);
|
|
859
|
+
}
|
|
860
|
+
function withMdlTransform(sv, texture) {
|
|
861
|
+
const transform = mdlTextureTransform(sv);
|
|
862
|
+
return transform ? { ...texture, transform } : texture;
|
|
863
|
+
}
|
|
864
|
+
function findTexture(sv, lookup) {
|
|
356
865
|
for (const name of lookup.direct) {
|
|
357
|
-
const
|
|
358
|
-
if (
|
|
866
|
+
const texture = directTexture(sv, name);
|
|
867
|
+
if (texture) return texture;
|
|
359
868
|
}
|
|
360
869
|
for (const name of lookup.surface) {
|
|
361
|
-
const conn = shader.GetAttribute(name).GetConnections()[0];
|
|
870
|
+
const conn = sv.shader.GetAttribute(`inputs:${name}`).GetConnections()[0];
|
|
362
871
|
if (!conn) continue;
|
|
363
|
-
const texPrim = shader.GetStage().GetPrimAtPath(conn.split(".")[0]);
|
|
872
|
+
const texPrim = sv.shader.GetStage().GetPrimAtPath(conn.split(".")[0]);
|
|
364
873
|
if (!texPrim) continue;
|
|
365
874
|
const file = texPrim.GetAttribute("inputs:file").Get();
|
|
366
|
-
if (file instanceof AssetPath && file.path)
|
|
875
|
+
if (file instanceof AssetPath && file.path) {
|
|
876
|
+
const tex = readUvTexture(texPrim, file.path);
|
|
877
|
+
const channel = outputChannelOf(conn);
|
|
878
|
+
if (channel) tex.outputChannel = channel;
|
|
879
|
+
return tex;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
for (const name of lookup.direct) {
|
|
883
|
+
const texture = mdlValueTexture(sv, name);
|
|
884
|
+
if (texture) return texture;
|
|
367
885
|
}
|
|
368
886
|
return void 0;
|
|
369
887
|
}
|
|
888
|
+
function outputChannelOf(connection) {
|
|
889
|
+
const m = /\.outputs:(\w+)$/.exec(connection);
|
|
890
|
+
switch (m?.[1]) {
|
|
891
|
+
case "r":
|
|
892
|
+
case "g":
|
|
893
|
+
case "b":
|
|
894
|
+
case "a":
|
|
895
|
+
return m[1];
|
|
896
|
+
case "rgb":
|
|
897
|
+
case "rgba":
|
|
898
|
+
return "rgb";
|
|
899
|
+
default:
|
|
900
|
+
return void 0;
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
function mdlTextureTransform(sv) {
|
|
904
|
+
const transform = {};
|
|
905
|
+
const translation = svVec2(sv, "texture_translate");
|
|
906
|
+
if (translation) transform.translation = translation;
|
|
907
|
+
const scale = svVec2(sv, "texture_scale");
|
|
908
|
+
if (scale) transform.scale = scale;
|
|
909
|
+
const rotation = svNumber(sv, "texture_rotate");
|
|
910
|
+
if (rotation !== void 0) transform.rotation = rotation;
|
|
911
|
+
return Object.keys(transform).length > 0 ? transform : void 0;
|
|
912
|
+
}
|
|
370
913
|
var WRAP_VALUES = /* @__PURE__ */ new Set(["repeat", "clamp", "mirror", "black"]);
|
|
371
914
|
function readUvTexture(texPrim, path) {
|
|
372
915
|
const tex = { path };
|
|
@@ -378,39 +921,58 @@ function readUvTexture(texPrim, path) {
|
|
|
378
921
|
if (scale) tex.scale = scale;
|
|
379
922
|
const bias = numArray(texPrim, "inputs:bias", 4);
|
|
380
923
|
if (bias) tex.bias = bias;
|
|
381
|
-
const
|
|
382
|
-
if (
|
|
924
|
+
const sourceColorSpace = texPrim.GetAttribute("inputs:sourceColorSpace").Get();
|
|
925
|
+
if (sourceColorSpace === "raw" || sourceColorSpace === "sRGB" || sourceColorSpace === "auto") {
|
|
926
|
+
tex.sourceColorSpace = sourceColorSpace;
|
|
927
|
+
}
|
|
928
|
+
const st = readStChain(texPrim);
|
|
929
|
+
if (st.transform) tex.transform = st.transform;
|
|
930
|
+
if (st.uvSet) tex.uvSet = st.uvSet;
|
|
383
931
|
return tex;
|
|
384
932
|
}
|
|
385
|
-
function
|
|
386
|
-
const conn =
|
|
387
|
-
if (!conn) return
|
|
388
|
-
|
|
389
|
-
if (!node || node.GetAttribute("info:id").Get() !== "UsdTransform2d") return void 0;
|
|
390
|
-
const transform = {};
|
|
391
|
-
const translation = numArray(node, "inputs:translation", 2);
|
|
392
|
-
if (translation) transform.translation = translation;
|
|
393
|
-
const scale = numArray(node, "inputs:scale", 2);
|
|
394
|
-
if (scale) transform.scale = scale;
|
|
395
|
-
const rotation = node.GetAttribute("inputs:rotation").Get();
|
|
396
|
-
if (typeof rotation === "number") transform.rotation = rotation;
|
|
397
|
-
return Object.keys(transform).length > 0 ? transform : void 0;
|
|
933
|
+
function connectedPrim(prim, input) {
|
|
934
|
+
const conn = prim.GetAttribute(input).GetConnections()[0];
|
|
935
|
+
if (!conn) return null;
|
|
936
|
+
return prim.GetStage().GetPrimAtPath(conn.split(".")[0]);
|
|
398
937
|
}
|
|
399
|
-
function
|
|
400
|
-
const
|
|
401
|
-
|
|
402
|
-
|
|
938
|
+
function readStChain(texPrim) {
|
|
939
|
+
const out = {};
|
|
940
|
+
let node = connectedPrim(texPrim, "inputs:st");
|
|
941
|
+
if (node && node.GetAttribute("info:id").Get() === "UsdTransform2d") {
|
|
942
|
+
const transform = {};
|
|
943
|
+
const translation = numArray(node, "inputs:translation", 2);
|
|
944
|
+
if (translation) transform.translation = translation;
|
|
945
|
+
const scale = numArray(node, "inputs:scale", 2);
|
|
946
|
+
if (scale) transform.scale = scale;
|
|
947
|
+
const rotation = node.GetAttribute("inputs:rotation").Get();
|
|
948
|
+
if (typeof rotation === "number") transform.rotation = rotation;
|
|
949
|
+
if (Object.keys(transform).length > 0) out.transform = transform;
|
|
950
|
+
node = connectedPrim(node, "inputs:in");
|
|
951
|
+
}
|
|
952
|
+
if (node && node.GetAttribute("info:id").Get() === "UsdPrimvarReader_float2") {
|
|
953
|
+
const varname = node.GetAttribute("inputs:varname").Get();
|
|
954
|
+
if (typeof varname === "string" && varname.length > 0) out.uvSet = varname;
|
|
403
955
|
}
|
|
404
|
-
return
|
|
956
|
+
return out;
|
|
957
|
+
}
|
|
958
|
+
function numArray(prim, name, length) {
|
|
959
|
+
return asVec(prim.GetAttribute(name).Get(), length);
|
|
405
960
|
}
|
|
406
961
|
function findBinding(prim) {
|
|
962
|
+
let chosen;
|
|
407
963
|
let p = prim;
|
|
408
964
|
while (p) {
|
|
409
|
-
const
|
|
410
|
-
|
|
965
|
+
for (const name of ["material:binding:preview", "material:binding"]) {
|
|
966
|
+
const rel = p.GetRelationship(name);
|
|
967
|
+
const target = rel.GetTargets()[0];
|
|
968
|
+
if (!target) continue;
|
|
969
|
+
const stronger = rel.GetMetadata("bindMaterialAs") === "strongerThanDescendants";
|
|
970
|
+
if (chosen === void 0 || stronger) chosen = target;
|
|
971
|
+
break;
|
|
972
|
+
}
|
|
411
973
|
p = p.GetParent();
|
|
412
974
|
}
|
|
413
|
-
return
|
|
975
|
+
return chosen;
|
|
414
976
|
}
|
|
415
977
|
function findSurfaceShader(material) {
|
|
416
978
|
for (const out of SURFACE_OUTPUTS) {
|
|
@@ -423,22 +985,6 @@ function findSurfaceShader(material) {
|
|
|
423
985
|
}
|
|
424
986
|
return material.GetChildren().find((c) => c.GetTypeName() === "Shader") ?? void 0;
|
|
425
987
|
}
|
|
426
|
-
function firstColor(shader, names) {
|
|
427
|
-
for (const name of names) {
|
|
428
|
-
const v = shader.GetAttribute(name).Get();
|
|
429
|
-
if (Array.isArray(v) && v.length >= 3 && v.every((n) => typeof n === "number")) {
|
|
430
|
-
return [v[0], v[1], v[2]];
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
return void 0;
|
|
434
|
-
}
|
|
435
|
-
function firstNumber(shader, names) {
|
|
436
|
-
for (const name of names) {
|
|
437
|
-
const v = shader.GetAttribute(name).Get();
|
|
438
|
-
if (typeof v === "number") return v;
|
|
439
|
-
}
|
|
440
|
-
return void 0;
|
|
441
|
-
}
|
|
442
988
|
|
|
443
989
|
// src/robot/buildKinematicTree.ts
|
|
444
990
|
var WORLD = "";
|
|
@@ -720,61 +1266,6 @@ function leafName(path) {
|
|
|
720
1266
|
return parts[parts.length - 1] ?? path;
|
|
721
1267
|
}
|
|
722
1268
|
|
|
723
|
-
// src/usd/AssetResolver.ts
|
|
724
|
-
var DefaultAssetResolver = class {
|
|
725
|
-
resolve(assetPath, baseUrl) {
|
|
726
|
-
try {
|
|
727
|
-
return new URL(assetPath, baseUrl || void 0).href;
|
|
728
|
-
} catch {
|
|
729
|
-
return joinPosix(baseUrl, assetPath);
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
async fetchText(url) {
|
|
733
|
-
const res = await fetch(url);
|
|
734
|
-
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
|
|
735
|
-
return res.text();
|
|
736
|
-
}
|
|
737
|
-
async fetchBytes(url) {
|
|
738
|
-
const res = await fetch(url);
|
|
739
|
-
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
|
|
740
|
-
return new Uint8Array(await res.arrayBuffer());
|
|
741
|
-
}
|
|
742
|
-
};
|
|
743
|
-
function createMemoryResolver(files) {
|
|
744
|
-
const decoder = new TextDecoder();
|
|
745
|
-
const encoder = new TextEncoder();
|
|
746
|
-
return {
|
|
747
|
-
resolve(assetPath, baseUrl) {
|
|
748
|
-
return joinPosix(baseUrl, assetPath);
|
|
749
|
-
},
|
|
750
|
-
fetchText(url) {
|
|
751
|
-
const v = files[url];
|
|
752
|
-
if (v === void 0) return Promise.reject(new Error(`asset not found: ${url}`));
|
|
753
|
-
return Promise.resolve(typeof v === "string" ? v : decoder.decode(v));
|
|
754
|
-
},
|
|
755
|
-
fetchBytes(url) {
|
|
756
|
-
const v = files[url];
|
|
757
|
-
if (v === void 0) return Promise.reject(new Error(`asset not found: ${url}`));
|
|
758
|
-
return Promise.resolve(typeof v === "string" ? encoder.encode(v) : v);
|
|
759
|
-
}
|
|
760
|
-
};
|
|
761
|
-
}
|
|
762
|
-
function joinPosix(baseUrl, rel) {
|
|
763
|
-
if (rel.startsWith("/")) return normalizePosix(rel);
|
|
764
|
-
const dir = baseUrl.slice(0, baseUrl.lastIndexOf("/") + 1);
|
|
765
|
-
return normalizePosix(dir + rel);
|
|
766
|
-
}
|
|
767
|
-
function normalizePosix(path) {
|
|
768
|
-
const isAbsolute = path.startsWith("/");
|
|
769
|
-
const out = [];
|
|
770
|
-
for (const part of path.split("/")) {
|
|
771
|
-
if (part === "" || part === ".") continue;
|
|
772
|
-
if (part === "..") out.pop();
|
|
773
|
-
else out.push(part);
|
|
774
|
-
}
|
|
775
|
-
return (isAbsolute ? "/" : "") + out.join("/");
|
|
776
|
-
}
|
|
777
|
-
|
|
778
1269
|
// src/parser/reader.ts
|
|
779
1270
|
var ParseError = class extends Error {
|
|
780
1271
|
constructor(message, line, col) {
|
|
@@ -861,7 +1352,7 @@ var TokenizeError = class extends Error {
|
|
|
861
1352
|
};
|
|
862
1353
|
var IDENT_START = /[A-Za-z_]/;
|
|
863
1354
|
var IDENT_CONT = /[A-Za-z0-9_:]/;
|
|
864
|
-
var
|
|
1355
|
+
var NUMBER_RE2 = /^[-+]?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?/;
|
|
865
1356
|
var INF_NAN_RE = /^[-+]?(?:inf|nan)\b/i;
|
|
866
1357
|
function tokenize(src) {
|
|
867
1358
|
const tokens = [];
|
|
@@ -933,7 +1424,7 @@ function tokenize(src) {
|
|
|
933
1424
|
continue;
|
|
934
1425
|
}
|
|
935
1426
|
if (/[0-9]/.test(c) || (c === "-" || c === "+" || c === ".") && /[0-9.]/.test(src[i + 1] ?? "")) {
|
|
936
|
-
const m =
|
|
1427
|
+
const m = NUMBER_RE2.exec(src.slice(i));
|
|
937
1428
|
if (m) {
|
|
938
1429
|
const text = m[0];
|
|
939
1430
|
push("number", text, startCol, Number(text));
|
|
@@ -1776,6 +2267,10 @@ var Attribute = class {
|
|
|
1776
2267
|
GetConnections() {
|
|
1777
2268
|
return this._spec?.connections ?? [];
|
|
1778
2269
|
}
|
|
2270
|
+
/** Authored attribute metadata (`interpolation`, `elementSize`, …). */
|
|
2271
|
+
GetMetadata(key) {
|
|
2272
|
+
return this._spec?.metadata[key];
|
|
2273
|
+
}
|
|
1779
2274
|
};
|
|
1780
2275
|
var Relationship = class {
|
|
1781
2276
|
constructor(_prim, _name, _spec) {
|
|
@@ -1807,6 +2302,10 @@ var Relationship = class {
|
|
|
1807
2302
|
GetTargets() {
|
|
1808
2303
|
return this._spec?.targets ?? [];
|
|
1809
2304
|
}
|
|
2305
|
+
/** Authored relationship metadata (`bindMaterialAs`, …). */
|
|
2306
|
+
GetMetadata(key) {
|
|
2307
|
+
return this._spec?.metadata[key];
|
|
2308
|
+
}
|
|
1810
2309
|
};
|
|
1811
2310
|
|
|
1812
2311
|
// src/usd/Prim.ts
|
|
@@ -2159,10 +2658,17 @@ var CrateType = {
|
|
|
2159
2658
|
Quatf: 17,
|
|
2160
2659
|
Vec2d: 19,
|
|
2161
2660
|
Vec2f: 20,
|
|
2661
|
+
Vec2h: 21,
|
|
2662
|
+
Vec2i: 22,
|
|
2162
2663
|
Vec3d: 23,
|
|
2163
2664
|
Vec3f: 24,
|
|
2665
|
+
Vec3h: 25,
|
|
2666
|
+
Vec3i: 26,
|
|
2164
2667
|
Vec4d: 27,
|
|
2165
2668
|
Vec4f: 28,
|
|
2669
|
+
Vec4h: 29,
|
|
2670
|
+
Vec4i: 30,
|
|
2671
|
+
Dictionary: 31,
|
|
2166
2672
|
TokenListOp: 32,
|
|
2167
2673
|
PathListOp: 34,
|
|
2168
2674
|
ReferenceListOp: 35,
|
|
@@ -2173,6 +2679,8 @@ var CrateType = {
|
|
|
2173
2679
|
Permission: 43,
|
|
2174
2680
|
Variability: 44,
|
|
2175
2681
|
VariantSelectionMap: 45,
|
|
2682
|
+
TimeSamples: 46,
|
|
2683
|
+
DoubleVector: 48,
|
|
2176
2684
|
StringVector: 50,
|
|
2177
2685
|
PayloadListOp: 55};
|
|
2178
2686
|
var ListOpBits = {
|
|
@@ -2207,6 +2715,12 @@ function halfToFloat(h) {
|
|
|
2207
2715
|
var MAGIC = "PXR-USDC";
|
|
2208
2716
|
var scratch = new DataView(new ArrayBuffer(8));
|
|
2209
2717
|
var FIELDSET_END = -1;
|
|
2718
|
+
var MIN_COMPRESSED_ARRAY_SIZE = 16;
|
|
2719
|
+
function inlineInt8s(low, n) {
|
|
2720
|
+
const out = new Array(n);
|
|
2721
|
+
for (let i = 0; i < n; i++) out[i] = (low >>> i * 8 & 255) << 24 >> 24;
|
|
2722
|
+
return out;
|
|
2723
|
+
}
|
|
2210
2724
|
var CrateReader = class {
|
|
2211
2725
|
version;
|
|
2212
2726
|
view;
|
|
@@ -2440,6 +2954,33 @@ var CrateReader = class {
|
|
|
2440
2954
|
if (b.isInlined) return this.readInlined(b.type, b.payload);
|
|
2441
2955
|
return this.readScalar(b.type, Number(b.payload));
|
|
2442
2956
|
}
|
|
2957
|
+
/**
|
|
2958
|
+
* Decode a `timeSamples` field (a {@link CrateType.TimeSamples} rep) into
|
|
2959
|
+
* parallel times/values arrays; `undefined` if `rep` is some other type.
|
|
2960
|
+
*
|
|
2961
|
+
* Layout (pxr `crateFile.cpp`, `Write(TimeSamples)`): an `int64` offset —
|
|
2962
|
+
* relative to its own position — jumps over the recursively-written times
|
|
2963
|
+
* data to the times `ValueRep` (a `DoubleVector`); a second such offset
|
|
2964
|
+
* jumps over the samples' data to `[u64 count][count × ValueRep]`. Sample
|
|
2965
|
+
* reps decode through {@link getValue}, so every scalar/array type works.
|
|
2966
|
+
*/
|
|
2967
|
+
getTimeSamples(rep) {
|
|
2968
|
+
const b = decodeRepBits(rep);
|
|
2969
|
+
if (b.type !== CrateType.TimeSamples || b.isArray || b.isInlined) return void 0;
|
|
2970
|
+
const off = Number(b.payload);
|
|
2971
|
+
let p = off + Number(this.i64(off));
|
|
2972
|
+
const times = this.getValue(this.view.getBigUint64(p, true));
|
|
2973
|
+
p += 8;
|
|
2974
|
+
if (!Array.isArray(times) || !times.every((t) => typeof t === "number")) return void 0;
|
|
2975
|
+
p += Number(this.i64(p));
|
|
2976
|
+
const count = this.u64(p);
|
|
2977
|
+
p += 8;
|
|
2978
|
+
const values = new Array(count);
|
|
2979
|
+
for (let i = 0; i < count; i++) {
|
|
2980
|
+
values[i] = this.getValue(this.view.getBigUint64(p + i * 8, true));
|
|
2981
|
+
}
|
|
2982
|
+
return { times, values };
|
|
2983
|
+
}
|
|
2443
2984
|
readInlined(type, payload) {
|
|
2444
2985
|
const low = Number(payload & 0xffffffffn);
|
|
2445
2986
|
switch (type) {
|
|
@@ -2469,6 +3010,62 @@ var CrateReader = class {
|
|
|
2469
3010
|
case CrateType.Permission:
|
|
2470
3011
|
case CrateType.Variability:
|
|
2471
3012
|
return low;
|
|
3013
|
+
// Vectors whose components are all small integers are inlined as one
|
|
3014
|
+
// int8 per component in the payload's low bytes (crateValueInliners.h).
|
|
3015
|
+
case CrateType.Vec2i:
|
|
3016
|
+
case CrateType.Vec2h:
|
|
3017
|
+
case CrateType.Vec2f:
|
|
3018
|
+
case CrateType.Vec2d:
|
|
3019
|
+
return inlineInt8s(low, 2);
|
|
3020
|
+
case CrateType.Vec3i:
|
|
3021
|
+
case CrateType.Vec3h:
|
|
3022
|
+
case CrateType.Vec3f:
|
|
3023
|
+
case CrateType.Vec3d:
|
|
3024
|
+
return inlineInt8s(low, 3);
|
|
3025
|
+
case CrateType.Vec4i:
|
|
3026
|
+
case CrateType.Vec4h:
|
|
3027
|
+
case CrateType.Vec4f:
|
|
3028
|
+
case CrateType.Vec4d:
|
|
3029
|
+
return inlineInt8s(low, 4);
|
|
3030
|
+
// Matrices inline when off-diagonal is zero and the diagonal fits int8.
|
|
3031
|
+
case CrateType.Matrix3d: {
|
|
3032
|
+
const [a, b, c] = inlineInt8s(low, 3);
|
|
3033
|
+
return new UsdMatrix([
|
|
3034
|
+
a,
|
|
3035
|
+
0,
|
|
3036
|
+
0,
|
|
3037
|
+
0,
|
|
3038
|
+
b,
|
|
3039
|
+
0,
|
|
3040
|
+
0,
|
|
3041
|
+
0,
|
|
3042
|
+
c
|
|
3043
|
+
], 3);
|
|
3044
|
+
}
|
|
3045
|
+
case CrateType.Matrix4d: {
|
|
3046
|
+
const [a, b, c, d] = inlineInt8s(low, 4);
|
|
3047
|
+
return new UsdMatrix([
|
|
3048
|
+
a,
|
|
3049
|
+
0,
|
|
3050
|
+
0,
|
|
3051
|
+
0,
|
|
3052
|
+
0,
|
|
3053
|
+
b,
|
|
3054
|
+
0,
|
|
3055
|
+
0,
|
|
3056
|
+
0,
|
|
3057
|
+
0,
|
|
3058
|
+
c,
|
|
3059
|
+
0,
|
|
3060
|
+
0,
|
|
3061
|
+
0,
|
|
3062
|
+
0,
|
|
3063
|
+
d
|
|
3064
|
+
], 4);
|
|
3065
|
+
}
|
|
3066
|
+
// Only the empty dictionary is inlined.
|
|
3067
|
+
case CrateType.Dictionary:
|
|
3068
|
+
return {};
|
|
2472
3069
|
default:
|
|
2473
3070
|
return void 0;
|
|
2474
3071
|
}
|
|
@@ -2486,6 +3083,12 @@ var CrateReader = class {
|
|
|
2486
3083
|
return v.getInt32(off, true);
|
|
2487
3084
|
case CrateType.UInt:
|
|
2488
3085
|
return v.getUint32(off, true);
|
|
3086
|
+
case CrateType.UChar:
|
|
3087
|
+
return v.getUint8(off);
|
|
3088
|
+
case CrateType.Int64:
|
|
3089
|
+
return Number(v.getBigInt64(off, true));
|
|
3090
|
+
case CrateType.UInt64:
|
|
3091
|
+
return Number(v.getBigUint64(off, true));
|
|
2489
3092
|
case CrateType.Token:
|
|
2490
3093
|
return this.getToken(v.getUint32(off, true));
|
|
2491
3094
|
case CrateType.String:
|
|
@@ -2504,6 +3107,18 @@ var CrateReader = class {
|
|
|
2504
3107
|
return this.readFloat64s(off, 3);
|
|
2505
3108
|
case CrateType.Vec4d:
|
|
2506
3109
|
return this.readFloat64s(off, 4);
|
|
3110
|
+
case CrateType.Vec2h:
|
|
3111
|
+
return this.readHalfs(off, 2);
|
|
3112
|
+
case CrateType.Vec3h:
|
|
3113
|
+
return this.readHalfs(off, 3);
|
|
3114
|
+
case CrateType.Vec4h:
|
|
3115
|
+
return this.readHalfs(off, 4);
|
|
3116
|
+
case CrateType.Vec2i:
|
|
3117
|
+
return this.readInt32s(off, 2);
|
|
3118
|
+
case CrateType.Vec3i:
|
|
3119
|
+
return this.readInt32s(off, 3);
|
|
3120
|
+
case CrateType.Vec4i:
|
|
3121
|
+
return this.readInt32s(off, 4);
|
|
2507
3122
|
case CrateType.Quatf: {
|
|
2508
3123
|
const q = this.readFloat32s(off, 4);
|
|
2509
3124
|
return new Quat(q[3], [q[0], q[1], q[2]]);
|
|
@@ -2533,41 +3148,176 @@ var CrateReader = class {
|
|
|
2533
3148
|
return this.readIndexVector(off, "string").items;
|
|
2534
3149
|
case CrateType.VariantSelectionMap:
|
|
2535
3150
|
return this.readVariantSelectionMap(off);
|
|
3151
|
+
case CrateType.DoubleVector: {
|
|
3152
|
+
const count = this.u64(off);
|
|
3153
|
+
return this.readFloat64s(off + 8, count);
|
|
3154
|
+
}
|
|
3155
|
+
case CrateType.Dictionary:
|
|
3156
|
+
return this.readDictionary(off, 0);
|
|
2536
3157
|
default:
|
|
2537
3158
|
return void 0;
|
|
2538
3159
|
}
|
|
2539
3160
|
}
|
|
3161
|
+
/** Array headers store a u32 count before crate 0.7.0, a u64 from 0.7.0 on. */
|
|
3162
|
+
arrayHeader(off) {
|
|
3163
|
+
if (this.version[0] === 0 && this.version[1] < 7) {
|
|
3164
|
+
return { count: this.view.getUint32(off, true), next: off + 4 };
|
|
3165
|
+
}
|
|
3166
|
+
return { count: this.u64(off), next: off + 8 };
|
|
3167
|
+
}
|
|
2540
3168
|
readArray(type, off, compressed) {
|
|
2541
3169
|
if (off === 0) return [];
|
|
2542
|
-
const count = this.
|
|
2543
|
-
|
|
2544
|
-
if (compressed)
|
|
2545
|
-
const compressedSize = this.u64(p);
|
|
2546
|
-
p += 8;
|
|
2547
|
-
return decodeIntegers32(this.bytes.subarray(p, p + compressedSize), count);
|
|
2548
|
-
}
|
|
3170
|
+
const { count, next: p } = this.arrayHeader(off);
|
|
3171
|
+
if (count === 0) return [];
|
|
3172
|
+
if (compressed) return this.readCompressedArray(type, p, count);
|
|
2549
3173
|
const v = this.view;
|
|
2550
3174
|
switch (type) {
|
|
3175
|
+
case CrateType.Bool: {
|
|
3176
|
+
const out = new Array(count);
|
|
3177
|
+
for (let i = 0; i < count; i++) out[i] = this.bytes[p + i] !== 0;
|
|
3178
|
+
return out;
|
|
3179
|
+
}
|
|
3180
|
+
case CrateType.UChar: {
|
|
3181
|
+
const out = new Array(count);
|
|
3182
|
+
for (let i = 0; i < count; i++) out[i] = this.bytes[p + i];
|
|
3183
|
+
return out;
|
|
3184
|
+
}
|
|
2551
3185
|
case CrateType.Int:
|
|
2552
3186
|
case CrateType.UInt: {
|
|
2553
3187
|
const out = new Array(count);
|
|
2554
3188
|
for (let i = 0; i < count; i++) out[i] = v.getInt32(p + i * 4, true);
|
|
2555
3189
|
return out;
|
|
2556
3190
|
}
|
|
2557
|
-
case CrateType.
|
|
3191
|
+
case CrateType.Int64: {
|
|
2558
3192
|
const out = new Array(count);
|
|
2559
|
-
for (let i = 0; i < count; i++) out[i] = v.
|
|
3193
|
+
for (let i = 0; i < count; i++) out[i] = Number(v.getBigInt64(p + i * 8, true));
|
|
2560
3194
|
return out;
|
|
2561
3195
|
}
|
|
3196
|
+
case CrateType.UInt64: {
|
|
3197
|
+
const out = new Array(count);
|
|
3198
|
+
for (let i = 0; i < count; i++) out[i] = Number(v.getBigUint64(p + i * 8, true));
|
|
3199
|
+
return out;
|
|
3200
|
+
}
|
|
3201
|
+
case CrateType.Half:
|
|
3202
|
+
return this.readHalfs(p, count);
|
|
3203
|
+
case CrateType.Float:
|
|
3204
|
+
return this.readFloat32s(p, count);
|
|
3205
|
+
case CrateType.Double:
|
|
3206
|
+
return this.readFloat64s(p, count);
|
|
2562
3207
|
case CrateType.Token: {
|
|
2563
3208
|
const out = new Array(count);
|
|
2564
3209
|
for (let i = 0; i < count; i++) out[i] = this.getToken(v.getUint32(p + i * 4, true));
|
|
2565
3210
|
return out;
|
|
2566
3211
|
}
|
|
3212
|
+
case CrateType.String: {
|
|
3213
|
+
const out = new Array(count);
|
|
3214
|
+
for (let i = 0; i < count; i++) {
|
|
3215
|
+
out[i] = this.getToken(this.getStrings()[v.getUint32(p + i * 4, true)] ?? 0);
|
|
3216
|
+
}
|
|
3217
|
+
return out;
|
|
3218
|
+
}
|
|
3219
|
+
case CrateType.AssetPath: {
|
|
3220
|
+
const out = new Array(count);
|
|
3221
|
+
for (let i = 0; i < count; i++) {
|
|
3222
|
+
out[i] = new AssetPath(
|
|
3223
|
+
this.getToken(this.getStrings()[v.getUint32(p + i * 4, true)] ?? 0)
|
|
3224
|
+
);
|
|
3225
|
+
}
|
|
3226
|
+
return out;
|
|
3227
|
+
}
|
|
3228
|
+
case CrateType.Vec2f:
|
|
3229
|
+
return this.readTupleArray(p, count, 2, "f32");
|
|
2567
3230
|
case CrateType.Vec3f:
|
|
2568
|
-
return this.
|
|
3231
|
+
return this.readTupleArray(p, count, 3, "f32");
|
|
3232
|
+
case CrateType.Vec4f:
|
|
3233
|
+
return this.readTupleArray(p, count, 4, "f32");
|
|
3234
|
+
case CrateType.Vec2d:
|
|
3235
|
+
return this.readTupleArray(p, count, 2, "f64");
|
|
2569
3236
|
case CrateType.Vec3d:
|
|
2570
|
-
return this.
|
|
3237
|
+
return this.readTupleArray(p, count, 3, "f64");
|
|
3238
|
+
case CrateType.Vec4d:
|
|
3239
|
+
return this.readTupleArray(p, count, 4, "f64");
|
|
3240
|
+
case CrateType.Vec2h:
|
|
3241
|
+
return this.readTupleArray(p, count, 2, "f16");
|
|
3242
|
+
case CrateType.Vec3h:
|
|
3243
|
+
return this.readTupleArray(p, count, 3, "f16");
|
|
3244
|
+
case CrateType.Vec4h:
|
|
3245
|
+
return this.readTupleArray(p, count, 4, "f16");
|
|
3246
|
+
case CrateType.Vec2i:
|
|
3247
|
+
return this.readTupleArray(p, count, 2, "i32");
|
|
3248
|
+
case CrateType.Vec3i:
|
|
3249
|
+
return this.readTupleArray(p, count, 3, "i32");
|
|
3250
|
+
case CrateType.Vec4i:
|
|
3251
|
+
return this.readTupleArray(p, count, 4, "i32");
|
|
3252
|
+
case CrateType.Quatf: {
|
|
3253
|
+
const out = new Array(count);
|
|
3254
|
+
for (let i = 0; i < count; i++) {
|
|
3255
|
+
const q = this.readFloat32s(p + i * 16, 4);
|
|
3256
|
+
out[i] = new Quat(q[3], [q[0], q[1], q[2]]);
|
|
3257
|
+
}
|
|
3258
|
+
return out;
|
|
3259
|
+
}
|
|
3260
|
+
case CrateType.Quatd: {
|
|
3261
|
+
const out = new Array(count);
|
|
3262
|
+
for (let i = 0; i < count; i++) {
|
|
3263
|
+
const q = this.readFloat64s(p + i * 32, 4);
|
|
3264
|
+
out[i] = new Quat(q[3], [q[0], q[1], q[2]]);
|
|
3265
|
+
}
|
|
3266
|
+
return out;
|
|
3267
|
+
}
|
|
3268
|
+
case CrateType.Matrix3d: {
|
|
3269
|
+
const out = new Array(count);
|
|
3270
|
+
for (let i = 0; i < count; i++) out[i] = new UsdMatrix(this.readFloat64s(p + i * 72, 9), 3);
|
|
3271
|
+
return out;
|
|
3272
|
+
}
|
|
3273
|
+
case CrateType.Matrix4d: {
|
|
3274
|
+
const out = new Array(count);
|
|
3275
|
+
for (let i = 0; i < count; i++)
|
|
3276
|
+
out[i] = new UsdMatrix(this.readFloat64s(p + i * 128, 16), 4);
|
|
3277
|
+
return out;
|
|
3278
|
+
}
|
|
3279
|
+
default:
|
|
3280
|
+
return void 0;
|
|
3281
|
+
}
|
|
3282
|
+
}
|
|
3283
|
+
/**
|
|
3284
|
+
* Decode an array whose rep has the compressed bit. Int arrays are
|
|
3285
|
+
* integer-compressed; half/float/double arrays (crate 0.6.0+) carry a code
|
|
3286
|
+
* byte — `'i'` when every value is integral, `'t'` for a lookup table +
|
|
3287
|
+
* compressed indexes. Arrays under {@link MIN_COMPRESSED_ARRAY_SIZE} elements
|
|
3288
|
+
* are stored raw even when the bit is set (mirrors pxr's writer).
|
|
3289
|
+
*/
|
|
3290
|
+
readCompressedArray(type, start, count) {
|
|
3291
|
+
let p = start;
|
|
3292
|
+
switch (type) {
|
|
3293
|
+
case CrateType.Int:
|
|
3294
|
+
case CrateType.UInt: {
|
|
3295
|
+
if (count < MIN_COMPRESSED_ARRAY_SIZE) {
|
|
3296
|
+
const out = new Array(count);
|
|
3297
|
+
for (let i = 0; i < count; i++) out[i] = this.view.getInt32(p + i * 4, true);
|
|
3298
|
+
return out;
|
|
3299
|
+
}
|
|
3300
|
+
return this.readCompressedInts(p, count).values;
|
|
3301
|
+
}
|
|
3302
|
+
case CrateType.Half:
|
|
3303
|
+
case CrateType.Float:
|
|
3304
|
+
case CrateType.Double: {
|
|
3305
|
+
const readRaw = (off, n) => type === CrateType.Double ? this.readFloat64s(off, n) : type === CrateType.Float ? this.readFloat32s(off, n) : this.readHalfs(off, n);
|
|
3306
|
+
if (count < MIN_COMPRESSED_ARRAY_SIZE) return readRaw(p, count);
|
|
3307
|
+
const code = this.bytes[p];
|
|
3308
|
+
p += 1;
|
|
3309
|
+
if (code === 105) {
|
|
3310
|
+
return this.readCompressedInts(p, count).values;
|
|
3311
|
+
}
|
|
3312
|
+
if (code === 116) {
|
|
3313
|
+
const lutSize = this.view.getUint32(p, true);
|
|
3314
|
+
p += 4;
|
|
3315
|
+
const lut = readRaw(p, lutSize);
|
|
3316
|
+
p += lutSize * (type === CrateType.Double ? 8 : type === CrateType.Float ? 4 : 2);
|
|
3317
|
+
return this.readCompressedInts(p, count).values.map((i) => lut[i] ?? 0);
|
|
3318
|
+
}
|
|
3319
|
+
return void 0;
|
|
3320
|
+
}
|
|
2571
3321
|
default:
|
|
2572
3322
|
return void 0;
|
|
2573
3323
|
}
|
|
@@ -2582,20 +3332,45 @@ var CrateReader = class {
|
|
|
2582
3332
|
for (let i = 0; i < n; i++) out[i] = this.view.getFloat64(off + i * 8, true);
|
|
2583
3333
|
return out;
|
|
2584
3334
|
}
|
|
2585
|
-
|
|
3335
|
+
readHalfs(off, n) {
|
|
3336
|
+
const out = new Array(n);
|
|
3337
|
+
for (let i = 0; i < n; i++) out[i] = halfToFloat(this.view.getUint16(off + i * 2, true));
|
|
3338
|
+
return out;
|
|
3339
|
+
}
|
|
3340
|
+
readInt32s(off, n) {
|
|
3341
|
+
const out = new Array(n);
|
|
3342
|
+
for (let i = 0; i < n; i++) out[i] = this.view.getInt32(off + i * 4, true);
|
|
3343
|
+
return out;
|
|
3344
|
+
}
|
|
3345
|
+
/** Read `count` fixed-size `n`-tuples (vec2/3/4 of the given element kind). */
|
|
3346
|
+
readTupleArray(off, count, n, kind) {
|
|
3347
|
+
const elemSize = kind === "f64" ? 8 : kind === "f16" ? 2 : 4;
|
|
2586
3348
|
const out = new Array(count);
|
|
2587
|
-
const stride = double ? 24 : 12;
|
|
2588
3349
|
for (let i = 0; i < count; i++) {
|
|
2589
|
-
const o = off + i *
|
|
2590
|
-
out[i] =
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
3350
|
+
const o = off + i * n * elemSize;
|
|
3351
|
+
out[i] = kind === "f64" ? this.readFloat64s(o, n) : kind === "f32" ? this.readFloat32s(o, n) : kind === "f16" ? this.readHalfs(o, n) : this.readInt32s(o, n);
|
|
3352
|
+
}
|
|
3353
|
+
return out;
|
|
3354
|
+
}
|
|
3355
|
+
/**
|
|
3356
|
+
* Read a `VtDictionary`: `[u64 count]`, then per entry a string index (key)
|
|
3357
|
+
* followed by a recursive VtValue — an `int64` offset (relative to its own
|
|
3358
|
+
* position) over the value's data to an 8-byte `ValueRep`.
|
|
3359
|
+
*/
|
|
3360
|
+
readDictionary(off, depth) {
|
|
3361
|
+
const out = {};
|
|
3362
|
+
if (depth > 16) return out;
|
|
3363
|
+
const count = this.u64(off);
|
|
3364
|
+
let p = off + 8;
|
|
3365
|
+
for (let i = 0; i < count; i++) {
|
|
3366
|
+
const key = this.getToken(this.getStrings()[this.view.getUint32(p, true)] ?? 0);
|
|
3367
|
+
p += 4;
|
|
3368
|
+
const repPos = p + Number(this.i64(p));
|
|
3369
|
+
const rep = this.view.getBigUint64(repPos, true);
|
|
3370
|
+
const b = decodeRepBits(rep);
|
|
3371
|
+
const value = b.type === CrateType.Dictionary && !b.isInlined && !b.isArray ? this.readDictionary(Number(b.payload), depth + 1) : this.getValue(rep);
|
|
3372
|
+
if (key && value !== void 0) out[key] = value;
|
|
3373
|
+
p = repPos + 8;
|
|
2599
3374
|
}
|
|
2600
3375
|
return out;
|
|
2601
3376
|
}
|
|
@@ -2750,7 +3525,7 @@ function crateToUsdaFile(crate) {
|
|
|
2750
3525
|
if (spec.specType !== SPEC_PRIM) continue;
|
|
2751
3526
|
const fm = fieldsOf(spec.fieldSetIndex);
|
|
2752
3527
|
primByPath.set(path, {
|
|
2753
|
-
specifier: SPECIFIERS2[
|
|
3528
|
+
specifier: SPECIFIERS2[asNumber3(crate, fm.get("specifier")) ?? 0] ?? "def",
|
|
2754
3529
|
typeName: asString(crate, fm.get("typeName")) ?? "",
|
|
2755
3530
|
name: leaf(path),
|
|
2756
3531
|
metadata: buildPrimMetadata(crate, fm),
|
|
@@ -2798,13 +3573,14 @@ function buildAttribute(crate, name, fm) {
|
|
|
2798
3573
|
const defaultRep = fm.get("default");
|
|
2799
3574
|
const rawType = asString(crate, fm.get("typeName")) ?? "";
|
|
2800
3575
|
const isArrayType = rawType.endsWith("[]");
|
|
3576
|
+
const customRep = fm.get("custom");
|
|
2801
3577
|
const attr = {
|
|
2802
3578
|
kind: "attribute",
|
|
2803
3579
|
name,
|
|
2804
3580
|
typeName: isArrayType ? rawType.slice(0, -2) : rawType,
|
|
2805
3581
|
isArray: isArrayType || (defaultRep !== void 0 ? decodeRepBits(defaultRep).isArray : false),
|
|
2806
|
-
variability:
|
|
2807
|
-
custom:
|
|
3582
|
+
variability: asNumber3(crate, fm.get("variability")) === 1 ? "uniform" : "varying",
|
|
3583
|
+
custom: customRep !== void 0 && crate.getValue(customRep) === true,
|
|
2808
3584
|
metadata: {},
|
|
2809
3585
|
line: 0
|
|
2810
3586
|
};
|
|
@@ -2812,6 +3588,25 @@ function buildAttribute(crate, name, fm) {
|
|
|
2812
3588
|
const value = crate.getValue(defaultRep);
|
|
2813
3589
|
if (value !== void 0) attr.value = value;
|
|
2814
3590
|
}
|
|
3591
|
+
const connections = fm.has("connectionPaths") ? crate.getValue(fm.get("connectionPaths")) : void 0;
|
|
3592
|
+
if (Array.isArray(connections)) {
|
|
3593
|
+
const paths = connections.filter((c) => typeof c === "string" && c.length > 0);
|
|
3594
|
+
if (paths.length > 0) attr.connections = paths;
|
|
3595
|
+
}
|
|
3596
|
+
const interpolation = asString(crate, fm.get("interpolation"));
|
|
3597
|
+
if (interpolation !== void 0) attr.metadata.interpolation = interpolation;
|
|
3598
|
+
const tsRep = fm.get("timeSamples");
|
|
3599
|
+
if (tsRep !== void 0) {
|
|
3600
|
+
const ts = crate.getTimeSamples(tsRep);
|
|
3601
|
+
if (ts) {
|
|
3602
|
+
const samples = /* @__PURE__ */ new Map();
|
|
3603
|
+
const pairs = ts.times.map((t, i) => [t, ts.values[i]]).sort((a, b) => a[0] - b[0]);
|
|
3604
|
+
for (const [t, v] of pairs) {
|
|
3605
|
+
if (v !== void 0) samples.set(t, v);
|
|
3606
|
+
}
|
|
3607
|
+
if (samples.size > 0) attr.timeSamples = samples;
|
|
3608
|
+
}
|
|
3609
|
+
}
|
|
2815
3610
|
return attr;
|
|
2816
3611
|
}
|
|
2817
3612
|
function buildRelationship(crate, name, fm) {
|
|
@@ -2856,8 +3651,16 @@ function buildLayerMetadata(crate, fm) {
|
|
|
2856
3651
|
if (upAxis !== void 0) meta.upAxis = upAxis;
|
|
2857
3652
|
const defaultPrim2 = asString(crate, fm.get("defaultPrim"));
|
|
2858
3653
|
if (defaultPrim2 !== void 0) meta.defaultPrim = defaultPrim2;
|
|
2859
|
-
const metersPerUnit =
|
|
3654
|
+
const metersPerUnit = asNumber3(crate, fm.get("metersPerUnit"));
|
|
2860
3655
|
if (metersPerUnit !== void 0) meta.metersPerUnit = metersPerUnit;
|
|
3656
|
+
for (const key of ["startTimeCode", "endTimeCode", "timeCodesPerSecond", "framesPerSecond"]) {
|
|
3657
|
+
const value = asNumber3(crate, fm.get(key));
|
|
3658
|
+
if (value !== void 0) meta[key] = value;
|
|
3659
|
+
}
|
|
3660
|
+
const customLayerData = fm.has("customLayerData") ? crate.getValue(fm.get("customLayerData")) : void 0;
|
|
3661
|
+
if (customLayerData && typeof customLayerData === "object" && !Array.isArray(customLayerData)) {
|
|
3662
|
+
meta.customLayerData = customLayerData;
|
|
3663
|
+
}
|
|
2861
3664
|
return meta;
|
|
2862
3665
|
}
|
|
2863
3666
|
function asString(crate, rep) {
|
|
@@ -2865,7 +3668,7 @@ function asString(crate, rep) {
|
|
|
2865
3668
|
const v = crate.getValue(rep);
|
|
2866
3669
|
return typeof v === "string" ? v : void 0;
|
|
2867
3670
|
}
|
|
2868
|
-
function
|
|
3671
|
+
function asNumber3(crate, rep) {
|
|
2869
3672
|
if (rep === void 0) return void 0;
|
|
2870
3673
|
const v = crate.getValue(rep);
|
|
2871
3674
|
return typeof v === "number" ? v : void 0;
|
|
@@ -3182,6 +3985,33 @@ function stripKeys(meta, keys) {
|
|
|
3182
3985
|
}
|
|
3183
3986
|
return out;
|
|
3184
3987
|
}
|
|
3988
|
+
|
|
3989
|
+
// src/usd/mdl/loadMdlModules.ts
|
|
3990
|
+
function collectMdlAssetPaths(stage) {
|
|
3991
|
+
const paths = /* @__PURE__ */ new Set();
|
|
3992
|
+
for (const prim of stage.Traverse()) {
|
|
3993
|
+
if (prim.GetTypeName() !== "Shader") continue;
|
|
3994
|
+
const asset = prim.GetAttribute("info:mdl:sourceAsset").Get();
|
|
3995
|
+
if (asset instanceof AssetPath && asset.path) paths.add(asset.path);
|
|
3996
|
+
}
|
|
3997
|
+
return [...paths];
|
|
3998
|
+
}
|
|
3999
|
+
async function loadMdlModules(stage, resolver, baseUrl) {
|
|
4000
|
+
const paths = collectMdlAssetPaths(stage);
|
|
4001
|
+
if (paths.length === 0) return void 0;
|
|
4002
|
+
const modules = /* @__PURE__ */ new Map();
|
|
4003
|
+
await Promise.all(
|
|
4004
|
+
paths.map(async (path) => {
|
|
4005
|
+
try {
|
|
4006
|
+
const module = parseMdl(await resolver.fetchText(resolver.resolve(path, baseUrl)));
|
|
4007
|
+
if (module.materials.size > 0) modules.set(path, module);
|
|
4008
|
+
} catch {
|
|
4009
|
+
}
|
|
4010
|
+
})
|
|
4011
|
+
);
|
|
4012
|
+
if (modules.size === 0) return void 0;
|
|
4013
|
+
return (assetPath) => modules.get(assetPath);
|
|
4014
|
+
}
|
|
3185
4015
|
var USD_ENTRY = /\.(usda|usdc|usd)$/i;
|
|
3186
4016
|
function isZip(bytes) {
|
|
3187
4017
|
if (bytes.length < 4 || bytes[0] !== 80 || bytes[1] !== 75) return false;
|
|
@@ -3218,6 +4048,6 @@ function openUsdz(bytes) {
|
|
|
3218
4048
|
return { rootEntry, resolver };
|
|
3219
4049
|
}
|
|
3220
4050
|
|
|
3221
|
-
export { ARTICULATION_ROOT_API, Attribute, COLLISION_API, CrateReader, DEFAULT_METERS_PER_UNIT, DefaultAssetResolver, Layer, MASS_API, MESH_COLLISION_API, PHYSICS_MATERIAL_API, ParseError, Prim, RIGID_BODY_API, Relationship, Stage, TokenizeError, buildKinematicTree, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, createMemoryResolver, driveKindFor, extractRobotDescription, gatherGprimDescendants, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, getMaterialSubsets, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, isMesh, isNonVisualPurpose, isRenderableGprim, isScope, isSolidGprim, isXform, isZip, iterDescendants, joinPosix, jointValueFromSI, jointValueToSI, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, resolveBoundMaterial, serializeUsda, toBytes, tokenize };
|
|
3222
|
-
//# sourceMappingURL=chunk-
|
|
3223
|
-
//# sourceMappingURL=chunk-
|
|
4051
|
+
export { ARTICULATION_ROOT_API, Attribute, COLLISION_API, CrateReader, DEFAULT_METERS_PER_UNIT, DefaultAssetResolver, Layer, MASS_API, MESH_COLLISION_API, PHYSICS_MATERIAL_API, ParseError, Prim, RIGID_BODY_API, Relationship, Stage, TokenizeError, buildKinematicTree, collectMdlAssetPaths, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, createMemoryResolver, driveKindFor, extractRobotDescription, gatherGprimDescendants, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, getMaterialSubsets, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, isBasisCurves, isMdlTexture, isMesh, isNonVisualPurpose, isPoints, isRenderableGprim, isScope, isSolidGprim, isUnsupportedGprim, isXform, isZip, iterDescendants, joinPosix, jointValueFromSI, jointValueToSI, loadMdlModules, normalizeJointLimits, openUsdz, parseMdl, parseMdlLiteral, parseOpType, parseUsda, refineJointType, resolveBoundMaterial, serializeUsda, toBytes, tokenize };
|
|
4052
|
+
//# sourceMappingURL=chunk-AXPMXEQC.js.map
|
|
4053
|
+
//# sourceMappingURL=chunk-AXPMXEQC.js.map
|