three-usd-robot 0.6.0 → 0.7.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 +35 -5
- package/dist/{ThreeUsdRobot-CajXJqYU.d.ts → ThreeUsdRobot-Ljh4PDVD.d.ts} +1 -1
- package/dist/{ThreeUsdRobotLoader-DrMMLzo-.d.ts → ThreeUsdRobotLoader-BSIVFA48.d.ts} +2 -2
- package/dist/{buildKinematicTree-wtZPzy0B.d.ts → buildKinematicTree-Ccd2DIKH.d.ts} +5 -0
- package/dist/{chunk-4MEZM763.js → chunk-4GPCBXUS.js} +160 -41
- package/dist/chunk-4GPCBXUS.js.map +1 -0
- package/dist/{chunk-YVWSO27W.js → chunk-FL554IS5.js} +61 -10
- package/dist/chunk-FL554IS5.js.map +1 -0
- package/dist/{chunk-JZMCABQO.js → chunk-O7XP5FQ4.js} +102 -31
- package/dist/chunk-O7XP5FQ4.js.map +1 -0
- package/dist/core.d.ts +16 -4
- package/dist/core.js +2 -2
- package/dist/extras.d.ts +2 -2
- package/dist/helpers.d.ts +2 -2
- package/dist/index.d.ts +26 -7
- package/dist/index.js +65 -32
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +4 -4
- package/dist/react.js +2 -2
- package/package.json +6 -2
- package/dist/chunk-4MEZM763.js.map +0 -1
- package/dist/chunk-JZMCABQO.js.map +0 -1
- package/dist/chunk-YVWSO27W.js.map +0 -1
package/README.md
CHANGED
|
@@ -9,6 +9,11 @@ Think of it as a **USD version of [`urdf-loader`](https://www.npmjs.com/package/
|
|
|
9
9
|
it reads the link / joint / xform / mesh structure out of `UsdPhysics` assets
|
|
10
10
|
and drives forward kinematics on a Three.js `Object3D` hierarchy.
|
|
11
11
|
|
|
12
|
+
**[▶ Live demo](https://three-usd-robot.vercel.app)** — stock Isaac Sim robots
|
|
13
|
+
streamed from NVIDIA's asset CDN, joints driven from a slider panel, and
|
|
14
|
+
exported back to `.usda` / `.usdz` in the browser.
|
|
15
|
+
|
|
16
|
+

|
|
12
17
|

|
|
13
18
|
|
|
14
19
|
## Features
|
|
@@ -25,8 +30,26 @@ and drives forward kinematics on a Three.js `Object3D` hierarchy.
|
|
|
25
30
|
simulation-ready for Isaac Sim.
|
|
26
31
|
- **React** — declarative `<UsdRobot>` for React Three Fiber.
|
|
27
32
|
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
Stock Isaac Sim robot assets load straight from their public CDN — Franka
|
|
34
|
+
Panda, UR10e, Fanuc CRX-10iA/L, Kuka KR210, Shadow Hand, Unitree H1/Go2 and
|
|
35
|
+
friends all compose from their variant-driven, multi-layer form:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
const ROOT = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1";
|
|
39
|
+
const franka = await new ThreeUsdRobotLoader()
|
|
40
|
+
.loadAsync(`${ROOT}/Isaac/Robots/FrankaRobotics/FrankaPanda/franka.usd`);
|
|
41
|
+
|
|
42
|
+
franka.setJointValues({ panda_joint2: -0.785, panda_joint4: -2.356, panda_joint6: 1.571 });
|
|
43
|
+
franka.getLinkWorldPosition("panda_hand"); // (0.307, 0, 0.590) — the documented ready pose
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The CDN is public and CORS-enabled, so this works in the browser too. Try
|
|
47
|
+
`npx tsx scripts/demo-franka.ts` for a console walkthrough (articulation table,
|
|
48
|
+
FK check, and a re-export to one self-contained file), or open the Vite example
|
|
49
|
+
and pick a robot from the preset list.
|
|
50
|
+
|
|
51
|
+
Not yet supported: time samples stored inside binary crate files, non-mesh
|
|
52
|
+
gprims (`Cube`, `Sphere`, …), and full material/shader fidelity.
|
|
30
53
|
|
|
31
54
|
## Install
|
|
32
55
|
|
|
@@ -198,9 +221,16 @@ and `.usdz` packages to ASCII USDA.
|
|
|
198
221
|
|
|
199
222
|
## Examples
|
|
200
223
|
|
|
201
|
-
[`examples/`](./examples) holds runnable Vite demos
|
|
202
|
-
|
|
203
|
-
|
|
224
|
+
[`examples/`](./examples) holds runnable Vite demos:
|
|
225
|
+
|
|
226
|
+
- **`vite-joint-slider`** — the [live demo](https://three-usd-robot.vercel.app):
|
|
227
|
+
vanilla Three.js + `lil-gui`, with a robot picker, joint sliders, animation
|
|
228
|
+
playback and USD export.
|
|
229
|
+
- **`vite-basic-viewer`** — the same thing through React Three Fiber.
|
|
230
|
+
|
|
231
|
+
Both take `?asset=<url>` for any asset, or `?isaac=<path under Isaac/>` to pull
|
|
232
|
+
one straight from NVIDIA's CDN. `npm run demo:build` generates the factory cell
|
|
233
|
+
and builds the deployable site.
|
|
204
234
|
|
|
205
235
|
## Package entry points
|
|
206
236
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
|
-
import { J as JointType, A as Axis, a as JointDescription, L as LinkDescription, R as RobotDescription, K as KinematicTree } from './buildKinematicTree-
|
|
2
|
+
import { J as JointType, A as Axis, a as JointDescription, L as LinkDescription, R as RobotDescription, K as KinematicTree } from './buildKinematicTree-Ccd2DIKH.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* The articulated "motion" node of a joint, inserted between the joint's two
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { R as RobotDescription } from './buildKinematicTree-
|
|
1
|
+
import { R as RobotDescription } from './buildKinematicTree-Ccd2DIKH.js';
|
|
2
2
|
import { A as AssetResolver } from './AssetResolver-CpIJNgWZ.js';
|
|
3
|
-
import { T as ThreeUsdRobot } from './ThreeUsdRobot-
|
|
3
|
+
import { T as ThreeUsdRobot } from './ThreeUsdRobot-Ljh4PDVD.js';
|
|
4
4
|
|
|
5
5
|
type ThreeUsdRobotLoaderOptions = {
|
|
6
6
|
/** Resolver for references / payloads / sublayers (default {@link DefaultAssetResolver}). */
|
|
@@ -89,6 +89,11 @@ type PrimSpec = {
|
|
|
89
89
|
type VariantContent = {
|
|
90
90
|
properties: PropertySpec[];
|
|
91
91
|
children: PrimSpec[];
|
|
92
|
+
/**
|
|
93
|
+
* Metadata authored on the variant itself. Composition arcs live here — the
|
|
94
|
+
* common "this variant references another layer" pattern in Isaac Sim assets.
|
|
95
|
+
*/
|
|
96
|
+
metadata: MetadataMap;
|
|
92
97
|
};
|
|
93
98
|
/** `variantSetName → variantName → content`. */
|
|
94
99
|
type VariantSetMap = {
|
|
@@ -394,6 +394,24 @@ function isNonVisualPurpose(prim) {
|
|
|
394
394
|
const p = getPurpose(prim);
|
|
395
395
|
return p === "guide" || p === "proxy";
|
|
396
396
|
}
|
|
397
|
+
function getMaterialSubsets(meshPrim) {
|
|
398
|
+
const out = [];
|
|
399
|
+
for (const child of meshPrim.GetChildren()) {
|
|
400
|
+
if (child.GetTypeName() !== "GeomSubset") continue;
|
|
401
|
+
const elementType = child.GetAttribute("elementType").Get();
|
|
402
|
+
if (elementType !== void 0 && elementType !== "face") continue;
|
|
403
|
+
const family = child.GetAttribute("familyName").Get();
|
|
404
|
+
if (family !== void 0 && family !== "materialBind") continue;
|
|
405
|
+
const indices = child.GetAttribute("indices").Get();
|
|
406
|
+
if (!Array.isArray(indices)) continue;
|
|
407
|
+
const faces = [];
|
|
408
|
+
for (const i of indices) {
|
|
409
|
+
if (typeof i === "number") faces.push(i);
|
|
410
|
+
}
|
|
411
|
+
if (faces.length > 0) out.push({ prim: child, faces });
|
|
412
|
+
}
|
|
413
|
+
return out;
|
|
414
|
+
}
|
|
397
415
|
function* iterDescendants(prim) {
|
|
398
416
|
for (const child of prim.GetChildren()) {
|
|
399
417
|
yield child;
|
|
@@ -549,9 +567,7 @@ function computeLocalTransform(prim) {
|
|
|
549
567
|
opName = opName.slice(INVERT_PREFIX.length);
|
|
550
568
|
}
|
|
551
569
|
const attr = prim.GetAttribute(opName);
|
|
552
|
-
if (!attr.IsValid())
|
|
553
|
-
throw new Error(`${prim.GetPath()}: xformOpOrder references missing op "${opName}"`);
|
|
554
|
-
}
|
|
570
|
+
if (!attr.IsValid()) continue;
|
|
555
571
|
const opValue = attr.Get();
|
|
556
572
|
if (opValue === void 0) continue;
|
|
557
573
|
let opMatrix = opMatrixFor(parseOpType(opName), opValue, `${prim.GetPath()}.${opName}`);
|
|
@@ -660,7 +676,7 @@ function resolveBoundMaterial(stage, prim) {
|
|
|
660
676
|
if (!material) return void 0;
|
|
661
677
|
const shader = findSurfaceShader(material);
|
|
662
678
|
if (!shader) return void 0;
|
|
663
|
-
const result = {};
|
|
679
|
+
const result = { name: material.GetName() };
|
|
664
680
|
const color = firstColor(shader, DIFFUSE_INPUTS);
|
|
665
681
|
if (color) result.color = color;
|
|
666
682
|
const opacity = firstNumber(shader, OPACITY_INPUTS);
|
|
@@ -994,8 +1010,10 @@ function buildLink(path, prim) {
|
|
|
994
1010
|
const collisionPrims = [];
|
|
995
1011
|
for (const meshPath of gatherMeshDescendants(prim)) {
|
|
996
1012
|
const mp = prim.GetStage().GetPrimAtPath(meshPath);
|
|
997
|
-
if (mp
|
|
998
|
-
|
|
1013
|
+
if (!mp) continue;
|
|
1014
|
+
const nonVisual = isNonVisualPurpose(mp);
|
|
1015
|
+
if (!nonVisual) visualPrims.push(meshPath);
|
|
1016
|
+
if (nonVisual || hasCollisionAPI(mp)) collisionPrims.push(meshPath);
|
|
999
1017
|
}
|
|
1000
1018
|
const inertial = getMassProperties(prim);
|
|
1001
1019
|
const worldTransform = computeWorldTransform(prim);
|
|
@@ -1631,11 +1649,11 @@ function parseVariantSet(r) {
|
|
|
1631
1649
|
const variants = {};
|
|
1632
1650
|
while (!r.is("rbrace") && !r.atEnd()) {
|
|
1633
1651
|
const variantName = r.expect("string").value;
|
|
1634
|
-
|
|
1652
|
+
const metadata = r.is("lparen") ? parseMetadataBlock(r) : {};
|
|
1635
1653
|
r.expect("lbrace");
|
|
1636
1654
|
const body = parseBody(r);
|
|
1637
1655
|
r.expect("rbrace");
|
|
1638
|
-
variants[variantName] = { properties: body.properties, children: body.children };
|
|
1656
|
+
variants[variantName] = { properties: body.properties, children: body.children, metadata };
|
|
1639
1657
|
}
|
|
1640
1658
|
r.expect("rbrace");
|
|
1641
1659
|
return { setName, variants };
|
|
@@ -1845,7 +1863,13 @@ function pushPrimBody(out, properties, children, variantSets, level) {
|
|
|
1845
1863
|
for (const [setName, variants] of Object.entries(variantSets)) {
|
|
1846
1864
|
out.push(`${pad}variantSet ${quoteString(setName)} = {`);
|
|
1847
1865
|
for (const [variantName, content] of Object.entries(variants)) {
|
|
1848
|
-
|
|
1866
|
+
const head = `${pad}${INDENT}${quoteString(variantName)}`;
|
|
1867
|
+
if (Object.keys(content.metadata).length > 0) {
|
|
1868
|
+
pushWithMetadata(out, head, content.metadata, level + 1);
|
|
1869
|
+
out.push(`${pad}${INDENT}{`);
|
|
1870
|
+
} else {
|
|
1871
|
+
out.push(`${head} {`);
|
|
1872
|
+
}
|
|
1849
1873
|
pushPrimBody(out, content.properties, content.children, void 0, level + 2);
|
|
1850
1874
|
out.push(`${pad}${INDENT}}`);
|
|
1851
1875
|
}
|
|
@@ -2510,6 +2534,8 @@ var CrateType = {
|
|
|
2510
2534
|
Specifier: 42,
|
|
2511
2535
|
Permission: 43,
|
|
2512
2536
|
Variability: 44,
|
|
2537
|
+
VariantSelectionMap: 45,
|
|
2538
|
+
StringVector: 50,
|
|
2513
2539
|
PayloadListOp: 55};
|
|
2514
2540
|
var ListOpBits = {
|
|
2515
2541
|
HasExplicit: 1 << 1,
|
|
@@ -2865,6 +2891,10 @@ var CrateReader = class {
|
|
|
2865
2891
|
return this.readIndexVector(off, "token").items;
|
|
2866
2892
|
case CrateType.PathVector:
|
|
2867
2893
|
return this.readIndexVector(off, "path").items;
|
|
2894
|
+
case CrateType.StringVector:
|
|
2895
|
+
return this.readIndexVector(off, "string").items;
|
|
2896
|
+
case CrateType.VariantSelectionMap:
|
|
2897
|
+
return this.readVariantSelectionMap(off);
|
|
2868
2898
|
default:
|
|
2869
2899
|
return void 0;
|
|
2870
2900
|
}
|
|
@@ -2931,6 +2961,24 @@ var CrateReader = class {
|
|
|
2931
2961
|
}
|
|
2932
2962
|
return out;
|
|
2933
2963
|
}
|
|
2964
|
+
/**
|
|
2965
|
+
* Read an `SdfVariantSelectionMap`: `[u64 count]` then `count` pairs of
|
|
2966
|
+
* string indexes (`variantSetName → variantName`). Surfaces as a dictionary
|
|
2967
|
+
* so it maps straight onto the USDA `variants = { ... }` metadatum.
|
|
2968
|
+
*/
|
|
2969
|
+
readVariantSelectionMap(off) {
|
|
2970
|
+
const count = this.u64(off);
|
|
2971
|
+
const strings = this.getStrings();
|
|
2972
|
+
const out = {};
|
|
2973
|
+
let p = off + 8;
|
|
2974
|
+
for (let i = 0; i < count; i++) {
|
|
2975
|
+
const key = this.getToken(strings[this.view.getUint32(p, true)] ?? 0);
|
|
2976
|
+
const value = this.getToken(strings[this.view.getUint32(p + 4, true)] ?? 0);
|
|
2977
|
+
if (key) out[key] = value;
|
|
2978
|
+
p += 8;
|
|
2979
|
+
}
|
|
2980
|
+
return out;
|
|
2981
|
+
}
|
|
2934
2982
|
/** Read a `[u64 count][count × uint32|int32 index]` vector → resolved strings. */
|
|
2935
2983
|
readIndexVector(off, kind) {
|
|
2936
2984
|
const count = this.u64(off);
|
|
@@ -2938,7 +2986,7 @@ var CrateReader = class {
|
|
|
2938
2986
|
const items = new Array(count);
|
|
2939
2987
|
for (let i = 0; i < count; i++) {
|
|
2940
2988
|
const idx = this.view.getInt32(p, true);
|
|
2941
|
-
items[i] = kind === "token" ? this.getToken(idx) : this.getPaths()[idx] ?? "";
|
|
2989
|
+
items[i] = kind === "token" ? this.getToken(idx) : kind === "string" ? this.getToken(this.getStrings()[idx] ?? 0) : this.getPaths()[idx] ?? "";
|
|
2942
2990
|
p += 4;
|
|
2943
2991
|
}
|
|
2944
2992
|
return { items, next: p };
|
|
@@ -3020,6 +3068,7 @@ var SPEC_PRIM = 6;
|
|
|
3020
3068
|
var SPEC_PSEUDO_ROOT = 7;
|
|
3021
3069
|
var SPEC_ATTRIBUTE = 1;
|
|
3022
3070
|
var SPEC_RELATIONSHIP = 8;
|
|
3071
|
+
var SPEC_VARIANT = 10;
|
|
3023
3072
|
var SPECIFIERS2 = ["def", "over", "class"];
|
|
3024
3073
|
function crateToUsdaFile(crate) {
|
|
3025
3074
|
const paths = crate.getPaths();
|
|
@@ -3034,8 +3083,26 @@ function crateToUsdaFile(crate) {
|
|
|
3034
3083
|
return map;
|
|
3035
3084
|
};
|
|
3036
3085
|
const primByPath = /* @__PURE__ */ new Map();
|
|
3086
|
+
const variantByPath = /* @__PURE__ */ new Map();
|
|
3037
3087
|
const rootPrims = [];
|
|
3038
3088
|
let layerMetadata = {};
|
|
3089
|
+
const containerAt = (path) => {
|
|
3090
|
+
const prim = primByPath.get(path);
|
|
3091
|
+
if (prim) return prim;
|
|
3092
|
+
const cached = variantByPath.get(path);
|
|
3093
|
+
if (cached) return cached;
|
|
3094
|
+
const selection = variantNode(path);
|
|
3095
|
+
if (!selection) return void 0;
|
|
3096
|
+
const owner = primByPath.get(selection.owner);
|
|
3097
|
+
if (!owner) return void 0;
|
|
3098
|
+
owner.variantSets ??= {};
|
|
3099
|
+
owner.variantSets[selection.setName] ??= {};
|
|
3100
|
+
const set = owner.variantSets[selection.setName];
|
|
3101
|
+
set[selection.variantName] ??= { properties: [], children: [], metadata: {} };
|
|
3102
|
+
const content = set[selection.variantName];
|
|
3103
|
+
variantByPath.set(path, content);
|
|
3104
|
+
return content;
|
|
3105
|
+
};
|
|
3039
3106
|
for (const spec of specs) {
|
|
3040
3107
|
const path = paths[spec.pathIndex] ?? "";
|
|
3041
3108
|
if (spec.specType === SPEC_PSEUDO_ROOT) {
|
|
@@ -3054,24 +3121,41 @@ function crateToUsdaFile(crate) {
|
|
|
3054
3121
|
line: 0
|
|
3055
3122
|
});
|
|
3056
3123
|
}
|
|
3124
|
+
for (const spec of specs) {
|
|
3125
|
+
if (spec.specType !== SPEC_VARIANT) continue;
|
|
3126
|
+
const content = containerAt(paths[spec.pathIndex] ?? "");
|
|
3127
|
+
if (content)
|
|
3128
|
+
Object.assign(content.metadata, buildPrimMetadata(crate, fieldsOf(spec.fieldSetIndex)));
|
|
3129
|
+
}
|
|
3057
3130
|
for (const spec of specs) {
|
|
3058
3131
|
if (spec.specType !== SPEC_ATTRIBUTE && spec.specType !== SPEC_RELATIONSHIP) continue;
|
|
3059
3132
|
const split = splitProperty(paths[spec.pathIndex] ?? "");
|
|
3060
3133
|
if (!split) continue;
|
|
3061
|
-
const
|
|
3062
|
-
if (!
|
|
3134
|
+
const owner = containerAt(split.primPath);
|
|
3135
|
+
if (!owner) continue;
|
|
3063
3136
|
const fm = fieldsOf(spec.fieldSetIndex);
|
|
3064
|
-
|
|
3137
|
+
owner.properties.push(
|
|
3065
3138
|
spec.specType === SPEC_ATTRIBUTE ? buildAttribute(crate, split.propName, fm) : buildRelationship(crate, split.propName, fm)
|
|
3066
3139
|
);
|
|
3067
3140
|
}
|
|
3068
3141
|
for (const [path, prim] of primByPath) {
|
|
3069
3142
|
const parentPath = parentOf(path);
|
|
3070
3143
|
if (parentPath === "/") rootPrims.push(prim);
|
|
3071
|
-
else
|
|
3144
|
+
else containerAt(parentPath)?.children.push(prim);
|
|
3072
3145
|
}
|
|
3073
3146
|
return { version: crate.version.join("."), metadata: layerMetadata, prims: rootPrims };
|
|
3074
3147
|
}
|
|
3148
|
+
function variantNode(path) {
|
|
3149
|
+
if (!path.endsWith("}")) return null;
|
|
3150
|
+
const open = path.lastIndexOf("{");
|
|
3151
|
+
if (open < 0) return null;
|
|
3152
|
+
const selection = path.slice(open + 1, -1);
|
|
3153
|
+
const eq = selection.indexOf("=");
|
|
3154
|
+
if (eq < 0) return null;
|
|
3155
|
+
const variantName = selection.slice(eq + 1);
|
|
3156
|
+
if (variantName === "") return null;
|
|
3157
|
+
return { owner: path.slice(0, open), setName: selection.slice(0, eq), variantName };
|
|
3158
|
+
}
|
|
3075
3159
|
function buildAttribute(crate, name, fm) {
|
|
3076
3160
|
const defaultRep = fm.get("default");
|
|
3077
3161
|
const rawType = asString(crate, fm.get("typeName")) ?? "";
|
|
@@ -3112,6 +3196,10 @@ function buildPrimMetadata(crate, fm) {
|
|
|
3112
3196
|
if (Array.isArray(apiSchemas)) meta.apiSchemas = apiSchemas;
|
|
3113
3197
|
const kind = asString(crate, fm.get("kind"));
|
|
3114
3198
|
if (kind !== void 0) meta.kind = kind;
|
|
3199
|
+
const variants = fm.has("variantSelection") ? crate.getValue(fm.get("variantSelection")) : void 0;
|
|
3200
|
+
if (variants && typeof variants === "object" && !Array.isArray(variants)) {
|
|
3201
|
+
meta.variants = variants;
|
|
3202
|
+
}
|
|
3115
3203
|
for (const key of ARC_FIELDS) {
|
|
3116
3204
|
if (!fm.has(key)) continue;
|
|
3117
3205
|
const arcs = crate.getValue(fm.get(key));
|
|
@@ -3121,6 +3209,11 @@ function buildPrimMetadata(crate, fm) {
|
|
|
3121
3209
|
}
|
|
3122
3210
|
function buildLayerMetadata(crate, fm) {
|
|
3123
3211
|
const meta = {};
|
|
3212
|
+
const subLayers = fm.has("subLayers") ? crate.getValue(fm.get("subLayers")) : void 0;
|
|
3213
|
+
if (Array.isArray(subLayers)) {
|
|
3214
|
+
const paths = subLayers.filter((s) => typeof s === "string" && s.length > 0);
|
|
3215
|
+
if (paths.length > 0) meta.subLayers = paths.map((p) => new AssetPath(p));
|
|
3216
|
+
}
|
|
3124
3217
|
const upAxis = asString(crate, fm.get("upAxis"));
|
|
3125
3218
|
if (upAxis !== void 0) meta.upAxis = upAxis;
|
|
3126
3219
|
const defaultPrim2 = asString(crate, fm.get("defaultPrim"));
|
|
@@ -3157,16 +3250,24 @@ function leaf(path) {
|
|
|
3157
3250
|
// src/usd/composition.ts
|
|
3158
3251
|
var ARC_KEYS = ["references", "payload", "payloads", "inherits", "specializes"];
|
|
3159
3252
|
var STRIP_KEYS = [...ARC_KEYS, "variants", "variantSets"];
|
|
3160
|
-
async function composeLayer(text, baseUrl, resolver, options = {}, stack = /* @__PURE__ */ new Set()) {
|
|
3161
|
-
return composeFile(parseUsda(text), baseUrl, resolver, options, stack);
|
|
3253
|
+
async function composeLayer(text, baseUrl, resolver, options = {}, stack = /* @__PURE__ */ new Set(), cache = /* @__PURE__ */ new Map()) {
|
|
3254
|
+
return composeFile(parseUsda(text), baseUrl, resolver, options, stack, cache);
|
|
3162
3255
|
}
|
|
3163
|
-
async function composeFile(file, baseUrl, resolver, options = {}, stack = /* @__PURE__ */ new Set()) {
|
|
3256
|
+
async function composeFile(file, baseUrl, resolver, options = {}, stack = /* @__PURE__ */ new Set(), cache = /* @__PURE__ */ new Map()) {
|
|
3164
3257
|
const warn = options.onWarn ?? (() => {
|
|
3165
3258
|
});
|
|
3166
3259
|
let weak = [];
|
|
3167
3260
|
const subLayers = toArcs(file.metadata.subLayers);
|
|
3168
3261
|
for (let i = subLayers.length - 1; i >= 0; i--) {
|
|
3169
|
-
const sub = await loadExternalFile(
|
|
3262
|
+
const sub = await loadExternalFile(
|
|
3263
|
+
subLayers[i],
|
|
3264
|
+
baseUrl,
|
|
3265
|
+
resolver,
|
|
3266
|
+
options,
|
|
3267
|
+
stack,
|
|
3268
|
+
warn,
|
|
3269
|
+
cache
|
|
3270
|
+
);
|
|
3170
3271
|
if (sub) weak = mergePrimLists(weak, sub.prims);
|
|
3171
3272
|
}
|
|
3172
3273
|
const ctx = {
|
|
@@ -3176,7 +3277,8 @@ async function composeFile(file, baseUrl, resolver, options = {}, stack = /* @__
|
|
|
3176
3277
|
warn,
|
|
3177
3278
|
stack,
|
|
3178
3279
|
index: buildPathIndex(file.prims),
|
|
3179
|
-
resolving: /* @__PURE__ */ new Set()
|
|
3280
|
+
resolving: /* @__PURE__ */ new Set(),
|
|
3281
|
+
cache
|
|
3180
3282
|
};
|
|
3181
3283
|
const resolved = [];
|
|
3182
3284
|
for (const prim of file.prims) resolved.push(await resolvePrim(prim, "", ctx));
|
|
@@ -3187,6 +3289,7 @@ async function resolvePrim(spec, parentPath, ctx) {
|
|
|
3187
3289
|
const path = `${parentPath}/${spec.name}`;
|
|
3188
3290
|
let properties = spec.properties;
|
|
3189
3291
|
let children = spec.children;
|
|
3292
|
+
const variantArcs = [];
|
|
3190
3293
|
const selection = spec.metadata.variants;
|
|
3191
3294
|
if (spec.variantSets && isDictionary2(selection)) {
|
|
3192
3295
|
for (const [setName, variantName] of Object.entries(selection)) {
|
|
@@ -3194,6 +3297,7 @@ async function resolvePrim(spec, parentPath, ctx) {
|
|
|
3194
3297
|
if (!variant) continue;
|
|
3195
3298
|
properties = mergeProperties(variant.properties, properties);
|
|
3196
3299
|
children = mergePrimLists(variant.children, children);
|
|
3300
|
+
for (const key of ARC_KEYS) variantArcs.push(...toArcs(variant.metadata[key]));
|
|
3197
3301
|
}
|
|
3198
3302
|
}
|
|
3199
3303
|
const resolvedChildren = [];
|
|
@@ -3207,7 +3311,7 @@ async function resolvePrim(spec, parentPath, ctx) {
|
|
|
3207
3311
|
children: resolvedChildren,
|
|
3208
3312
|
line: spec.line
|
|
3209
3313
|
};
|
|
3210
|
-
const arcs = ARC_KEYS.flatMap((k) => toArcs(spec.metadata[k]));
|
|
3314
|
+
const arcs = [...variantArcs, ...ARC_KEYS.flatMap((k) => toArcs(spec.metadata[k]))];
|
|
3211
3315
|
let base = null;
|
|
3212
3316
|
for (const arc of arcs) {
|
|
3213
3317
|
const target = await loadReferencedPrim(arc, ctx, path);
|
|
@@ -3216,20 +3320,21 @@ async function resolvePrim(spec, parentPath, ctx) {
|
|
|
3216
3320
|
return base ? mergePrim(base, local) : local;
|
|
3217
3321
|
}
|
|
3218
3322
|
async function loadReferencedPrim(arc, ctx, destPath) {
|
|
3219
|
-
if (arc.assetPath) {
|
|
3323
|
+
if (arc.assetPath?.path) {
|
|
3220
3324
|
const composed = await loadExternalFile(
|
|
3221
3325
|
arc,
|
|
3222
3326
|
ctx.baseUrl,
|
|
3223
3327
|
ctx.resolver,
|
|
3224
3328
|
ctx.options,
|
|
3225
3329
|
ctx.stack,
|
|
3226
|
-
ctx.warn
|
|
3330
|
+
ctx.warn,
|
|
3331
|
+
ctx.cache
|
|
3227
3332
|
);
|
|
3228
3333
|
if (!composed) return null;
|
|
3229
3334
|
const target = arc.primPath ? findPrimByPath(composed, arc.primPath) : defaultPrim(composed, ctx.warn);
|
|
3230
3335
|
if (!target) {
|
|
3231
3336
|
ctx.warn(
|
|
3232
|
-
`reference target ${arc.primPath ?? "(defaultPrim)"} not found in ${arc.assetPath
|
|
3337
|
+
`reference target ${arc.primPath ?? "(defaultPrim)"} not found in ${arc.assetPath?.path}`
|
|
3233
3338
|
);
|
|
3234
3339
|
return null;
|
|
3235
3340
|
}
|
|
@@ -3255,9 +3360,10 @@ async function loadReferencedPrim(arc, ctx, destPath) {
|
|
|
3255
3360
|
}
|
|
3256
3361
|
return null;
|
|
3257
3362
|
}
|
|
3258
|
-
async function loadExternalFile(arc, baseUrl, resolver, options, stack, warn) {
|
|
3259
|
-
if (!arc.assetPath) return null;
|
|
3260
|
-
const
|
|
3363
|
+
async function loadExternalFile(arc, baseUrl, resolver, options, stack, warn, cache) {
|
|
3364
|
+
if (!arc.assetPath?.path) return null;
|
|
3365
|
+
const assetPath = arc.assetPath.path;
|
|
3366
|
+
const url = resolver.resolve(assetPath, baseUrl);
|
|
3261
3367
|
if (stack.has(url)) {
|
|
3262
3368
|
warn(`composition cycle detected at ${url}; skipping`);
|
|
3263
3369
|
return null;
|
|
@@ -3266,18 +3372,31 @@ async function loadExternalFile(arc, baseUrl, resolver, options, stack, warn) {
|
|
|
3266
3372
|
warn(`composition exceeded max depth at ${url}; skipping`);
|
|
3267
3373
|
return null;
|
|
3268
3374
|
}
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3375
|
+
const cached = cache.get(url);
|
|
3376
|
+
if (cached) return cached;
|
|
3377
|
+
const pending = (async () => {
|
|
3378
|
+
let bytes;
|
|
3379
|
+
try {
|
|
3380
|
+
bytes = await fetchLayerBytes(resolver, url);
|
|
3381
|
+
} catch (err) {
|
|
3382
|
+
warn(`cannot resolve "${assetPath}" -> ${url}: ${err.message}`);
|
|
3383
|
+
return null;
|
|
3384
|
+
}
|
|
3385
|
+
const childStack = /* @__PURE__ */ new Set([...stack, url]);
|
|
3386
|
+
if (CrateReader.isCrate(bytes)) {
|
|
3387
|
+
return composeFile(
|
|
3388
|
+
crateToUsdaFile(new CrateReader(bytes)),
|
|
3389
|
+
url,
|
|
3390
|
+
resolver,
|
|
3391
|
+
options,
|
|
3392
|
+
childStack,
|
|
3393
|
+
cache
|
|
3394
|
+
);
|
|
3395
|
+
}
|
|
3396
|
+
return composeLayer(new TextDecoder().decode(bytes), url, resolver, options, childStack, cache);
|
|
3397
|
+
})();
|
|
3398
|
+
cache.set(url, pending);
|
|
3399
|
+
return pending;
|
|
3281
3400
|
}
|
|
3282
3401
|
async function fetchLayerBytes(resolver, url) {
|
|
3283
3402
|
if (resolver.fetchBytes) return resolver.fetchBytes(url);
|
|
@@ -3455,6 +3574,6 @@ function openUsdz(bytes) {
|
|
|
3455
3574
|
return { rootEntry, resolver };
|
|
3456
3575
|
}
|
|
3457
3576
|
|
|
3458
|
-
export { ARTICULATION_ROOT_API, AssetPath, Attribute, COLLISION_API, CrateReader, DEFAULT_METERS_PER_UNIT, DEG2RAD, DefaultAssetResolver, Layer, MASS_API, MESH_COLLISION_API, PHYSICS_MATERIAL_API, ParseError, Prim, Quat, RAD2DEG, RIGID_BODY_API, Relationship, Stage, TokenizeError, UsdMatrix, buildKinematicTree, channelFromSamples, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, createMemoryResolver, decomposeRigid, driveKindFor, extractRobotDescription, fromUsdMatrix, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, getTranslation, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, identity4, interpolate, invert, isMesh, isNonVisualPurpose, isScope, isXform, iterDescendants, joinPosix, jointValueFromSI, jointValueToSI, makeEuler, makeRotationFromQuat, makeRotationX, makeRotationY, makeRotationZ, makeScale, makeTranslation, multiply, multiplyAll, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, resolveBoundMaterial, serializeUsda, toUsdMatrix, tokenize };
|
|
3459
|
-
//# sourceMappingURL=chunk-
|
|
3460
|
-
//# sourceMappingURL=chunk-
|
|
3577
|
+
export { ARTICULATION_ROOT_API, AssetPath, Attribute, COLLISION_API, CrateReader, DEFAULT_METERS_PER_UNIT, DEG2RAD, DefaultAssetResolver, Layer, MASS_API, MESH_COLLISION_API, PHYSICS_MATERIAL_API, ParseError, Prim, Quat, RAD2DEG, RIGID_BODY_API, Relationship, Stage, TokenizeError, UsdMatrix, buildKinematicTree, channelFromSamples, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, createMemoryResolver, decomposeRigid, driveKindFor, extractRobotDescription, fromUsdMatrix, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, getMaterialSubsets, getTranslation, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, identity4, interpolate, invert, isMesh, isNonVisualPurpose, isScope, isXform, iterDescendants, joinPosix, jointValueFromSI, jointValueToSI, makeEuler, makeRotationFromQuat, makeRotationX, makeRotationY, makeRotationZ, makeScale, makeTranslation, multiply, multiplyAll, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, resolveBoundMaterial, serializeUsda, toUsdMatrix, tokenize };
|
|
3578
|
+
//# sourceMappingURL=chunk-4GPCBXUS.js.map
|
|
3579
|
+
//# sourceMappingURL=chunk-4GPCBXUS.js.map
|