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 CHANGED
@@ -23,11 +23,16 @@ exported back to `.usda` / `.usdz` in the browser.
23
23
  instanceable prims are composed for you.
24
24
  - **Robots** — links, joints (fixed / revolute / continuous / prismatic), limits,
25
25
  drives and the initial pose become a `setJointValue`-able hierarchy.
26
- - **Rendering** — meshes and solid gprims (`Cube` / `Sphere` / `Cylinder` /
27
- `Capsule` / `Cone`) with `UsdShade` materials (UsdPreviewSurface / OmniPBR)
28
- and textures; up-axis and units normalized automatically. Articulation-free
29
- stages load as static scenes.
30
- - **Animation** plays back time-sampled joint trajectories.
26
+ - **Rendering** — meshes, solid gprims (`Cube` / `Sphere` / `Cylinder` /
27
+ `Capsule` / `Cone`), point clouds (`Points`) and curves (`BasisCurves`:
28
+ linear / bezier / bspline / catmullRom, periodic wrap, and an opt-in
29
+ `curveTubes` mode that turns authored widths into tube meshes) with
30
+ `UsdShade` materials (UsdPreviewSurface / Omniverse MDL) and textures; up-axis
31
+ and units normalized automatically. Articulation-free stages load as
32
+ static scenes.
33
+ - **Animation** — plays back time-sampled joint trajectories, and replays
34
+ baked body-transform recordings through `setLinkTransforms` with
35
+ constraint diagnostics.
31
36
  - **Export** — write robots and whole cells back to `.usda` / `.usdz`,
32
37
  simulation-ready for Isaac Sim.
33
38
  - **React** — declarative `<UsdRobot>` for React Three Fiber.
@@ -50,8 +55,30 @@ The CDN is public and CORS-enabled, so this works in the browser too. Try
50
55
  FK check, and a re-export to one self-contained file), or open the Vite example
51
56
  and pick a robot from the preset list.
52
57
 
53
- Not yet supported: time samples stored inside binary crate files, point/curve
54
- gprims (`Points`, `BasisCurves`, …), and full material/shader fidelity.
58
+ Materials target **UsdPreviewSurface fidelity plus an Omniverse MDL mapping**:
59
+ constant and textured inputs, faceVarying / indexed UVs, multiple UV sets,
60
+ per-vertex display colors, physical extensions (`ior` / `clearcoat` /
61
+ specular workflow → `MeshPhysicalMaterial`), packed ORM maps,
62
+ `sourceColorSpace`, and purpose/strength-aware bindings. MDL shaders are
63
+ identified by `info:mdl:sourceAsset` and mapped **by family** — no shader
64
+ execution — and referenced `.mdl` modules are fetched and parsed for their
65
+ declaration values, so wrapper materials
66
+ (`export material X(*) = OmniPBR(…)`) render correctly even when the USD
67
+ shader authors no inputs at all. Value priority: authored USD inputs >
68
+ wrapper arguments > declaration defaults.
69
+
70
+ | MDL family | three.js mapping |
71
+ | --- | --- |
72
+ | `OmniPBR` (and derivatives, e.g. `OmniPBR_Opacity`) | color / metalness / roughness / emissive (`emissive_intensity`), per-channel texture maps and packed `ORM_texture`, opacity, normal map, `texture_translate/rotate/scale` |
73
+ | `OmniPBR_ClearCoat` | the OmniPBR mapping plus `clearcoat` / `clearcoatRoughness` / `clearcoatNormalMap` |
74
+ | `OmniGlass` | `MeshPhysicalMaterial` with `transmission` / `ior` (default 1.491) / `roughness` / `thickness`, glass color + texture |
75
+ | `OmniSurface(Lite)` | constants subset: diffuse color / metalness / roughness / IOR / coat / emission / opacity |
76
+
77
+ Executing MDL or MaterialX shader graphs is out of scope; unknown MDL
78
+ materials fall back to the OmniPBR mapping with a warning. Not yet
79
+ supported: collection-based material bindings, and the exotic curve schemas
80
+ (`NurbsCurves`, `HermiteCurves`, `NurbsPatch`) which load with a warning and
81
+ are skipped.
55
82
 
56
83
  ## Install
