three-usd-robot 0.13.0 → 0.14.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.
Files changed (43) hide show
  1. package/README.md +19 -1
  2. package/dist/{MeshBinding-B_8RhuQE.d.ts → MeshBinding-5Dad1EOh.d.ts} +16 -4
  3. package/dist/{ThreeUsdRobot-X1zbpRZo.d.ts → ThreeUsdRobot-CurQqRqu.d.ts} +78 -2
  4. package/dist/{ThreeUsdRobotLoader-u3d1yoLM.d.ts → ThreeUsdRobotLoader-DrYXpMta.d.ts} +28 -4
  5. package/dist/chunk-ALC7RBKC.js +68 -0
  6. package/dist/chunk-ALC7RBKC.js.map +1 -0
  7. package/dist/{chunk-JN2QPDB3.js → chunk-HDZGWL6P.js} +36 -3
  8. package/dist/chunk-HDZGWL6P.js.map +1 -0
  9. package/dist/{chunk-YGJ23CG3.js → chunk-IAOPNN6V.js} +3 -66
  10. package/dist/chunk-IAOPNN6V.js.map +1 -0
  11. package/dist/{chunk-5ZPHZ5ZH.js → chunk-IT5RWB7A.js} +5 -4
  12. package/dist/chunk-IT5RWB7A.js.map +1 -0
  13. package/dist/{chunk-FUVHAORT.js → chunk-KRT4NL3H.js} +190 -126
  14. package/dist/chunk-KRT4NL3H.js.map +1 -0
  15. package/dist/{chunk-GRJGPHLW.js → chunk-WQRP5IDJ.js} +382 -59
  16. package/dist/chunk-WQRP5IDJ.js.map +1 -0
  17. package/dist/chunk-ZQXYVBQI.js +154 -0
  18. package/dist/chunk-ZQXYVBQI.js.map +1 -0
  19. package/dist/core.d.ts +5 -4
  20. package/dist/core.js +5 -3
  21. package/dist/extras.d.ts +2 -2
  22. package/dist/helpers.d.ts +2 -2
  23. package/dist/helpers.js +3 -2
  24. package/dist/helpers.js.map +1 -1
  25. package/dist/index.d.ts +61 -8
  26. package/dist/index.js +10 -8
  27. package/dist/index.js.map +1 -1
  28. package/dist/nodes.d.ts +4 -4
  29. package/dist/{parseMdl-vfzBGoMr.d.ts → parseMdl-M862hSal.d.ts} +1 -29
  30. package/dist/react.d.ts +5 -5
  31. package/dist/react.js +6 -4
  32. package/dist/react.js.map +1 -1
  33. package/dist/rendering.d.ts +114 -0
  34. package/dist/rendering.js +174 -0
  35. package/dist/rendering.js.map +1 -0
  36. package/dist/usdGeomCamera-BEsGuz7m.d.ts +53 -0
  37. package/dist/{buildKinematicTree-Q9JOjAjM.d.ts → usdLux-BqQlSOwG.d.ts} +108 -1
  38. package/package.json +5 -1
  39. package/dist/chunk-5ZPHZ5ZH.js.map +0 -1
  40. package/dist/chunk-FUVHAORT.js.map +0 -1
  41. package/dist/chunk-GRJGPHLW.js.map +0 -1
  42. package/dist/chunk-JN2QPDB3.js.map +0 -1
  43. package/dist/chunk-YGJ23CG3.js.map +0 -1
package/README.md CHANGED
@@ -28,6 +28,13 @@ exported back to `.usda` / `.usdz` in the browser.
28
28
  materials (UsdPreviewSurface / Omniverse MDL / MaterialX, plus optional TSL
29
29
  graph execution on WebGPU) and textures; up-axis and units normalized
30
30
  automatically. Articulation-free stages load as static scenes.
31
+ - **Lighting** — `UsdLux` lights (distant / sphere / rect / disk, ShapingAPI
32
+ cones, ShadowAPI) become Three.js lights with shadows preconfigured, and
33
+ DomeLights become HDRI environment lighting via
34
+ `three-usd-robot/rendering`.
35
+ - **Cameras** — `UsdGeomCamera` prims (film-back FOV, clipping, orthographic,
36
+ exposure metadata) become Three.js cameras riding the joint hierarchy —
37
+ view a cell through its authored sensor cameras.
31
38
  - **Animation** — plays back time-sampled joint trajectories, and replays
32
39
  baked body-transform recordings through `setLinkTransforms` with
33
40
  constraint diagnostics.
@@ -81,6 +88,16 @@ robot.getJointNames(); // commandable joints
81
88
  robot.getKinematicTree(); // root, ordering, loop joints, ...
82
89
  ```
83
90
 
91
+ `UsdLux` lights and `UsdGeomCamera` prims load with the stage; two more lines
92
+ give the viewer a real look ([lighting guide](./docs/lighting.md)):
93
+
94
+ ```ts
95
+ import { applyRenderDefaults, applyUsdEnvironment } from "three-usd-robot/rendering";
96
+
97
+ applyRenderDefaults(renderer); // ACES tone mapping + soft shadow maps
98
+ await applyUsdEnvironment(robot, scene, { background: true }); // DomeLight → HDRI environment
99
+ ```
100
+
84
101
  `parse` also takes in-memory content (USDA text, an `ArrayBuffer` / typed
85
102
  array / `Blob` — the format is sniffed, so a dropped `File` works as-is), and
86
103
  the loader normalizes units and up-axis for you: Isaac's Z-up assets stand
@@ -91,8 +108,9 @@ robotics-style Z-up world. Details in the [runtime guide](./docs/runtime.md).
91
108
 
92
109
  | Doc | Contents |
93
110
  | --- | --- |
94
- | [Runtime guide](./docs/runtime.md) | Input sources, up-axis & units, naming contract, mimic joints, viewer helpers & ghosts, static scenes, joint sliders, React Three Fiber, using the core without Three.js |
111
+ | [Runtime guide](./docs/runtime.md) | Input sources, up-axis & units, naming contract, mimic joints, viewer helpers & ghosts, static scenes, lights & cameras, joint sliders, React Three Fiber, using the core without Three.js |
95
112
  | [Materials](./docs/materials.md) | UsdPreviewSurface fidelity, Omniverse MDL family mappings, MaterialX, optional TSL graph execution (WebGPU) |
113
+ | [Lighting](./docs/lighting.md) | UsdLux → Three.js lights, DomeLight → IBL environment, shadow & tone-mapping defaults, intensity calibration for Omniverse assets |
96
114
  | [Animation & recorded playback](./docs/recorded-playback.md) | Time-sampled trajectories, baked body-transform recordings, constraint diagnostics & joint projection |
97
115
  | [Exporting USD](./docs/export.md) | Re-export, `RobotBuilder` authoring, simulation-ready assets (mass / collision / Isaac Robot Schema), USDZ packaging |
98
116
 
@@ -1,7 +1,7 @@
1
1
  import * as THREE from 'three';
2
- import { y as Vec2, z as Vec3, S as Stage, P as Prim, R as RobotDescription } from './buildKinematicTree-Q9JOjAjM.js';
3
- import { b as MdlModuleProvider, A as AssetResolver } from './parseMdl-vfzBGoMr.js';
4
- import { T as ThreeUsdRobot } from './ThreeUsdRobot-X1zbpRZo.js';
2
+ import { V as Vec2, a as Vec3, S as Stage, P as Prim, A as AssetResolver, R as RobotDescription } from './usdLux-BqQlSOwG.js';
3
+ import { M as MdlModuleProvider } from './parseMdl-M862hSal.js';
4
+ import { T as ThreeUsdRobot } from './ThreeUsdRobot-CurQqRqu.js';
5
5
 
6
6
  /**
7
7
  * Resolves `UsdShade` material bindings to flat PBR parameters.
@@ -162,8 +162,11 @@ type TextureProvider = (assetPath: string, options?: TextureOptions) => THREE.Te
162
162
  * against `baseUrl`. Image bytes are fetched once per URL (works for HTTP and
163
163
  * `.usdz` entries alike) and the decoded image is shared; each call returns a
164
164
  * distinct `THREE.Texture` carrying the requested color space / wrap / transform.
165
+ *
166
+ * `<UDIM>` paths resolve to their first tile (1001) with a one-time `onWarn`
167
+ * diagnostic — full UDIM sets are out of scope (M26).
165
168
  */
166
- declare function createTextureProvider(resolver: AssetResolver, baseUrl: string): TextureProvider;
169
+ declare function createTextureProvider(resolver: AssetResolver, baseUrl: string, onWarn?: (message: string) => void): TextureProvider;
167
170
 
168
171
  /**
169
172
  * Binds renderable gprims — `UsdGeom.Mesh` plus the parametric solids (`Cube` /
@@ -198,6 +201,8 @@ type BindMeshesOptions = {
198
201
  mdl?: MdlModuleProvider;
199
202
  /** Overrides material creation for mesh-like gprims (M22). */
200
203
  materialFactory?: MaterialFactory;
204
+ /** Flag visual meshes `castShadow` / `receiveShadow` (M25). */
205
+ shadows?: boolean;
201
206
  };
202
207
  /**
203
208
  * Build a `BufferGeometry` from a Mesh prim, or `null` if it has no points.
@@ -237,6 +242,12 @@ type BuildGprimOptions = {
237
242
  mdl?: MdlModuleProvider;
238
243
  /** Overrides material creation for mesh-like gprims (M22). */
239
244
  materialFactory?: MaterialFactory;
245
+ /**
246
+ * Flag mesh-like gprims `castShadow` / `receiveShadow` (M25). Free until a
247
+ * renderer enables shadow maps; fully transparent / transmissive meshes
248
+ * still receive but do not cast (Three.js shadows would be opaque black).
249
+ */
250
+ shadows?: boolean;
240
251
  };
241
252
  /**
242
253
  * Build a renderable `THREE.Object3D` for any supported gprim (M18):
@@ -283,6 +294,7 @@ declare function bindSceneMeshes(stage: Stage, robot3d: ThreeUsdRobot, desc: Rob
283
294
  onWarn?: (message: string) => void;
284
295
  mdl?: MdlModuleProvider;
285
296
  materialFactory?: MaterialFactory;
297
+ shadows?: boolean;
286
298
  }): number;
287
299
 
288
300
  export { type BindMeshesOptions as B, type MaterialFactory as M, type ResolveMaterialOptions as R, type TextureProvider as T, type BuildGprimOptions as a, type MeshKind as b, type ResolvedMaterial as c, type ResolvedTexture as d, type TextureColorSpace as e, type TextureOptions as f, type TextureTransform as g, type TextureWrap as h, bindRobotMeshes as i, bindSceneMeshes as j, buildGprimGeometry as k, buildGprimObject as l, buildMeshGeometry as m, buildMeshMaterial as n, createTextureProvider as o, findBoundSurfaceShader as p, resolveBoundMaterial as r };
@@ -1,5 +1,46 @@
1
1
  import * as THREE from 'three';
2
- import { g as JointType, A as Axis, f as JointMimicDescription, e as JointDescription, j as LinkDescription, R as RobotDescription, K as KinematicTree, S as Stage } from './buildKinematicTree-Q9JOjAjM.js';
2
+ import { S as Stage, k as JointType, b as Axis, j as JointMimicDescription, i as JointDescription, n as LinkDescription, R as RobotDescription, K as KinematicTree, L as LightDescription, A as AssetResolver } from './usdLux-BqQlSOwG.js';
3
+
4
+ /**
5
+ * Binds `UsdGeomCamera` prims to Three.js cameras and attaches them into the
6
+ * robot's hierarchy (M27).
7
+ *
8
+ * USD and Three.js share the same camera frame (−Z forward, +Y up), so a
9
+ * camera places with its prim transform alone — under its link object when it
10
+ * is mounted on the robot (a wrist or sensor camera follows the joints), else
11
+ * under the mirrored scenery groups or the root. Focal length and apertures
12
+ * are millimeters on a film back; clipping range and focus distance are stage
13
+ * units and get the same world normalization as everything else.
14
+ */
15
+
16
+ /** A bound USD camera — perspective or orthographic. */
17
+ type UsdBoundCamera = THREE.PerspectiveCamera | THREE.OrthographicCamera;
18
+ type BindCamerasOptions = {
19
+ /** Receives fidelity diagnostics. */
20
+ onWarn?: (message: string) => void;
21
+ };
22
+ /**
23
+ * Traverse the stage and bind every `Camera` prim. Call after mesh binding so
24
+ * cameras anchor into the existing hierarchy. Cameras with
25
+ * `visibility = "invisible"` or a guide/proxy purpose are skipped. Each
26
+ * result carries `userData.primPath` and `userData.usdCamera` (its
27
+ * {@link CameraDescription}).
28
+ */
29
+ declare function bindCameras(stage: Stage, robot3d: ThreeUsdRobot, options?: BindCamerasOptions): UsdBoundCamera[];
30
+ /**
31
+ * `UsdRender` aspect-ratio conform policies: how a camera's fixed aperture
32
+ * meets a viewport of a different aspect. `expandAperture` (the USD default)
33
+ * always shows at least the authored view; `cropAperture` never shows more;
34
+ * the `adjust*` policies pin one axis outright.
35
+ */
36
+ type AspectConformPolicy = "expandAperture" | "cropAperture" | "adjustApertureWidth" | "adjustApertureHeight";
37
+ /**
38
+ * Fit a bound USD camera to a viewport aspect ratio (width / height) and
39
+ * update its projection. Call on resize, or before rendering through a camera
40
+ * from {@link ThreeUsdRobot.cameras}. Cameras without USD metadata just get
41
+ * the aspect applied.
42
+ */
43
+ declare function conformCameraAspect(camera: UsdBoundCamera, viewportAspect: number, policy?: AspectConformPolicy): void;
3
44
 
4
45
  /**
5
46
  * The articulated "motion" node of a joint, inserted between the joint's two
@@ -154,6 +195,41 @@ declare class ThreeUsdRobot extends THREE.Object3D {
154
195
  * {@link ThreeUsdRobotLoader}; `undefined` for programmatically-built robots.
155
196
  */
156
197
  stage?: Stage;
198
+ /**
199
+ * UsdLux lights bound from the stage (M25), already attached into this
200
+ * hierarchy; each carries `userData.primPath` and `userData.usdLight` (its
201
+ * resolved description). Populated by {@link ThreeUsdRobotLoader} unless
202
+ * `loadLights: false`.
203
+ */
204
+ lights: THREE.Light[];
205
+ /**
206
+ * DomeLights parsed from the stage (M25). Not realized as Three.js lights —
207
+ * they describe an image-based environment; apply one with
208
+ * `applyUsdEnvironment` from `three-usd-robot/rendering` (M26).
209
+ */
210
+ domeLights: LightDescription[];
211
+ /**
212
+ * `UsdGeomCamera` prims bound from the stage (M27), hierarchy-attached so a
213
+ * sensor camera on a link follows the joints. Each carries
214
+ * `userData.primPath` and `userData.usdCamera`; fit one to a viewport with
215
+ * `conformCameraAspect`. Populated by {@link ThreeUsdRobotLoader} unless
216
+ * `loadCameras: false`.
217
+ */
218
+ cameras: UsdBoundCamera[];
219
+ /**
220
+ * Asset-resolution context captured at load (M26) — lets
221
+ * `three-usd-robot/rendering` fetch referenced images (dome HDRIs, including
222
+ * entries inside a `.usdz` package). Set by {@link ThreeUsdRobotLoader}.
223
+ */
224
+ assetContext?: {
225
+ resolver: AssetResolver;
226
+ baseUrl: string;
227
+ };
228
+ /**
229
+ * The loader's `lightIntensityScale` (M26): `applyUsdEnvironment` defaults
230
+ * to it so the dome environment scales consistently with the bound lights.
231
+ */
232
+ lightIntensityScale?: number;
157
233
  private readonly linkObjects;
158
234
  private readonly jointObjects;
159
235
  private readonly linkKeyByPath;
@@ -374,4 +450,4 @@ declare class ThreeUsdRobot extends THREE.Object3D {
374
450
  private setKindVisibility;
375
451
  }
376
452
 
377
- 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 };
453
+ export { type AspectConformPolicy as A, type BindCamerasOptions as B, JointObject as J, LinkObject as L, ThreeUsdRobot as T, type UsdBoundCamera as U, 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, bindCameras as g, conformCameraAspect as h };
@@ -1,8 +1,7 @@
1
- import { R as RobotDescription } from './buildKinematicTree-Q9JOjAjM.js';
2
- import { A as AssetResolver } from './parseMdl-vfzBGoMr.js';
1
+ import { A as AssetResolver, R as RobotDescription } from './usdLux-BqQlSOwG.js';
3
2
  import { U as UsdSource, B as BinarySource } from './bytes-CxGRGry_.js';
4
- import { M as MaterialFactory } from './MeshBinding-B_8RhuQE.js';
5
- import { W as WorldUpAxis, a as ThreeUsdRobotOptions, T as ThreeUsdRobot } from './ThreeUsdRobot-X1zbpRZo.js';
3
+ import { M as MaterialFactory } from './MeshBinding-5Dad1EOh.js';
4
+ import { W as WorldUpAxis, a as ThreeUsdRobotOptions, T as ThreeUsdRobot } from './ThreeUsdRobot-CurQqRqu.js';
6
5
 
7
6
  type ThreeUsdRobotLoaderOptions = {
8
7
  /** Resolver for references / payloads / sublayers (default {@link DefaultAssetResolver}). */
@@ -20,6 +19,31 @@ type ThreeUsdRobotLoaderOptions = {
20
19
  loadSceneGeometry?: boolean;
21
20
  /** Load diffuse textures referenced by materials (default `true`). */
22
21
  loadTextures?: boolean;
22
+ /**
23
+ * Bind `UsdLux` lights into the hierarchy (M25, default `true`) — even when
24
+ * scene geometry is off, since they light the robot. Bound lights land on
25
+ * {@link ThreeUsdRobot.lights}; DomeLights on {@link ThreeUsdRobot.domeLights}.
26
+ */
27
+ loadLights?: boolean;
28
+ /**
29
+ * Bind `UsdGeomCamera` prims into the hierarchy (M27, default `true`) —
30
+ * they land on {@link ThreeUsdRobot.cameras}, link-mounted sensor cameras
31
+ * following the joints.
32
+ */
33
+ loadCameras?: boolean;
34
+ /**
35
+ * Multiplies every light's authored emission (`intensity × 2^exposure`,
36
+ * default `1`). Stages authored in Omniverse/RTX photometric units
37
+ * (intensities in the thousands) typically want `0.001` to land in
38
+ * Three.js's exposure-1 range; see docs/lighting.md.
39
+ */
40
+ lightIntensityScale?: number;
41
+ /**
42
+ * Flag meshes `castShadow` / `receiveShadow` and configure light shadows per
43
+ * `ShadowAPI` (M25, default `true`). Costs nothing until a renderer enables
44
+ * shadow maps.
45
+ */
46
+ shadows?: boolean;
23
47
  /**
24
48
  * Render `BasisCurves` that author `widths` as tube meshes instead of
25
49
  * 1-px lines (default `false`, M18).
@@ -0,0 +1,68 @@
1
+ import { multiplyAll, invert, decomposeRigid } from './chunk-IAOPNN6V.js';
2
+
3
+ // src/kinematics/jointResiduals.ts
4
+ var AXIS_INDEX = { X: 0, Y: 1, Z: 2 };
5
+ function decomposeJointRelative(joint, parentWorld, childWorld) {
6
+ const d = multiplyAll([
7
+ invert(joint.jointFrame0),
8
+ invert(parentWorld),
9
+ childWorld,
10
+ joint.jointFrame1
11
+ ]);
12
+ const t = [d[12], d[13], d[14]];
13
+ const { orientation } = decomposeRigid(d);
14
+ const sign = orientation.real < 0 ? -1 : 1;
15
+ const w = sign * orientation.real;
16
+ const vx = sign * orientation.imaginary[0];
17
+ const vy = sign * orientation.imaginary[1];
18
+ const vz = sign * orientation.imaginary[2];
19
+ const rotationAngle = 2 * Math.atan2(Math.hypot(vx, vy, vz), w);
20
+ const i = AXIS_INDEX[joint.axis];
21
+ if (joint.type === "prismatic") {
22
+ const anchor = Math.hypot(i === 0 ? 0 : t[0], i === 1 ? 0 : t[1], i === 2 ? 0 : t[2]);
23
+ return { q: t[i], anchorError: anchor, axisError: rotationAngle };
24
+ }
25
+ if (joint.type === "fixed") {
26
+ return { q: 0, anchorError: Math.hypot(...t), axisError: rotationAngle };
27
+ }
28
+ const proj = i === 0 ? vx : i === 1 ? vy : vz;
29
+ const twistNorm = Math.hypot(w, proj);
30
+ const q = twistNorm > 1e-12 ? 2 * Math.atan2(proj, w) : 0;
31
+ const swing = 2 * Math.atan2(Math.sqrt(Math.max(0, 1 - twistNorm * twistNorm)), twistNorm);
32
+ return { q, anchorError: Math.hypot(...t), axisError: swing };
33
+ }
34
+ function nearestAngleBranch(q, previous) {
35
+ const TWO_PI = 2 * Math.PI;
36
+ return q + TWO_PI * Math.round((previous - q) / TWO_PI);
37
+ }
38
+
39
+ // src/kinematics/sampling.ts
40
+ function interpolate(channel, t) {
41
+ const { times, values } = channel;
42
+ const n = times.length;
43
+ if (n === 0) return 0;
44
+ if (t <= times[0]) return values[0];
45
+ if (t >= times[n - 1]) return values[n - 1];
46
+ let lo = 0;
47
+ let hi = n - 1;
48
+ while (lo < hi) {
49
+ const mid = lo + hi >> 1;
50
+ if (times[mid] <= t) lo = mid + 1;
51
+ else hi = mid;
52
+ }
53
+ const i = lo - 1;
54
+ const t0 = times[i];
55
+ const t1 = times[i + 1];
56
+ const span = t1 - t0;
57
+ const f = span > 0 ? (t - t0) / span : 0;
58
+ return values[i] + (values[i + 1] - values[i]) * f;
59
+ }
60
+ function channelFromSamples(samples) {
61
+ const times = [...samples.keys()].sort((a, b) => a - b);
62
+ const values = times.map((t) => samples.get(t) ?? 0);
63
+ return { times, values };
64
+ }
65
+
66
+ export { channelFromSamples, decomposeJointRelative, interpolate, nearestAngleBranch };
67
+ //# sourceMappingURL=chunk-ALC7RBKC.js.map
68
+ //# sourceMappingURL=chunk-ALC7RBKC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/kinematics/jointResiduals.ts","../src/kinematics/sampling.ts"],"names":[],"mappings":"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","file":"chunk-ALC7RBKC.js","sourcesContent":["/**\n * Closed-form decomposition of a joint's observed parent→child transform\n * against its ideal single-DOF model (baked-playback diagnostics, M23).\n *\n * A UsdPhysics joint constrains child body1 to parent body0 through its two\n * authored frames: `inv(Wp) · Wc = F0 · M(q) · inv(F1)`, where `M(q)` rotates\n * about the joint axis (revolute / continuous), slides along it (prismatic),\n * or is identity (fixed). Observed world transforms therefore yield\n *\n * D = inv(F0) · inv(Wp) · Wc · F1\n *\n * which equals `M(q)` exactly for a constraint-consistent pose. This module\n * extracts `q` from `D` and reports what remains as residuals: translation at\n * the joint anchor (`anchorError`, stage linear units) and rotation off the\n * DOF (`axisError`, radians — the swing of a swing–twist split for revolute\n * joints). Inputs must be rigid stage-space transforms, before any\n * `metersPerUnit` or up-axis normalization.\n */\n\nimport { type Mat4, decomposeRigid, invert, multiplyAll } from \"./transforms.js\";\n\n/** The slice of a joint description the decomposition needs (structurally satisfied by `JointDescription`). */\nexport type JointDofInput = {\n type: \"fixed\" | \"revolute\" | \"continuous\" | \"prismatic\";\n /** Axis token as authored (`physics:axis`). */\n axis: \"X\" | \"Y\" | \"Z\";\n /** Joint frame in the parent (body0) local space. */\n jointFrame0: Mat4;\n /** Joint frame in the child (body1) local space. */\n jointFrame1: Mat4;\n};\n\nexport type JointRelativeDecomposition = {\n /** Joint value along the DOF (radians / stage length units; `0` for fixed). */\n q: number;\n /** Translation residual at the joint anchor (stage linear units). */\n anchorError: number;\n /** Rotation residual off the DOF (radians). */\n axisError: number;\n};\n\nconst AXIS_INDEX = { X: 0, Y: 1, Z: 2 } as const;\n\n/** Decompose `inv(Wp)·Wc` against the joint's single-DOF model (see module docs). */\nexport function decomposeJointRelative(\n joint: JointDofInput,\n parentWorld: Mat4,\n childWorld: Mat4,\n): JointRelativeDecomposition {\n const d = multiplyAll([\n invert(joint.jointFrame0),\n invert(parentWorld),\n childWorld,\n joint.jointFrame1,\n ]);\n const t: [number, number, number] = [d[12]!, d[13]!, d[14]!];\n\n // Principal-branch (w ≥ 0) unit quaternion of D's rotation block.\n const { orientation } = decomposeRigid(d);\n const sign = orientation.real < 0 ? -1 : 1;\n const w = sign * orientation.real;\n const vx = sign * orientation.imaginary[0];\n const vy = sign * orientation.imaginary[1];\n const vz = sign * orientation.imaginary[2];\n const rotationAngle = 2 * Math.atan2(Math.hypot(vx, vy, vz), w);\n\n const i = AXIS_INDEX[joint.axis];\n if (joint.type === \"prismatic\") {\n const anchor = Math.hypot(i === 0 ? 0 : t[0], i === 1 ? 0 : t[1], i === 2 ? 0 : t[2]);\n return { q: t[i], anchorError: anchor, axisError: rotationAngle };\n }\n if (joint.type === \"fixed\") {\n return { q: 0, anchorError: Math.hypot(...t), axisError: rotationAngle };\n }\n\n // Revolute / continuous — swing–twist about the axis: the twist is the joint\n // value, the swing is the violation. With d normalized and w ≥ 0 the twist\n // is (w, proj·axis)/‖(w, proj)‖ and cos(swing/2) = ‖(w, proj)‖.\n const proj = i === 0 ? vx : i === 1 ? vy : vz;\n const twistNorm = Math.hypot(w, proj);\n const q = twistNorm > 1e-12 ? 2 * Math.atan2(proj, w) : 0;\n const swing = 2 * Math.atan2(Math.sqrt(Math.max(0, 1 - twistNorm * twistNorm)), twistNorm);\n return { q, anchorError: Math.hypot(...t), axisError: swing };\n}\n\n/**\n * Move `q` to the 2πk branch nearest `previous` — frame-to-frame continuity\n * past ±π for revolute/continuous joints (`opts.previous` of\n * `jointValuesFromLinkTransforms`).\n */\nexport function nearestAngleBranch(q: number, previous: number): number {\n const TWO_PI = 2 * Math.PI;\n return q + TWO_PI * Math.round((previous - q) / TWO_PI);\n}\n","/**\n * Time-sample interpolation for animated values (e.g. joint trajectories).\n *\n * USD time samples are keyed by time code. We linearly interpolate between the\n * two bracketing samples and hold the endpoints outside the authored range\n * (matching USD's held extrapolation).\n */\n\n/** A sorted time-sampled scalar channel. */\nexport type SampleChannel = {\n /** Sample times, ascending. */\n times: number[];\n /** Sample values, parallel to {@link times} (SI units). */\n values: number[];\n};\n\n/** Linearly sample `channel` at time `t` (held outside the range). */\nexport function interpolate(channel: SampleChannel, t: number): number {\n const { times, values } = channel;\n const n = times.length;\n if (n === 0) return 0;\n if (t <= times[0]!) return values[0]!;\n if (t >= times[n - 1]!) return values[n - 1]!;\n\n // Binary search for the first sample time > t.\n let lo = 0;\n let hi = n - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (times[mid]! <= t) lo = mid + 1;\n else hi = mid;\n }\n const i = lo - 1; // times[i] <= t < times[i+1]\n const t0 = times[i]!;\n const t1 = times[i + 1]!;\n const span = t1 - t0;\n const f = span > 0 ? (t - t0) / span : 0;\n return values[i]! + (values[i + 1]! - values[i]!) * f;\n}\n\n/** Build a sorted {@link SampleChannel} from `(time → value)` pairs via `map`. */\nexport function channelFromSamples(samples: Map<number, number>): SampleChannel {\n const times = [...samples.keys()].sort((a, b) => a - b);\n const values = times.map((t) => samples.get(t) ?? 0);\n return { times, values };\n}\n"]}
@@ -1,4 +1,5 @@
1
- import { identity4, multiply, invert, nearestAngleBranch, multiplyAll, decomposeJointRelative, interpolate } from './chunk-YGJ23CG3.js';
1
+ import { nearestAngleBranch, decomposeJointRelative, interpolate } from './chunk-ALC7RBKC.js';
2
+ import { identity4, multiply, invert, multiplyAll } from './chunk-IAOPNN6V.js';
2
3
  import * as THREE4 from 'three';
3
4
 
4
5
  function axisVector(axis) {
@@ -87,6 +88,38 @@ var ThreeUsdRobot = class extends THREE4.Object3D {
87
88
  * {@link ThreeUsdRobotLoader}; `undefined` for programmatically-built robots.
88
89
  */
89
90
  stage;
91
+ /**
92
+ * UsdLux lights bound from the stage (M25), already attached into this
93
+ * hierarchy; each carries `userData.primPath` and `userData.usdLight` (its
94
+ * resolved description). Populated by {@link ThreeUsdRobotLoader} unless
95
+ * `loadLights: false`.
96
+ */
97
+ lights = [];
98
+ /**
99
+ * DomeLights parsed from the stage (M25). Not realized as Three.js lights —
100
+ * they describe an image-based environment; apply one with
101
+ * `applyUsdEnvironment` from `three-usd-robot/rendering` (M26).
102
+ */
103
+ domeLights = [];
104
+ /**
105
+ * `UsdGeomCamera` prims bound from the stage (M27), hierarchy-attached so a
106
+ * sensor camera on a link follows the joints. Each carries
107
+ * `userData.primPath` and `userData.usdCamera`; fit one to a viewport with
108
+ * `conformCameraAspect`. Populated by {@link ThreeUsdRobotLoader} unless
109
+ * `loadCameras: false`.
110
+ */
111
+ cameras = [];
112
+ /**
113
+ * Asset-resolution context captured at load (M26) — lets
114
+ * `three-usd-robot/rendering` fetch referenced images (dome HDRIs, including
115
+ * entries inside a `.usdz` package). Set by {@link ThreeUsdRobotLoader}.
116
+ */
117
+ assetContext;
118
+ /**
119
+ * The loader's `lightIntensityScale` (M26): `applyUsdEnvironment` defaults
120
+ * to it so the dome environment scales consistently with the bound lights.
121
+ */
122
+ lightIntensityScale;
90
123
  linkObjects = /* @__PURE__ */ new Map();
91
124
  jointObjects = /* @__PURE__ */ new Map();
92
125
  linkKeyByPath = /* @__PURE__ */ new Map();
@@ -784,5 +817,5 @@ function setMatrix(obj, m) {
784
817
  }
785
818
 
786
819
  export { JointObject, LinkObject, ThreeUsdRobot, axisVector };
787
- //# sourceMappingURL=chunk-JN2QPDB3.js.map
788
- //# sourceMappingURL=chunk-JN2QPDB3.js.map
820
+ //# sourceMappingURL=chunk-HDZGWL6P.js.map
821
+ //# sourceMappingURL=chunk-HDZGWL6P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/three/axis.ts","../src/three/JointObject.ts","../src/three/LinkObject.ts","../src/three/ThreeUsdRobot.ts"],"names":["THREE","THREE2","THREE3"],"mappings":"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","file":"chunk-HDZGWL6P.js","sourcesContent":["import * as THREE from \"three\";\nimport type { Axis } from \"../robot/RobotDescription.js\";\n\n/** Unit vector for a USD joint axis token. Returns a fresh vector each call. */\nexport function axisVector(axis: Axis): THREE.Vector3 {\n switch (axis) {\n case \"X\":\n return new THREE.Vector3(1, 0, 0);\n case \"Y\":\n return new THREE.Vector3(0, 1, 0);\n case \"Z\":\n return new THREE.Vector3(0, 0, 1);\n }\n}\n","import * as THREE from \"three\";\nimport type {\n Axis,\n JointDescription,\n JointMimicDescription,\n JointType,\n} from \"../robot/RobotDescription.js\";\nimport { axisVector } from \"./axis.js\";\n\n/**\n * The articulated \"motion\" node of a joint, inserted between the joint's two\n * fixed frames (`jointFrame0` and `inverse(jointFrame1)`). {@link setValue}\n * rotates it about the axis (revolute/continuous) or slides it along the axis\n * (prismatic); fixed joints are inert.\n */\nexport class JointObject extends THREE.Object3D {\n readonly isJointObject = true;\n readonly jointName: string;\n /** Full USD prim path of the joint — the collision-proof address. */\n readonly primPath: string;\n readonly jointType: JointType;\n readonly axisToken: Axis;\n readonly axis: THREE.Vector3;\n readonly lower: number | undefined;\n readonly upper: number | undefined;\n /** Mimic constraint this joint follows, if any (see {@link JointMimicDescription}). */\n readonly mimic: JointMimicDescription | undefined;\n\n private _value = 0;\n\n constructor(joint: JointDescription) {\n super();\n this.name = joint.name;\n this.jointName = joint.name;\n this.primPath = joint.primPath;\n this.jointType = joint.type;\n this.axisToken = joint.axis;\n this.axis = axisVector(joint.axis);\n this.lower = joint.lower;\n this.upper = joint.upper;\n this.mimic = joint.mimic;\n }\n\n get value(): number {\n return this._value;\n }\n\n get articulated(): boolean {\n return this.jointType !== \"fixed\";\n }\n\n /**\n * Set the joint value (radians for revolute/continuous, length for prismatic).\n * Optionally clamps to authored limits. Returns the value actually applied.\n */\n setValue(value: number, clampToLimits = true): number {\n if (!this.articulated) return this._value; // fixed joint: inert\n\n let v = value;\n if (clampToLimits) {\n if (this.lower !== undefined && v < this.lower) v = this.lower;\n if (this.upper !== undefined && v > this.upper) v = this.upper;\n }\n this._value = v;\n\n if (this.jointType === \"prismatic\") {\n this.position.copy(this.axis).multiplyScalar(v);\n this.quaternion.identity();\n } else {\n this.quaternion.setFromAxisAngle(this.axis, v);\n this.position.set(0, 0, 0);\n }\n return v;\n }\n}\n","import * as THREE from \"three\";\nimport type { LinkDescription } from \"../robot/RobotDescription.js\";\n\n/**\n * Three.js node for a robot link. Its frame is the USD link prim's frame;\n * visual/collision meshes (M6) attach as children relative to it. Placement\n * relative to the parent is supplied by the joint chain, so a link's own local\n * matrix is identity (except the root, which carries the world-fixed placement).\n */\nexport class LinkObject extends THREE.Object3D {\n readonly isLinkObject = true;\n readonly linkName: string;\n readonly primPath: string;\n\n constructor(link: LinkDescription) {\n super();\n this.name = link.name;\n this.linkName = link.name;\n this.primPath = link.primPath;\n // Placement comes from the parent joint chain; keep the local matrix fixed.\n this.matrixAutoUpdate = false;\n }\n}\n","import * as THREE from \"three\";\nimport {\n type JointRelativeDecomposition,\n decomposeJointRelative,\n nearestAngleBranch,\n} from \"../kinematics/jointResiduals.js\";\nimport { interpolate } from \"../kinematics/sampling.js\";\nimport { type Mat4, identity4, invert, multiply, multiplyAll } from \"../kinematics/transforms.js\";\nimport type {\n JointDescription,\n LinkDescription,\n RobotDescription,\n} from \"../robot/RobotDescription.js\";\nimport type { KinematicTree } from \"../robot/buildKinematicTree.js\";\nimport type { LightDescription } from \"../schemas/usdLux.js\";\nimport type { AssetResolver } from \"../usd/AssetResolver.js\";\nimport type { Stage } from \"../usd/Stage.js\";\nimport type { UsdBoundCamera } from \"./CameraBinding.js\";\nimport { JointObject } from \"./JointObject.js\";\nimport { LinkObject } from \"./LinkObject.js\";\n\n/** Target world up-axis: normalize to Y-up / Z-up, or keep the authored orientation. */\nexport type WorldUpAxis = \"Y\" | \"Z\" | \"keep\";\n\nexport type ThreeUsdRobotOptions = {\n /** Clamp `setJointValue` to authored limits (default `true`). */\n clampJointLimits?: boolean;\n /** Size of the built-in joint-axis / link-frame helpers (stage units, default `0.15`). */\n helperSize?: number;\n /**\n * Target world up-axis. The root is rotated so the stage's authored `upAxis`\n * lands in that convention: `\"Y\"` for a standard three.js scene, `\"Z\"` for a\n * robotics-style Z-up world, `\"keep\"` for no correction. Takes precedence\n * over the deprecated {@link ThreeUsdRobotOptions.upAxisConversion}.\n */\n worldUp?: WorldUpAxis;\n /**\n * Legacy up-axis correction: `\"auto\"` ≡ `worldUp: \"Y\"`, `\"Y\"` / `\"none\"` ≡\n * `worldUp: \"keep\"`, and `\"Z\"` forces the Z-up→Y-up rotation regardless of\n * stage metadata. Default `\"none\"` (the loader defaults to `\"auto\"`).\n * @deprecated Use {@link ThreeUsdRobotOptions.worldUp}.\n */\n upAxisConversion?: \"auto\" | \"Y\" | \"Z\" | \"none\";\n /** Extra uniform scale multiplied with the stage `metersPerUnit` (default `1`). */\n unitScale?: number;\n /** Seed joints from their authored initial value (drive target / joint state). Default `true`. */\n applyInitialPose?: boolean;\n /**\n * Diagnose {@link ThreeUsdRobot.setLinkTransforms} poses against the joint\n * constraints and `console.warn` once per baked session when one deviates\n * beyond tolerance (default 1 mm anchor / 0.01 rad axis). `true` uses the\n * defaults; pass an object to tune them.\n */\n debugBakedTransforms?: boolean | { anchorTolerance?: number; axisTolerance?: number };\n};\n\n/**\n * A rigid world pose for {@link ThreeUsdRobot.setLinkTransforms} —\n * `quaternion` in Three.js `[x, y, z, w]` order (USD authors quatf as\n * `(w, x, y, z)`; reorder when reading recorded USD by hand).\n */\nexport type LinkPose = {\n position: [number, number, number];\n quaternion: [number, number, number, number];\n};\n\n/**\n * Coordinate space of {@link LinkPose} batches. `\"world\"` (default) is the\n * Three.js scene world *after* `worldUp` / unit normalization — with\n * `worldUp: \"Z\"` you hand in Z-up poses — including any transform on the\n * robot object itself (which must stay a similarity: uniform scale, no\n * shear). `\"stage\"` is the authored USD stage space (before up-axis rotation\n * and `metersPerUnit` scaling), as prim world transforms are written in the\n * file.\n */\nexport type LinkPoseSpace = \"world\" | \"stage\";\n\nexport type LinkPosesOptions = {\n /** Interpretation of the poses (default `\"world\"`). */\n space?: LinkPoseSpace;\n};\n\nexport type JointValuesFromLinkTransformsOptions = LinkPosesOptions & {\n /**\n * Previous joint values (keyed like the returned `values`): each\n * revolute/continuous joint picks the 2πk branch of its projection nearest\n * this, for frame-to-frame continuity past ±π.\n */\n previous?: Record<string, number>;\n /** Clamp `values` to authored limits (default `false` — deviations are reported, not hidden). */\n clampLimits?: boolean;\n};\n\n/**\n * Per-joint constraint residual of a link-pose batch, keyed by joint prim\n * path. The ideal parent→child transform of a joint is a pure motion along\n * its DOF; whatever the poses leave over splits into `anchorError` /\n * `axisError` (see {@link ThreeUsdRobot.validateLinkTransforms}).\n */\nexport type JointResidual = {\n /** Translation residual at the joint anchor, in meters (`metersPerUnit` applied). */\n anchorError: number;\n /** Rotation residual off the joint DOF, in radians. */\n axisError: number;\n /** Projected joint value (SI: radians / stage length units; `0` for fixed joints). */\n q: number;\n /** Whether `q` lies outside the authored limits. */\n limitExceeded: boolean;\n};\n\n/**\n * A Three.js `Object3D` that realizes a {@link RobotDescription} as a kinematic\n * hierarchy and drives forward kinematics via {@link setJointValue}.\n *\n * Per joint the hierarchy is\n * `parentLink → jointFrame0 → jointMotion → jointFrame1⁻¹ → childLink`,\n * where only `jointMotion` (a {@link JointObject}) changes with the joint value;\n * world poses then fall out of Three.js's `updateMatrixWorld`.\n *\n * **Naming contract** — a link/joint's key is its prim's leaf name when that\n * is unique across the robot, else its full prim path (deterministic; see the\n * extractor). Every accessor taking a name equally accepts the full prim path,\n * which is stable regardless of collisions; {@link getLinkObjectsByPath} /\n * {@link getJointObjectsByPath} enumerate the path-keyed tables.\n */\nexport class ThreeUsdRobot extends THREE.Object3D {\n readonly isThreeUsdRobot = true;\n readonly robot: RobotDescription;\n readonly tree: KinematicTree;\n readonly clampJointLimits: boolean;\n /**\n * The composed USD stage this robot was built from — the full prim tree, for\n * inspection tooling (structure panels, attribute browsers). Attached by\n * {@link ThreeUsdRobotLoader}; `undefined` for programmatically-built robots.\n */\n stage?: Stage;\n /**\n * UsdLux lights bound from the stage (M25), already attached into this\n * hierarchy; each carries `userData.primPath` and `userData.usdLight` (its\n * resolved description). Populated by {@link ThreeUsdRobotLoader} unless\n * `loadLights: false`.\n */\n lights: THREE.Light[] = [];\n /**\n * DomeLights parsed from the stage (M25). Not realized as Three.js lights —\n * they describe an image-based environment; apply one with\n * `applyUsdEnvironment` from `three-usd-robot/rendering` (M26).\n */\n domeLights: LightDescription[] = [];\n /**\n * `UsdGeomCamera` prims bound from the stage (M27), hierarchy-attached so a\n * sensor camera on a link follows the joints. Each carries\n * `userData.primPath` and `userData.usdCamera`; fit one to a viewport with\n * `conformCameraAspect`. Populated by {@link ThreeUsdRobotLoader} unless\n * `loadCameras: false`.\n */\n cameras: UsdBoundCamera[] = [];\n /**\n * Asset-resolution context captured at load (M26) — lets\n * `three-usd-robot/rendering` fetch referenced images (dome HDRIs, including\n * entries inside a `.usdz` package). Set by {@link ThreeUsdRobotLoader}.\n */\n assetContext?: { resolver: AssetResolver; baseUrl: string };\n /**\n * The loader's `lightIntensityScale` (M26): `applyUsdEnvironment` defaults\n * to it so the dome environment scales consistently with the bound lights.\n */\n lightIntensityScale?: number;\n\n private readonly linkObjects = new Map<string, LinkObject>();\n private readonly jointObjects = new Map<string, JointObject>();\n private readonly linkKeyByPath = new Map<string, string>();\n private readonly jointKeyByPath = new Map<string, string>();\n /** Mimic edges among realized joints: leader key → followers. */\n private readonly mimicFollowers = new Map<\n string,\n { key: string; multiplier: number; offset: number }[]\n >();\n private readonly mimicLeaderByFollower = new Map<string, string>();\n private warnedMimicDrive = false;\n private dirty = true;\n\n /** Constructed (fk rest) local matrix of every link, for baked→fk restore. */\n private readonly restLocal = new Map<string, Mat4>();\n private _displayMode: \"fk\" | \"baked\" = \"fk\";\n /** Stage-space link worlds while baked (`null` in fk mode). */\n private bakedStageWorld: Map<string, Mat4> | null = null;\n /** Frozen `frame0 · motion · frame1⁻¹` per tree joint while baked. */\n private bakedChainRel: Map<string, Mat4> | null = null;\n private readonly debugBaked: { anchorTolerance: number; axisTolerance: number } | null;\n private bakedDebugWarned = false;\n private readonly warnedPoseKeys = new Set<string>();\n private warnedNonUniformScale = false;\n\n private readonly helperSize: number;\n private _showVisual = true;\n private _showCollision = false;\n private _showJointAxes = false;\n private _showLinkFrames = false;\n private jointAxesHelpers: THREE.AxesHelper[] = [];\n private linkFrameHelpers: THREE.AxesHelper[] = [];\n\n constructor(robot: RobotDescription, tree: KinematicTree, options: ThreeUsdRobotOptions = {}) {\n super();\n this.name = robot.name;\n this.robot = robot;\n this.tree = tree;\n this.clampJointLimits = options.clampJointLimits ?? true;\n this.helperSize = options.helperSize ?? 0.15;\n\n // Create a node for every link up front; index links and joints by path.\n for (const [key, link] of Object.entries(robot.links)) {\n this.linkObjects.set(key, new LinkObject(link));\n this.linkKeyByPath.set(link.primPath, key);\n }\n for (const [key, joint] of Object.entries(robot.joints)) {\n this.jointKeyByPath.set(joint.primPath, key);\n }\n\n this.attachRoot();\n this.attachTreeEdges();\n this.attachIsolatedLinks();\n this.registerMimicFollowers();\n this.applyStageNormalization(robot, options);\n if (options.applyInitialPose ?? true) this.applyInitialPose(robot);\n this.propagateAllMimic();\n\n for (const [key, obj] of this.linkObjects) this.restLocal.set(key, obj.matrix.toArray());\n const debug = options.debugBakedTransforms;\n this.debugBaked = debug\n ? {\n anchorTolerance: (typeof debug === \"object\" ? debug.anchorTolerance : undefined) ?? 1e-3,\n axisTolerance: (typeof debug === \"object\" ? debug.axisTolerance : undefined) ?? 0.01,\n }\n : null;\n }\n\n /** Orient (authored upAxis → target world up) and scale (metersPerUnit × unitScale) the root. */\n private applyStageNormalization(robot: RobotDescription, options: ThreeUsdRobotOptions): void {\n const scale = (robot.metersPerUnit || 1) * (options.unitScale ?? 1);\n if (scale !== 1) this.scale.setScalar(scale);\n\n const rotateX = (angle: number) =>\n this.quaternion.setFromAxisAngle(new THREE.Vector3(1, 0, 0), angle);\n\n if (options.worldUp) {\n if (options.worldUp === \"Y\" && robot.upAxis === \"Z\") rotateX(-Math.PI / 2);\n else if (options.worldUp === \"Z\" && robot.upAxis === \"Y\") rotateX(Math.PI / 2);\n return; // matching axis or \"keep\": leave as authored\n }\n const conv = options.upAxisConversion ?? \"none\";\n if (conv === \"Z\" || (conv === \"auto\" && robot.upAxis === \"Z\")) rotateX(-Math.PI / 2);\n }\n\n /** Apply each joint's authored initial value, if any. */\n private applyInitialPose(robot: RobotDescription): void {\n for (const [key, joint] of Object.entries(robot.joints)) {\n if (joint.initialValue === undefined) continue;\n this.jointObjects.get(key)?.setValue(joint.initialValue, this.clampJointLimits);\n }\n this.dirty = true;\n }\n\n // -- Mimic joints ---------------------------------------------------------\n\n /** Index the mimic edges realized in the tree (leader and follower both driven). */\n private registerMimicFollowers(): void {\n for (const [key, joint] of Object.entries(this.robot.joints)) {\n const mimic = joint.mimic;\n if (!mimic || !this.jointObjects.has(key)) continue;\n const leaderKey = this.jointKey(mimic.joint);\n // A leader outside the fk tree (loop joint) cannot drive; leave the\n // follower independently commandable.\n if (!this.jointObjects.has(leaderKey)) continue;\n this.mimicLeaderByFollower.set(key, leaderKey);\n const list = this.mimicFollowers.get(leaderKey) ?? [];\n list.push({ key, multiplier: mimic.multiplier, offset: mimic.offset });\n this.mimicFollowers.set(leaderKey, list);\n }\n }\n\n /** Drive the followers of `leaderKey` from its current value (recursive, cycle-safe). */\n private propagateMimic(leaderKey: string, visited?: Set<string>): void {\n const followers = this.mimicFollowers.get(leaderKey);\n if (!followers) return;\n const leaderValue = this.jointObjects.get(leaderKey)?.value;\n if (leaderValue === undefined) return;\n const seen = visited ?? new Set([leaderKey]);\n for (const { key, multiplier, offset } of followers) {\n if (seen.has(key)) continue; // cycle — reported by the validator\n seen.add(key);\n this.jointObjects\n .get(key)\n ?.setValue(multiplier * leaderValue + offset, this.clampJointLimits);\n this.propagateMimic(key, seen);\n }\n }\n\n /** Re-derive every follower from its chain's top-most leader. */\n private propagateAllMimic(): void {\n for (const leaderKey of this.mimicFollowers.keys()) {\n if (!this.mimicLeaderByFollower.has(leaderKey)) this.propagateMimic(leaderKey);\n }\n if (this.mimicFollowers.size > 0) this.dirty = true;\n }\n\n /** Whether the joint (key or prim path) is a mimic follower, driven by its leader. */\n isMimicFollower(name: string): boolean {\n return this.mimicLeaderByFollower.has(this.jointKey(name));\n }\n\n /** Keys of the mimic-follower joints (excluded from {@link getJointNames}). */\n getMimicJointNames(): string[] {\n return [...this.mimicLeaderByFollower.keys()];\n }\n\n private warnMimicDriveOnce(key: string): void {\n if (this.warnedMimicDrive) return;\n this.warnedMimicDrive = true;\n const leader = this.mimicLeaderByFollower.get(key);\n console.warn(\n `three-usd-robot: \"${key}\" is a mimic follower of \"${leader}\" — its value derives from the leader; direct sets are ignored (warned once)`,\n );\n }\n\n private attachRoot(): void {\n const rootObj = this.linkObjects.get(this.tree.root);\n if (!rootObj) return; // empty robot\n const rootJointKey = this.tree.rootJoint;\n const rootLink = this.robot.links[this.tree.root];\n if (rootJointKey) {\n const j = this.robot.joints[rootJointKey];\n // World-fixed placement: jointFrame0 (in world) · inverse(jointFrame1).\n if (j) setMatrix(rootObj, multiply(j.jointFrame0, invert(j.jointFrame1)));\n } else if (rootLink?.worldTransform) {\n // Floating base: keep the authored stage placement.\n setMatrix(rootObj, rootLink.worldTransform);\n }\n this.add(rootObj);\n }\n\n private attachTreeEdges(): void {\n for (const linkKey of this.tree.order) {\n const node = this.tree.nodes[linkKey];\n if (!node || node.parent === null || node.jointToParent === null) continue;\n\n const parentObj = this.linkObjects.get(node.parent);\n const childObj = this.linkObjects.get(linkKey);\n const joint = this.robot.joints[node.jointToParent];\n if (!parentObj || !childObj || !joint) continue;\n\n this.attachJointChain(parentObj, childObj, node.jointToParent, joint);\n }\n }\n\n /** Build `parent → frame0 → motion → frame1⁻¹ → child` for one joint. */\n private attachJointChain(\n parent: LinkObject,\n child: LinkObject,\n jointKey: string,\n joint: JointDescription,\n ): void {\n const frame0 = new THREE.Group();\n frame0.name = `${joint.name}:frame0`;\n setMatrix(frame0, joint.jointFrame0);\n\n const motion = new JointObject(joint);\n\n const frame1Inv = new THREE.Group();\n frame1Inv.name = `${joint.name}:frame1Inv`;\n setMatrix(frame1Inv, invert(joint.jointFrame1));\n\n parent.add(frame0);\n frame0.add(motion);\n motion.add(frame1Inv);\n frame1Inv.add(child);\n\n this.jointObjects.set(jointKey, motion);\n }\n\n private attachIsolatedLinks(): void {\n for (const key of this.tree.isolatedLinks) {\n const obj = this.linkObjects.get(key);\n if (!obj || obj.parent) continue;\n // Not placeable by any joint chain — keep the authored stage placement\n // (other machines / free bodies on a multi-articulation stage).\n const worldTransform = this.robot.links[key]?.worldTransform;\n if (worldTransform) setMatrix(obj, worldTransform);\n this.add(obj);\n }\n }\n\n // -- Naming --------------------------------------------------------------\n\n /** Resolve a link reference — key or full prim path — to the extractor key. */\n private linkKey(ref: string): string {\n if (this.linkObjects.has(ref)) return ref;\n return this.linkKeyByPath.get(ref) ?? ref;\n }\n\n /** Resolve a joint reference — key or full prim path — to the extractor key. */\n private jointKey(ref: string): string {\n if (this.jointObjects.has(ref)) return ref;\n return this.jointKeyByPath.get(ref) ?? ref;\n }\n\n // -- Joint control -------------------------------------------------------\n\n /**\n * Set one joint value, addressed by key or full prim path. Unknown joints\n * are ignored, and so are mimic followers (their value derives from the\n * leader; a warning is logged once). Driving a leader also updates its\n * followers. Returns whether it applied. Always restores `\"fk\"` display\n * mode first (see {@link setLinkTransforms}).\n */\n setJointValue(name: string, value: number): boolean {\n this.exitBakedMode();\n const key = this.jointKey(name);\n if (this.mimicLeaderByFollower.has(key)) {\n this.warnMimicDriveOnce(key);\n return false;\n }\n const joint = this.jointObjects.get(key);\n if (!joint) return false;\n joint.setValue(value, this.clampJointLimits);\n this.propagateMimic(key);\n this.dirty = true;\n return true;\n }\n\n /**\n * Set several joint values at once (matrix update is coalesced). Mimic\n * followers in the batch are skipped like in {@link setJointValue}. Always\n * restores `\"fk\"` display mode first, recomputing every link purely from\n * joint values — even an empty batch returns from baked playback (see\n * {@link setLinkTransforms}).\n */\n setJointValues(values: Record<string, number>): void {\n this.exitBakedMode();\n for (const [name, value] of Object.entries(values)) {\n const key = this.jointKey(name);\n if (this.mimicLeaderByFollower.has(key)) {\n this.warnMimicDriveOnce(key);\n continue;\n }\n const joint = this.jointObjects.get(key);\n if (joint) {\n joint.setValue(value, this.clampJointLimits);\n this.propagateMimic(key);\n this.dirty = true;\n }\n }\n }\n\n getJointValue(name: string): number | undefined {\n return this.jointObjects.get(this.jointKey(name))?.value;\n }\n\n /** Recompute world matrices. Called lazily by the getters; safe to call directly. */\n updateKinematics(): void {\n this.updateMatrixWorld(true);\n this.dirty = false;\n }\n\n private ensureUpdated(): void {\n if (this.dirty) this.updateKinematics();\n }\n\n // -- Baked link transforms (M23) -----------------------------------------\n\n /**\n * `\"fk\"` (default): link placements derive from joint values. `\"baked\"`:\n * {@link setLinkTransforms} wrote link poses directly and the joints no\n * longer constrain the display; any `setJointValue`-family call restores fk.\n */\n get displayMode(): \"fk\" | \"baked\" {\n return this._displayMode;\n }\n\n /**\n * Drive link world poses directly — the display path for baked recordings\n * (Isaac Sim body-transform time samples, maximal-coordinate playback).\n * usdview-like semantics: constraint deviations are shown, never corrected —\n * {@link validateLinkTransforms} measures them,\n * {@link jointValuesFromLinkTransforms} projects onto the joints instead.\n *\n * Enters `\"baked\"` display mode; joint values stay untouched. Return to fk\n * with {@link setJointValues} (any batch, even `{}`), which recomputes\n * every link purely from joint values.\n *\n * Keys are link keys or full prim paths; unknown keys warn once and are\n * skipped. Unspecified links KEEP their current world pose — a track that\n * omits a link means \"it did not move\". Poses are rigid, `quaternion` in\n * `[x, y, z, w]` order, interpreted per `opts.space` (default `\"world\"`:\n * the Three.js scene world after `worldUp` normalization — pair a Z-up\n * meter track with `worldUp: \"Z\"`). Matrix updates are coalesced into the\n * next render / world query. Returns the number of poses applied.\n */\n setLinkTransforms(poses: Record<string, LinkPose>, opts: LinkPosesOptions = {}): number {\n const targets = this.resolvePoseTargets(poses, opts.space ?? \"world\");\n if (this._displayMode !== \"baked\") this.enterBakedMode();\n const current = this.bakedStageWorld ?? new Map<string, Mat4>();\n const rels = this.bakedChainRel ?? new Map<string, Mat4>();\n\n // Rewrite every link's local matrix parents-first: written links land on\n // their target, held links keep their world pose while ancestors move.\n // The chain nodes in between stay frozen at their fk values; each link's\n // local absorbs the difference, so world matrices come out exact.\n const next = new Map<string, Mat4>();\n for (const key of this.tree.order) {\n const node = this.tree.nodes[key];\n const obj = this.linkObjects.get(key);\n if (!node || !obj) continue;\n const world = targets.get(key) ?? current.get(key);\n if (!world) continue;\n if (node.parent === null || node.jointToParent === null) {\n next.set(key, world); // the root's Object3D parent is the robot itself\n setMatrix(obj, world);\n continue;\n }\n const parentWorld = next.get(node.parent);\n const chainRel = rels.get(node.jointToParent);\n if (!parentWorld || !chainRel) continue;\n next.set(key, world);\n setMatrix(obj, multiply(invert(multiply(parentWorld, chainRel)), world));\n }\n for (const key of this.tree.isolatedLinks) {\n const obj = this.linkObjects.get(key);\n const world = targets.get(key) ?? current.get(key);\n if (!obj || !world) continue;\n next.set(key, world);\n setMatrix(obj, world);\n }\n\n this.bakedStageWorld = next;\n this.dirty = true;\n this.warnBakedDeviationOnce(next);\n return targets.size;\n }\n\n /**\n * Measure how far a link-pose batch deviates from the joint constraints,\n * without touching the display. Unspecified links resolve to their current\n * displayed pose, so the report predicts exactly what\n * {@link setLinkTransforms} with the same batch would show.\n *\n * Keyed by joint prim path; covers every joint — fixed joints (`q` = 0\n * check), loop joints dropped from the fk tree (closure error) and the\n * world-fixed root attachment (a moved base against a fixed-base model).\n * Typical signatures: a constant `anchorError` offset on every joint —\n * recording/model mismatch (wrong version or scale); growth over time —\n * maximal-coordinate solver drift; large uniform `axisError` — a\n * coordinate-convention bug (Y/Z-up or quaternion order).\n */\n validateLinkTransforms(\n poses: Record<string, LinkPose>,\n opts: LinkPosesOptions = {},\n ): Record<string, JointResidual> {\n const out: Record<string, JointResidual> = {};\n for (const { joint, rel } of this.decomposeJoints(poses, opts.space ?? \"world\")) {\n out[joint.primPath] = this.buildResidual(joint, rel.q, rel);\n }\n return out;\n }\n\n /**\n * Project a link-pose batch onto the joint manifold: the closed-form 1-DOF\n * joint values that best reproduce it, plus the same residuals as\n * {@link validateLinkTransforms}. `values` covers the commandable\n * articulated tree joints (mimic followers excluded — their leaders\n * re-derive them), keyed by joint prim path, and feeds\n * {@link setJointValues} directly — the constraint-respecting playback of\n * the same track:\n *\n * ```ts\n * robot.setJointValues(robot.jointValuesFromLinkTransforms(poses, { previous }).values);\n * ```\n *\n * Residual `q` / `limitExceeded` always report the unclamped projection,\n * also when `clampLimits` clamps `values`.\n */\n jointValuesFromLinkTransforms(\n poses: Record<string, LinkPose>,\n opts: JointValuesFromLinkTransformsOptions = {},\n ): { values: Record<string, number>; residuals: Record<string, JointResidual> } {\n const values: Record<string, number> = {};\n const residuals: Record<string, JointResidual> = {};\n for (const { key, joint, rel } of this.decomposeJoints(poses, opts.space ?? \"world\")) {\n let q = rel.q;\n if (joint.type === \"revolute\" || joint.type === \"continuous\") {\n const previous = opts.previous?.[joint.primPath] ?? opts.previous?.[key];\n if (previous !== undefined) q = nearestAngleBranch(q, previous);\n }\n residuals[joint.primPath] = this.buildResidual(joint, q, rel);\n if (!this.jointObjects.get(key)?.articulated) continue;\n // Followers are not commandable — the constraint re-derives them when\n // the returned values are fed to setJointValues.\n if (this.mimicLeaderByFollower.has(key)) continue;\n if (opts.clampLimits) {\n if (joint.lower !== undefined && q < joint.lower) q = joint.lower;\n if (joint.upper !== undefined && q > joint.upper) q = joint.upper;\n }\n values[joint.primPath] = q;\n }\n return { values, residuals };\n }\n\n /** Restore the constructed fk link placements (no-op when already `\"fk\"`). */\n private exitBakedMode(): void {\n if (this._displayMode === \"fk\") return;\n for (const [key, local] of this.restLocal) {\n const obj = this.linkObjects.get(key);\n if (obj) setMatrix(obj, local);\n }\n this.bakedStageWorld = null;\n this.bakedChainRel = null;\n this.bakedDebugWarned = false;\n this._displayMode = \"fk\";\n this.dirty = true;\n }\n\n /** Freeze the fk state a baked session builds on (joints cannot move while baked). */\n private enterBakedMode(): void {\n const rels = this.computeChainRels();\n this.bakedChainRel = rels;\n this.bakedStageWorld = this.computeStageWorlds(rels);\n this._displayMode = \"baked\";\n }\n\n /** `frame0 · motion(q) · frame1⁻¹` of every tree joint, from live joint values. */\n private computeChainRels(): Map<string, Mat4> {\n const rels = new Map<string, Mat4>();\n for (const [key, motion] of this.jointObjects) {\n const joint = this.robot.joints[key];\n if (!joint) continue;\n motion.updateMatrix();\n rels.set(\n key,\n multiplyAll([joint.jointFrame0, motion.matrix.toArray(), invert(joint.jointFrame1)]),\n );\n }\n return rels;\n }\n\n /** Stage-space world transform of every link under the current display state. */\n private computeStageWorlds(rels: Map<string, Mat4>): Map<string, Mat4> {\n const worlds = new Map<string, Mat4>();\n for (const key of this.tree.order) {\n const node = this.tree.nodes[key];\n const obj = this.linkObjects.get(key);\n if (!node || !obj) continue;\n const local = obj.matrix.toArray();\n if (node.parent === null || node.jointToParent === null) {\n worlds.set(key, local);\n continue;\n }\n const parentWorld = worlds.get(node.parent);\n const chainRel = rels.get(node.jointToParent);\n if (!parentWorld || !chainRel) continue;\n worlds.set(key, multiplyAll([parentWorld, chainRel, local]));\n }\n for (const key of this.tree.isolatedLinks) {\n const obj = this.linkObjects.get(key);\n if (obj) worlds.set(key, obj.matrix.toArray());\n }\n return worlds;\n }\n\n private currentStageWorlds(): Map<string, Mat4> {\n return this.bakedStageWorld ?? this.computeStageWorlds(this.computeChainRels());\n }\n\n /** Resolve pose keys to link keys and convert each pose to a rigid stage-space matrix. */\n private resolvePoseTargets(\n poses: Record<string, LinkPose>,\n space: LinkPoseSpace,\n ): Map<string, Mat4> {\n const targets = new Map<string, Mat4>();\n const entries = Object.entries(poses);\n if (entries.length === 0) return targets;\n\n const toStage = space === \"world\" ? this.sceneToStageConverter() : null;\n const position = new THREE.Vector3();\n const quaternion = new THREE.Quaternion();\n const matrix = new THREE.Matrix4();\n for (const [ref, pose] of entries) {\n const key = this.linkKey(ref);\n if (!this.linkObjects.has(key)) {\n this.warnUnknownPoseKey(ref);\n continue;\n }\n position.fromArray(pose.position);\n quaternion.fromArray(pose.quaternion).normalize();\n toStage?.(position, quaternion);\n targets.set(key, matrix.compose(position, quaternion, UNIT_SCALE).toArray());\n }\n return targets;\n }\n\n /**\n * Scene world → stage space, undoing the robot's own world transform\n * (up-axis rotation, unit scale, any user placement) as a similarity — so\n * link locals stay rigid and the root keeps carrying the scale.\n */\n private sceneToStageConverter(): (position: THREE.Vector3, quaternion: THREE.Quaternion) => void {\n this.updateWorldMatrix(true, false);\n const rootPosition = new THREE.Vector3();\n const rootQuaternion = new THREE.Quaternion();\n const rootScale = new THREE.Vector3();\n this.matrixWorld.decompose(rootPosition, rootQuaternion, rootScale);\n const s = rootScale.x;\n if (\n !this.warnedNonUniformScale &&\n (Math.abs(rootScale.y - s) > 1e-6 * Math.abs(s) ||\n Math.abs(rootScale.z - s) > 1e-6 * Math.abs(s))\n ) {\n this.warnedNonUniformScale = true;\n console.warn(\n `three-usd-robot: non-uniform world scale on \"${this.name}\"; space:\"world\" poses are off`,\n );\n }\n const invQuaternion = rootQuaternion.clone().invert();\n const invScale = s !== 0 ? 1 / s : 1;\n return (position, quaternion) => {\n position.sub(rootPosition).applyQuaternion(invQuaternion).multiplyScalar(invScale);\n quaternion.premultiply(invQuaternion);\n };\n }\n\n /**\n * Decompose every joint's parent→child transform under a pose batch\n * (unspecified links resolve to their current displayed pose, mirroring\n * {@link setLinkTransforms}). Pure — the display is untouched.\n */\n private decomposeJoints(\n poses: Record<string, LinkPose>,\n space: LinkPoseSpace,\n ): { key: string; joint: JointDescription; rel: JointRelativeDecomposition }[] {\n const worlds = new Map(this.currentStageWorlds());\n for (const [key, world] of this.resolvePoseTargets(poses, space)) worlds.set(key, world);\n\n const out: { key: string; joint: JointDescription; rel: JointRelativeDecomposition }[] = [];\n for (const [key, joint] of Object.entries(this.robot.joints)) {\n const childWorld = worlds.get(joint.child);\n const parentWorld = joint.parent === \"\" ? IDENTITY4 : worlds.get(joint.parent);\n if (!childWorld || !parentWorld) continue;\n out.push({ key, joint, rel: decomposeJointRelative(joint, parentWorld, childWorld) });\n }\n return out;\n }\n\n private buildResidual(\n joint: JointDescription,\n q: number,\n rel: JointRelativeDecomposition,\n ): JointResidual {\n return {\n anchorError: rel.anchorError * this.robot.metersPerUnit,\n axisError: rel.axisError,\n q,\n limitExceeded:\n (joint.lower !== undefined && q < joint.lower - LIMIT_EPS) ||\n (joint.upper !== undefined && q > joint.upper + LIMIT_EPS),\n };\n }\n\n private warnUnknownPoseKey(ref: string): void {\n if (this.warnedPoseKeys.has(ref)) return;\n this.warnedPoseKeys.add(ref);\n console.warn(`three-usd-robot: unknown link \"${ref}\" in a pose batch; ignoring`);\n }\n\n /** `debugBakedTransforms`: warn once per baked session when poses break the constraints. */\n private warnBakedDeviationOnce(worlds: Map<string, Mat4>): void {\n if (!this.debugBaked || this.bakedDebugWarned) return;\n const { anchorTolerance, axisTolerance } = this.debugBaked;\n let count = 0;\n let worst: { path: string; anchor: number; axis: number; score: number } | null = null;\n for (const joint of Object.values(this.robot.joints)) {\n const childWorld = worlds.get(joint.child);\n const parentWorld = joint.parent === \"\" ? IDENTITY4 : worlds.get(joint.parent);\n if (!childWorld || !parentWorld) continue;\n const rel = decomposeJointRelative(joint, parentWorld, childWorld);\n const anchor = rel.anchorError * this.robot.metersPerUnit;\n if (anchor <= anchorTolerance && rel.axisError <= axisTolerance) continue;\n count++;\n const score = anchor / anchorTolerance + rel.axisError / axisTolerance;\n if (!worst || score > worst.score) {\n worst = { path: joint.primPath, anchor, axis: rel.axisError, score };\n }\n }\n if (!worst) return;\n this.bakedDebugWarned = true;\n console.warn(\n `three-usd-robot: baked poses deviate from ${count} joint constraint(s) — worst ` +\n `${worst.path}: anchor ${(worst.anchor * 1e3).toFixed(3)} mm, axis ` +\n `${worst.axis.toFixed(4)} rad (recording/model mismatch? warned once per baked session)`,\n );\n }\n\n // -- Queries -------------------------------------------------------------\n\n /** World matrix of a link, addressed by key or full prim path. */\n getLinkWorldMatrix(name: string): THREE.Matrix4 {\n const obj = this.linkObjects.get(this.linkKey(name));\n if (!obj) throw new Error(`unknown link \"${name}\"`);\n this.ensureUpdated();\n return obj.matrixWorld.clone();\n }\n\n getLinkWorldPosition(name: string): THREE.Vector3 {\n return new THREE.Vector3().setFromMatrixPosition(this.getLinkWorldMatrix(name));\n }\n\n /** Link object by key or full prim path. */\n getLinkObject(name: string): LinkObject | undefined {\n return this.linkObjects.get(this.linkKey(name));\n }\n\n /** Joint object by key or full prim path. */\n getJointObject(name: string): JointObject | undefined {\n return this.jointObjects.get(this.jointKey(name));\n }\n\n /**\n * Table of link prim path → {@link LinkObject}. Prim paths are the\n * collision-proof way to pin a link (e.g. to attach tools or gizmos).\n */\n getLinkObjectsByPath(): Map<string, LinkObject> {\n const out = new Map<string, LinkObject>();\n for (const [path, key] of this.linkKeyByPath) {\n const obj = this.linkObjects.get(key);\n if (obj) out.set(path, obj);\n }\n return out;\n }\n\n /**\n * Table of joint prim path → {@link JointObject}, covering the joints\n * realized in the kinematic tree (loop joints have no motion node).\n */\n getJointObjectsByPath(): Map<string, JointObject> {\n const out = new Map<string, JointObject>();\n for (const [path, key] of this.jointKeyByPath) {\n const obj = this.jointObjects.get(key);\n if (obj) out.set(path, obj);\n }\n return out;\n }\n\n getJoints(): JointDescription[] {\n return Object.values(this.robot.joints);\n }\n\n getLinks(): LinkDescription[] {\n return Object.values(this.robot.links);\n }\n\n /**\n * Names of the commandable joints — articulated tree joints minus mimic\n * followers, whose values derive from their leader\n * (see {@link getMimicJointNames}).\n */\n getJointNames(): string[] {\n return [...this.jointObjects.keys()].filter((key) => !this.mimicLeaderByFollower.has(key));\n }\n\n getLinkNames(): string[] {\n return [...this.linkObjects.keys()];\n }\n\n getKinematicTree(): KinematicTree {\n return this.tree;\n }\n\n /** Authored stage up-axis (`\"Y\"` or `\"Z\"`) — unaffected by `worldUp` normalization. */\n get upAxis(): \"Y\" | \"Z\" {\n return this.robot.upAxis;\n }\n\n /** Authored stage scale in meters per unit (already applied to the root). */\n get metersPerUnit(): number {\n return this.robot.metersPerUnit;\n }\n\n // -- Animation playback --------------------------------------------------\n\n /** Playback rate in time codes per second (from the stage; default 24). */\n getTimeCodesPerSecond(): number {\n return this.robot.timeCodesPerSecond ?? 24;\n }\n\n /** Whether any joint has a time-sampled trajectory. */\n hasAnimation(): boolean {\n return Object.values(this.robot.joints).some((j) => j.valueSamples !== undefined);\n }\n\n /**\n * Animation range in time codes: the union of authored joint sample ranges,\n * falling back to the stage `startTimeCode`/`endTimeCode`. `null` if neither.\n */\n getTimeRange(): { start: number; end: number } | null {\n let start = Number.POSITIVE_INFINITY;\n let end = Number.NEGATIVE_INFINITY;\n for (const joint of Object.values(this.robot.joints)) {\n const times = joint.valueSamples?.times;\n if (!times || times.length === 0) continue;\n start = Math.min(start, times[0]!);\n end = Math.max(end, times[times.length - 1]!);\n }\n if (start <= end) return { start, end };\n\n const { startTimeCode, endTimeCode } = this.robot;\n if (startTimeCode !== undefined && endTimeCode !== undefined) {\n return { start: startTimeCode, end: endTimeCode };\n }\n return null;\n }\n\n /**\n * Sample every animated joint at time code `t` and apply the values (an fk\n * drive — leaves baked mode). Samples on mimic followers are ignored; the\n * constraint re-derives them from their leader.\n */\n setTime(t: number): void {\n this.exitBakedMode();\n for (const [key, joint] of Object.entries(this.robot.joints)) {\n if (!joint.valueSamples || this.mimicLeaderByFollower.has(key)) continue;\n this.setJointValue(key, interpolate(joint.valueSamples, t));\n }\n }\n\n // -- Display toggles -----------------------------------------------------\n\n get showVisual(): boolean {\n return this._showVisual;\n }\n set showVisual(v: boolean) {\n this._showVisual = v;\n this.setKindVisibility(\"visual\", v);\n }\n\n get showCollision(): boolean {\n return this._showCollision;\n }\n set showCollision(v: boolean) {\n this._showCollision = v;\n this.setKindVisibility(\"collision\", v);\n }\n\n get showJointAxes(): boolean {\n return this._showJointAxes;\n }\n set showJointAxes(v: boolean) {\n this._showJointAxes = v;\n if (v && this.jointAxesHelpers.length === 0) {\n for (const joint of this.jointObjects.values()) {\n const h = new THREE.AxesHelper(this.helperSize);\n h.name = `${joint.jointName}:axes`;\n joint.add(h);\n this.jointAxesHelpers.push(h);\n }\n }\n for (const h of this.jointAxesHelpers) h.visible = v;\n }\n\n get showLinkFrames(): boolean {\n return this._showLinkFrames;\n }\n set showLinkFrames(v: boolean) {\n this._showLinkFrames = v;\n if (v && this.linkFrameHelpers.length === 0) {\n for (const link of this.linkObjects.values()) {\n const h = new THREE.AxesHelper(this.helperSize);\n h.name = `${link.linkName}:frame`;\n link.add(h);\n this.linkFrameHelpers.push(h);\n }\n }\n for (const h of this.linkFrameHelpers) h.visible = v;\n }\n\n private setKindVisibility(kind: string, visible: boolean): void {\n this.traverse((o) => {\n if ((o.userData as { kind?: string }).kind === kind) o.visible = visible;\n });\n }\n}\n\nconst UNIT_SCALE = new THREE.Vector3(1, 1, 1);\nconst IDENTITY4: Mat4 = identity4();\n/** Slack for `limitExceeded` so poses exactly at a limit round-trip clean. */\nconst LIMIT_EPS = 1e-9;\n\n/** Assign a fixed local matrix to an object (disables Three.js auto-update). */\nfunction setMatrix(obj: THREE.Object3D, m: Mat4): void {\n obj.matrixAutoUpdate = false;\n obj.matrix.fromArray(m);\n obj.matrixWorldNeedsUpdate = true;\n}\n"]}
@@ -325,69 +325,6 @@ function cross(a, b) {
325
325
  return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
326
326
  }