57
84
 
@@ -202,6 +229,48 @@ if (range) {
202
229
  }
203
230
  ```
204
231
 
232
+ ### Baked link transforms (recorded playback)
233
+
234
+ Recordings baked as **body transforms** (Isaac Sim stage-recorder output,
235
+ maximal-coordinate solver playback) can drive link poses directly, bypassing
236
+ the joints — usdview-style display semantics:
237
+
238
+ ```ts
239
+ // A world-pose track keyed by prim path (or link key), quaternion in [x, y, z, w]:
240
+ robot.setLinkTransforms({
241
+ "/World/link1": { position: [0, 0, 1], quaternion: [0, 0, 0, 1] },
242
+ "/World/link2": { position: [0.3, 0, 2], quaternion: [0, 0, 0, 1] },
243
+ }); // batched — one matrix update; unlisted links keep their current world pose
244
+
245
+ robot.displayMode; // "baked": joint values are untouched and no longer place links
246
+ robot.setJointValues(liveValues); // recompute all links from joint values → "fk"
247
+ ```
248
+
249
+ Poses are read in the **three.js scene world after `worldUp` normalization** —
250
+ pair a Z-up meter track (Isaac / ROS convention) with `worldUp: "Z"`; feeding
251
+ it into the default Y-up normalization lays the robot on its side. Transforms
252
+ on the `robot` object itself (placement, uniform scaling) are accounted for,
253
+ and `{ space: "stage" }` reads authored stage coordinates instead.
254
+
255
+ Constraint deviations — a recording from a different model version, solver
256
+ drift, a coordinate-convention bug — are shown, never silently corrected.
257
+ Measure them, or project onto the joints instead:
258
+
259
+ ```ts
260
+ robot.validateLinkTransforms(poses);
261
+ // { "/World/joint1": { anchorError /* m */, axisError /* rad */, q, limitExceeded }, … }
262
+ // covers every joint: fixed joints, loop joints dropped from the FK tree,
263
+ // and the world-fixed root attachment
264
+
265
+ const { values, residuals } = robot.jointValuesFromLinkTransforms(poses, {
266
+ previous: lastValues, // ±π branch continuity, frame to frame
267
+ });
268
+ robot.setJointValues(values); // constraint-respecting playback of the same track
269
+ ```
270
+
271
+ `new ThreeUsdRobotLoader({ debugBakedTransforms: true })` warns once per baked
272
+ session when poses deviate beyond 1 mm / 0.01 rad.
273
+
205
274
  ### React Three Fiber
206
275
 
207
276
  `three-usd-robot/react` provides a declarative `<UsdRobot>` (`react` and
@@ -0,0 +1,347 @@
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, S as Stage } from './buildKinematicTree-BCySuZZn.js';
3
+
4
+ /**
5
+ * The articulated "motion" node of a joint, inserted between the joint's two
6
+ * fixed frames (`jointFrame0` and `inverse(jointFrame1)`). {@link setValue}
7
+ * rotates it about the axis (revolute/continuous) or slides it along the axis
8
+ * (prismatic); fixed joints are inert.
9
+ */
10
+ declare class JointObject extends THREE.Object3D {
11
+ readonly isJointObject = true;
12
+ readonly jointName: string;
13
+ /** Full USD prim path of the joint — the collision-proof address. */
14
+ readonly primPath: string;
15
+ readonly jointType: JointType;
16
+ readonly axisToken: Axis;
17
+ readonly axis: THREE.Vector3;
18
+ readonly lower: number | undefined;
19
+ readonly upper: number | undefined;
20
+ private _value;
21
+ constructor(joint: JointDescription);
22
+ get value(): number;
23
+ get articulated(): boolean;
24
+ /**
25
+ * Set the joint value (radians for revolute/continuous, length for prismatic).
26
+ * Optionally clamps to authored limits. Returns the value actually applied.
27
+ */
28
+ setValue(value: number, clampToLimits?: boolean): number;
29
+ }
30
+
31
+ /**
32
+ * Three.js node for a robot link. Its frame is the USD link prim's frame;
33
+ * visual/collision meshes (M6) attach as children relative to it. Placement
34
+ * relative to the parent is supplied by the joint chain, so a link's own local
35
+ * matrix is identity (except the root, which carries the world-fixed placement).
36
+ */
37
+ declare class LinkObject extends THREE.Object3D {
38
+ readonly isLinkObject = true;
39
+ readonly linkName: string;
40
+ readonly primPath: string;
41
+ constructor(link: LinkDescription);
42
+ }
43
+
44
+ /** Target world up-axis: normalize to Y-up / Z-up, or keep the authored orientation. */
45
+ type WorldUpAxis = "Y" | "Z" | "keep";
46
+ type ThreeUsdRobotOptions = {
47
+ /** Clamp `setJointValue` to authored limits (default `true`). */
48
+ clampJointLimits?: boolean;
49
+ /** Size of the built-in joint-axis / link-frame helpers (stage units, default `0.15`). */
50
+ helperSize?: number;
51
+ /**
52
+ * Target world up-axis. The root is rotated so the stage's authored `upAxis`
53
+ * lands in that convention: `"Y"` for a standard three.js scene, `"Z"` for a
54
+ * robotics-style Z-up world, `"keep"` for no correction. Takes precedence
55
+ * over the deprecated {@link ThreeUsdRobotOptions.upAxisConversion}.
56
+ */
57
+ worldUp?: WorldUpAxis;
58
+ /**
59
+ * Legacy up-axis correction: `"auto"` ≡ `worldUp: "Y"`, `"Y"` / `"none"` ≡
60
+ * `worldUp: "keep"`, and `"Z"` forces the Z-up→Y-up rotation regardless of
61
+ * stage metadata. Default `"none"` (the loader defaults to `"auto"`).
62
+ * @deprecated Use {@link ThreeUsdRobotOptions.worldUp}.
63
+ */
64
+ upAxisConversion?: "auto" | "Y" | "Z" | "none";
65
+ /** Extra uniform scale multiplied with the stage `metersPerUnit` (default `1`). */
66
+ unitScale?: number;
67
+ /** Seed joints from their authored initial value (drive target / joint state). Default `true`. */
68
+ applyInitialPose?: boolean;
69
+ /**
70
+ * Diagnose {@link ThreeUsdRobot.setLinkTransforms} poses against the joint
71
+ * constraints and `console.warn` once per baked session when one deviates
72
+ * beyond tolerance (default 1 mm anchor / 0.01 rad axis). `true` uses the
73
+ * defaults; pass an object to tune them.
74
+ */
75
+ debugBakedTransforms?: boolean | {
76
+ anchorTolerance?: number;
77
+ axisTolerance?: number;
78
+ };
79
+ };
80
+ /**
81
+ * A rigid world pose for {@link ThreeUsdRobot.setLinkTransforms} —
82
+ * `quaternion` in Three.js `[x, y, z, w]` order (USD authors quatf as
83
+ * `(w, x, y, z)`; reorder when reading recorded USD by hand).
84
+ */
85
+ type LinkPose = {
86
+ position: [number, number, number];
87
+ quaternion: [number, number, number, number];
88
+ };
89
+ /**
90
+ * Coordinate space of {@link LinkPose} batches. `"world"` (default) is the
91
+ * Three.js scene world *after* `worldUp` / unit normalization — with
92
+ * `worldUp: "Z"` you hand in Z-up poses — including any transform on the
93
+ * robot object itself (which must stay a similarity: uniform scale, no
94
+ * shear). `"stage"` is the authored USD stage space (before up-axis rotation
95
+ * and `metersPerUnit` scaling), as prim world transforms are written in the
96
+ * file.
97
+ */
98
+ type LinkPoseSpace = "world" | "stage";
99
+ type LinkPosesOptions = {
100
+ /** Interpretation of the poses (default `"world"`). */
101
+ space?: LinkPoseSpace;
102
+ };
103
+ type JointValuesFromLinkTransformsOptions = LinkPosesOptions & {
104
+ /**
105
+ * Previous joint values (keyed like the returned `values`): each
106
+ * revolute/continuous joint picks the 2πk branch of its projection nearest
107
+ * this, for frame-to-frame continuity past ±π.
108
+ */
109
+ previous?: Record<string, number>;
110
+ /** Clamp `values` to authored limits (default `false` — deviations are reported, not hidden). */
111
+ clampLimits?: boolean;
112
+ };
113
+ /**
114
+ * Per-joint constraint residual of a link-pose batch, keyed by joint prim
115
+ * path. The ideal parent→child transform of a joint is a pure motion along
116
+ * its DOF; whatever the poses leave over splits into `anchorError` /
117
+ * `axisError` (see {@link ThreeUsdRobot.validateLinkTransforms}).
118
+ */
119
+ type JointResidual = {
120
+ /** Translation residual at the joint anchor, in meters (`metersPerUnit` applied). */
121
+ anchorError: number;
122
+ /** Rotation residual off the joint DOF, in radians. */
123
+ axisError: number;
124
+ /** Projected joint value (SI: radians / stage length units; `0` for fixed joints). */
125
+ q: number;
126
+ /** Whether `q` lies outside the authored limits. */
127
+ limitExceeded: boolean;
128
+ };
129
+ /**
130
+ * A Three.js `Object3D` that realizes a {@link RobotDescription} as a kinematic
131
+ * hierarchy and drives forward kinematics via {@link setJointValue}.
132
+ *
133
+ * Per joint the hierarchy is
134
+ * `parentLink → jointFrame0 → jointMotion → jointFrame1⁻¹ → childLink`,
135
+ * where only `jointMotion` (a {@link JointObject}) changes with the joint value;
136
+ * world poses then fall out of Three.js's `updateMatrixWorld`.
137
+ *
138
+ * **Naming contract** — a link/joint's key is its prim's leaf name when that
139
+ * is unique across the robot, else its full prim path (deterministic; see the
140
+ * extractor). Every accessor taking a name equally accepts the full prim path,
141
+ * which is stable regardless of collisions; {@link getLinkObjectsByPath} /
142
+ * {@link getJointObjectsByPath} enumerate the path-keyed tables.
143
+ */
144
+ declare class ThreeUsdRobot extends THREE.Object3D {
145
+ readonly isThreeUsdRobot = true;
146
+ readonly robot: RobotDescription;
147
+ readonly tree: KinematicTree;
148
+ readonly clampJointLimits: boolean;
149
+ /**
150
+ * The composed USD stage this robot was built from — the full prim tree, for
151
+ * inspection tooling (structure panels, attribute browsers). Attached by
152
+ * {@link ThreeUsdRobotLoader}; `undefined` for programmatically-built robots.
153
+ */
154
+ stage?: Stage;
155
+ private readonly linkObjects;
156
+ private readonly jointObjects;
157
+ private readonly linkKeyByPath;
158
+ private readonly jointKeyByPath;
159
+ private dirty;
160
+ /** Constructed (fk rest) local matrix of every link, for baked→fk restore. */
161
+ private readonly restLocal;
162
+ private _displayMode;
163
+ /** Stage-space link worlds while baked (`null` in fk mode). */
164
+ private bakedStageWorld;
165
+ /** Frozen `frame0 · motion · frame1⁻¹` per tree joint while baked. */
166
+ private bakedChainRel;
167
+ private readonly debugBaked;
168
+ private bakedDebugWarned;
169
+ private readonly warnedPoseKeys;
170
+ private warnedNonUniformScale;
171
+ private readonly helperSize;
172
+ private _showVisual;
173
+ private _showCollision;
174
+ private _showJointAxes;
175
+ private _showLinkFrames;
176
+ private jointAxesHelpers;
177
+ private linkFrameHelpers;
178
+ constructor(robot: RobotDescription, tree: KinematicTree, options?: ThreeUsdRobotOptions);
179
+ /** Orient (authored upAxis → target world up) and scale (metersPerUnit × unitScale) the root. */
180
+ private applyStageNormalization;
181
+ /** Apply each joint's authored initial value, if any. */
182
+ private applyInitialPose;
183
+ private attachRoot;
184
+ private attachTreeEdges;
185
+ /** Build `parent → frame0 → motion → frame1⁻¹ → child` for one joint. */
186
+ private attachJointChain;
187
+ private attachIsolatedLinks;
188
+ /** Resolve a link reference — key or full prim path — to the extractor key. */
189
+ private linkKey;
190
+ /** Resolve a joint reference — key or full prim path — to the extractor key. */
191
+ private jointKey;
192
+ /**
193
+ * Set one joint value, addressed by key or full prim path. Unknown joints
194
+ * are ignored. Returns whether it applied. Always restores `"fk"` display
195
+ * mode first (see {@link setLinkTransforms}).
196
+ */
197
+ setJointValue(name: string, value: number): boolean;
198
+ /**
199
+ * Set several joint values at once (matrix update is coalesced). Always
200
+ * restores `"fk"` display mode first, recomputing every link purely from
201
+ * joint values — even an empty batch returns from baked playback (see
202
+ * {@link setLinkTransforms}).
203
+ */
204
+ setJointValues(values: Record<string, number>): void;
205
+ getJointValue(name: string): number | undefined;
206
+ /** Recompute world matrices. Called lazily by the getters; safe to call directly. */
207
+ updateKinematics(): void;
208
+ private ensureUpdated;
209
+ /**
210
+ * `"fk"` (default): link placements derive from joint values. `"baked"`:
211
+ * {@link setLinkTransforms} wrote link poses directly and the joints no
212
+ * longer constrain the display; any `setJointValue`-family call restores fk.
213
+ */
214
+ get displayMode(): "fk" | "baked";
215
+ /**
216
+ * Drive link world poses directly — the display path for baked recordings
217
+ * (Isaac Sim body-transform time samples, maximal-coordinate playback).
218
+ * usdview-like semantics: constraint deviations are shown, never corrected —
219
+ * {@link validateLinkTransforms} measures them,
220
+ * {@link jointValuesFromLinkTransforms} projects onto the joints instead.
221
+ *
222
+ * Enters `"baked"` display mode; joint values stay untouched. Return to fk
223
+ * with {@link setJointValues} (any batch, even `{}`), which recomputes
224
+ * every link purely from joint values.
225
+ *
226
+ * Keys are link keys or full prim paths; unknown keys warn once and are
227
+ * skipped. Unspecified links KEEP their current world pose — a track that
228
+ * omits a link means "it did not move". Poses are rigid, `quaternion` in
229
+ * `[x, y, z, w]` order, interpreted per `opts.space` (default `"world"`:
230
+ * the Three.js scene world after `worldUp` normalization — pair a Z-up
231
+ * meter track with `worldUp: "Z"`). Matrix updates are coalesced into the
232
+ * next render / world query. Returns the number of poses applied.
233
+ */
234
+ setLinkTransforms(poses: Record<string, LinkPose>, opts?: LinkPosesOptions): number;
235
+ /**
236
+ * Measure how far a link-pose batch deviates from the joint constraints,
237
+ * without touching the display. Unspecified links resolve to their current
238
+ * displayed pose, so the report predicts exactly what
239
+ * {@link setLinkTransforms} with the same batch would show.
240
+ *
241
+ * Keyed by joint prim path; covers every joint — fixed joints (`q` = 0
242
+ * check), loop joints dropped from the fk tree (closure error) and the
243
+ * world-fixed root attachment (a moved base against a fixed-base model).
244
+ * Typical signatures: a constant `anchorError` offset on every joint —
245
+ * recording/model mismatch (wrong version or scale); growth over time —
246
+ * maximal-coordinate solver drift; large uniform `axisError` — a
247
+ * coordinate-convention bug (Y/Z-up or quaternion order).
248
+ */
249
+ validateLinkTransforms(poses: Record<string, LinkPose>, opts?: LinkPosesOptions): Record<string, JointResidual>;
250
+ /**
251
+ * Project a link-pose batch onto the joint manifold: the closed-form 1-DOF
252
+ * joint values that best reproduce it, plus the same residuals as
253
+ * {@link validateLinkTransforms}. `values` covers the articulated tree
254
+ * joints, keyed by joint prim path, and feeds {@link setJointValues}
255
+ * directly — the constraint-respecting playback of the same track:
256
+ *
257
+ * ```ts
258
+ * robot.setJointValues(robot.jointValuesFromLinkTransforms(poses, { previous }).values);
259
+ * ```
260
+ *
261
+ * Residual `q` / `limitExceeded` always report the unclamped projection,
262
+ * also when `clampLimits` clamps `values`.
263
+ */
264
+ jointValuesFromLinkTransforms(poses: Record<string, LinkPose>, opts?: JointValuesFromLinkTransformsOptions): {
265
+ values: Record<string, number>;
266
+ residuals: Record<string, JointResidual>;
267
+ };
268
+ /** Restore the constructed fk link placements (no-op when already `"fk"`). */
269
+ private exitBakedMode;
270
+ /** Freeze the fk state a baked session builds on (joints cannot move while baked). */
271
+ private enterBakedMode;
272
+ /** `frame0 · motion(q) · frame1⁻¹` of every tree joint, from live joint values. */
273
+ private computeChainRels;
274
+ /** Stage-space world transform of every link under the current display state. */
275
+ private computeStageWorlds;
276
+ private currentStageWorlds;
277
+ /** Resolve pose keys to link keys and convert each pose to a rigid stage-space matrix. */
278
+ private resolvePoseTargets;
279
+ /**
280
+ * Scene world → stage space, undoing the robot's own world transform
281
+ * (up-axis rotation, unit scale, any user placement) as a similarity — so
282
+ * link locals stay rigid and the root keeps carrying the scale.
283
+ */
284
+ private sceneToStageConverter;
285
+ /**
286
+ * Decompose every joint's parent→child transform under a pose batch
287
+ * (unspecified links resolve to their current displayed pose, mirroring
288
+ * {@link setLinkTransforms}). Pure — the display is untouched.
289
+ */
290
+ private decomposeJoints;
291
+ private buildResidual;
292
+ private warnUnknownPoseKey;
293
+ /** `debugBakedTransforms`: warn once per baked session when poses break the constraints. */
294
+ private warnBakedDeviationOnce;
295
+ /** World matrix of a link, addressed by key or full prim path. */
296
+ getLinkWorldMatrix(name: string): THREE.Matrix4;
297
+ getLinkWorldPosition(name: string): THREE.Vector3;
298
+ /** Link object by key or full prim path. */
299
+ getLinkObject(name: string): LinkObject | undefined;
300
+ /** Joint object by key or full prim path. */
301
+ getJointObject(name: string): JointObject | undefined;
302
+ /**
303
+ * Table of link prim path → {@link LinkObject}. Prim paths are the
304
+ * collision-proof way to pin a link (e.g. to attach tools or gizmos).
305
+ */
306
+ getLinkObjectsByPath(): Map<string, LinkObject>;
307
+ /**
308
+ * Table of joint prim path → {@link JointObject}, covering the joints
309
+ * realized in the kinematic tree (loop joints have no motion node).
310
+ */
311
+ getJointObjectsByPath(): Map<string, JointObject>;
312
+ getJoints(): JointDescription[];
313
+ getLinks(): LinkDescription[];
314
+ /** Names of the articulated (controllable) joints. */
315
+ getJointNames(): string[];
316
+ getLinkNames(): string[];
317
+ getKinematicTree(): KinematicTree;
318
+ /** Authored stage up-axis (`"Y"` or `"Z"`) — unaffected by `worldUp` normalization. */
319
+ get upAxis(): "Y" | "Z";
320
+ /** Authored stage scale in meters per unit (already applied to the root). */
321
+ get metersPerUnit(): number;
322
+ /** Playback rate in time codes per second (from the stage; default 24). */
323
+ getTimeCodesPerSecond(): number;
324
+ /** Whether any joint has a time-sampled trajectory. */
325
+ hasAnimation(): boolean;
326
+ /**
327
+ * Animation range in time codes: the union of authored joint sample ranges,
328
+ * falling back to the stage `startTimeCode`/`endTimeCode`. `null` if neither.
329
+ */
330
+ getTimeRange(): {
331
+ start: number;
332
+ end: number;
333
+ } | null;
334
+ /** Sample every animated joint at time code `t` and apply the values (an fk drive — leaves baked mode). */
335
+ setTime(t: number): void;
336
+ get showVisual(): boolean;
337
+ set showVisual(v: boolean);
338
+ get showCollision(): boolean;
339
+ set showCollision(v: boolean);
340
+ get showJointAxes(): boolean;
341
+ set showJointAxes(v: boolean);
342
+ get showLinkFrames(): boolean;
343
+ set showLinkFrames(v: boolean);
344
+ private setKindVisibility;
345
+ }
346
+
347
+ export { JointObject as J, LinkObject as L, ThreeUsdRobot as T, type WorldUpAxis as W, type ThreeUsdRobotOptions as a, type JointResidual as b, type JointValuesFromLinkTransformsOptions as c, type LinkPose as d, type LinkPoseSpace as e, type LinkPosesOptions as f };
@@ -1,6 +1,6 @@
1
- import { R as RobotDescription } from './buildKinematicTree-DQ4Vr4sJ.js';
1
+ import { R as RobotDescription } from './buildKinematicTree-BCySuZZn.js';
2
2
  import { A as AssetResolver, U as UsdSource, B as BinarySource } from './bytes-MOJ2oN-u.js';
3
- import { W as WorldUpAxis, T as ThreeUsdRobot } from './ThreeUsdRobot-BAh-48DD.js';
3
+ import { W as WorldUpAxis, a as ThreeUsdRobotOptions, T as ThreeUsdRobot } from './ThreeUsdRobot-BxnCluuK.js';
4
4
 
5
5
  type ThreeUsdRobotLoaderOptions = {
6
6
  /** Resolver for references / payloads / sublayers (default {@link DefaultAssetResolver}). */
@@ -18,6 +18,11 @@ type ThreeUsdRobotLoaderOptions = {
18
18
  loadSceneGeometry?: boolean;
19
19
  /** Load diffuse textures referenced by materials (default `true`). */
20
20
  loadTextures?: boolean;
21
+ /**
22
+ * Render `BasisCurves` that author `widths` as tube meshes instead of
23
+ * 1-px lines (default `false`, M18).
24
+ */
25
+ curveTubes?: boolean;
21
26
  /**
22
27
  * Target world up-axis. Any stage (Y-up or Z-up) is normalized into this
23
28
  * convention: `"Y"` for a standard three.js scene (the default behavior),
@@ -36,6 +41,12 @@ type ThreeUsdRobotLoaderOptions = {
36
41
  clampJointLimits?: boolean;
37
42
  /** Seed joints from drive targets / joint state (M9). */
38
43
  applyDriveTargetsAsInitialPose?: boolean;
44
+ /**
45
+ * Diagnose {@link ThreeUsdRobot.setLinkTransforms} poses against the joint
46
+ * constraints and warn once per baked session past tolerance (default
47
+ * 1 mm anchor / 0.01 rad axis).
48
+ */
49
+ debugBakedTransforms?: ThreeUsdRobotOptions["debugBakedTransforms"];
39
50
  /** Override the robot name. */
40
51
  robotName?: string;
41
52
  /** Receives non-fatal load diagnostics. */
@@ -82,6 +93,8 @@ declare class ThreeUsdRobotLoader {
82
93
  private openSource;
83
94
  private openUsdzStage;
84
95
  private buildFromStage;
96
+ /** Surface recognized-but-unrenderable gprim schemas instead of silence (M18). */
97
+ private warnUnsupportedGprims;
85
98
  private composeStage;
86
99
  /** Compose a layer from raw bytes, sniffing binary crate vs USDA text. */
87
100
  private composeStageFromBytes;
@@ -364,6 +364,8 @@ declare class Attribute {
364
364
  Get(time?: number): UsdValue | undefined;
365
365
  GetTimeSamples(): Map<number, UsdValue>;
366
366
  GetConnections(): SdfPath[];
367
+ /** Authored attribute metadata (`interpolation`, `elementSize`, …). */
368
+ GetMetadata(key: string): UsdValue | undefined;
367
369
  }
368
370
  /** A relationship on a prim (`UsdRelationship`-like). */
369
371
  declare class Relationship {
@@ -378,6 +380,8 @@ declare class Relationship {
378
380
  GetNamespace(): string;
379
381
  IsCustom(): boolean;
380
382
  GetTargets(): SdfPath[];
383
+ /** Authored relationship metadata (`bindMaterialAs`, …). */
384
+ GetMetadata(key: string): UsdValue | undefined;
381
385
  }
382
386
 
383
387
  /**