327
327
 
328
- // src/kinematics/jointResiduals.ts
329
- var AXIS_INDEX = { X: 0, Y: 1, Z: 2 };
330
- function decomposeJointRelative(joint, parentWorld, childWorld) {
331
- const d = multiplyAll([
332
- invert(joint.jointFrame0),
333
- invert(parentWorld),
334
- childWorld,
335
- joint.jointFrame1
336
- ]);
337
- const t = [d[12], d[13], d[14]];
338
- const { orientation } = decomposeRigid(d);
339
- const sign = orientation.real < 0 ? -1 : 1;
340
- const w = sign * orientation.real;
341
- const vx = sign * orientation.imaginary[0];
342
- const vy = sign * orientation.imaginary[1];
343
- const vz = sign * orientation.imaginary[2];
344
- const rotationAngle = 2 * Math.atan2(Math.hypot(vx, vy, vz), w);
345
- const i = AXIS_INDEX[joint.axis];
346
- if (joint.type === "prismatic") {
347
- const anchor = Math.hypot(i === 0 ? 0 : t[0], i === 1 ? 0 : t[1], i === 2 ? 0 : t[2]);
348
- return { q: t[i], anchorError: anchor, axisError: rotationAngle };
349
- }
350
- if (joint.type === "fixed") {
351
- return { q: 0, anchorError: Math.hypot(...t), axisError: rotationAngle };
352
- }
353
- const proj = i === 0 ? vx : i === 1 ? vy : vz;
354
- const twistNorm = Math.hypot(w, proj);
355
- const q = twistNorm > 1e-12 ? 2 * Math.atan2(proj, w) : 0;
356
- const swing = 2 * Math.atan2(Math.sqrt(Math.max(0, 1 - twistNorm * twistNorm)), twistNorm);
357
- return { q, anchorError: Math.hypot(...t), axisError: swing };
358
- }
359
- function nearestAngleBranch(q, previous) {
360
- const TWO_PI = 2 * Math.PI;
361
- return q + TWO_PI * Math.round((previous - q) / TWO_PI);
362
- }
363
-
364
- // src/kinematics/sampling.ts
365
- function interpolate(channel, t) {
366
- const { times, values } = channel;
367
- const n = times.length;
368
- if (n === 0) return 0;
369
- if (t <= times[0]) return values[0];
370
- if (t >= times[n - 1]) return values[n - 1];
371
- let lo = 0;
372
- let hi = n - 1;
373
- while (lo < hi) {
374
- const mid = lo + hi >> 1;
375
- if (times[mid] <= t) lo = mid + 1;
376
- else hi = mid;
377
- }
378
- const i = lo - 1;
379
- const t0 = times[i];
380
- const t1 = times[i + 1];
381
- const span = t1 - t0;
382
- const f = span > 0 ? (t - t0) / span : 0;
383
- return values[i] + (values[i + 1] - values[i]) * f;
384
- }
385
- function channelFromSamples(samples) {
386
- const times = [...samples.keys()].sort((a, b) => a - b);
387
- const values = times.map((t) => samples.get(t) ?? 0);
388
- return { times, values };
389
- }
390
-
391
- export { DEG2RAD, RAD2DEG, channelFromSamples, decomposeJointRelative, decomposeRigid, fromUsdMatrix, getTranslation, identity4, interpolate, invert, makeEuler, makeRotationFromQuat, makeRotationX, makeRotationY, makeRotationZ, makeScale, makeTranslation, multiply, multiplyAll, nearestAngleBranch, toUsdMatrix };
392
- //# sourceMappingURL=chunk-YGJ23CG3.js.map
393
- //# sourceMappingURL=chunk-YGJ23CG3.js.map
328
+ export { DEG2RAD, RAD2DEG, decomposeRigid, fromUsdMatrix, getTranslation, identity4, invert, makeEuler, makeRotationFromQuat, makeRotationX, makeRotationY, makeRotationZ, makeScale, makeTranslation, multiply, multiplyAll, toUsdMatrix };
329
+ //# sourceMappingURL=chunk-IAOPNN6V.js.map
330
+ //# sourceMappingURL=chunk-IAOPNN6V.js.map