three-usd-robot 0.8.0 → 0.8.1

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
@@ -97,6 +97,25 @@ and `parseRobotDescription(data)` returns the Three.js-independent IR. Pass a
97
97
  `baseUrl` as the second `parse` argument if the layer has relative references
98
98
  or texture paths to resolve.
99
99
 
100
+ ### World up-axis & units
101
+
102
+ Stages load normalized: `metersPerUnit` scales the root, and the authored
103
+ `upAxis` (`"Y"` or `"Z"`) is rotated into your world convention via `worldUp`:
104
+
105
+ ```ts
106
+ new ThreeUsdRobotLoader(); // default: "Y" — upright in a stock three.js scene
107
+ new ThreeUsdRobotLoader({ worldUp: "Z" }); // robotics-style Z-up world
108
+ new ThreeUsdRobotLoader({ worldUp: "keep" }); // leave the authored orientation
109
+
110
+ robot.upAxis; // authored stage value ("Y" | "Z"), independent of normalization
111
+ robot.metersPerUnit; // authored stage scale (already applied to the root)
112
+ ```
113
+
114
+ Isaac Sim assets are Z-up, so the default makes them stand upright in a plain
115
+ three.js scene; a Z-up app (ROS-style) passes `worldUp: "Z"` once instead of
116
+ counter-rotating per asset. The M9 option `upAxisConversion` remains as a
117
+ deprecated alias (`"auto"` ≡ `worldUp: "Y"`, `"none"` ≡ `"keep"`).
118
+
100
119
  ### Stable addressing (naming contract)
101
120
 
102
121
  Joints and links are keyed by their prim's **leaf name** while it is unique
@@ -41,15 +41,25 @@ declare class LinkObject extends THREE.Object3D {
41
41
  constructor(link: LinkDescription);
42
42
  }
43
43
 
44
+ /** Target world up-axis: normalize to Y-up / Z-up, or keep the authored orientation. */
45
+ type WorldUpAxis = "Y" | "Z" | "keep";
44
46
  type ThreeUsdRobotOptions = {
45
47
  /** Clamp `setJointValue` to authored limits (default `true`). */
46
48
  clampJointLimits?: boolean;
47
49
  /** Size of the built-in joint-axis / link-frame helpers (stage units, default `0.15`). */
48
50
  helperSize?: number;
49
51
  /**
50
- * Up-axis correction applied at the robot root. `"auto"` rotates Z-up assets
51
- * into the Three.js Y-up scene; `"Z"` forces it, `"Y"`/`"none"` leave the
52
- * orientation as authored. Default `"none"` (the loader defaults to `"auto"`).
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}.
53
63
  */
54
64
  upAxisConversion?: "auto" | "Y" | "Z" | "none";
55
65
  /** Extra uniform scale multiplied with the stage `metersPerUnit` (default `1`). */
@@ -90,7 +100,7 @@ declare class ThreeUsdRobot extends THREE.Object3D {
90
100
  private jointAxesHelpers;
91
101
  private linkFrameHelpers;
92
102
  constructor(robot: RobotDescription, tree: KinematicTree, options?: ThreeUsdRobotOptions);
93
- /** Orient (Z-upY-up) and scale (metersPerUnit × unitScale) the robot root. */
103
+ /** Orient (authored upAxis target world up) and scale (metersPerUnit × unitScale) the root. */
94
104
  private applyStageNormalization;
95
105
  /** Apply each joint's authored initial value, if any. */
96
106
  private applyInitialPose;
@@ -137,6 +147,10 @@ declare class ThreeUsdRobot extends THREE.Object3D {
137
147
  getJointNames(): string[];
138
148
  getLinkNames(): string[];
139
149
  getKinematicTree(): KinematicTree;
150
+ /** Authored stage up-axis (`"Y"` or `"Z"`) — unaffected by `worldUp` normalization. */
151
+ get upAxis(): "Y" | "Z";
152
+ /** Authored stage scale in meters per unit (already applied to the root). */
153
+ get metersPerUnit(): number;
140
154
  /** Playback rate in time codes per second (from the stage; default 24). */
141
155
  getTimeCodesPerSecond(): number;
142
156
  /** Whether any joint has a time-sampled trajectory. */
@@ -162,4 +176,4 @@ declare class ThreeUsdRobot extends THREE.Object3D {
162
176
  private setKindVisibility;
163
177
  }
164
178
 
165
- export { JointObject as J, LinkObject as L, ThreeUsdRobot as T, type ThreeUsdRobotOptions as a };
179
+ export { JointObject as J, LinkObject as L, ThreeUsdRobot as T, type WorldUpAxis as W, type ThreeUsdRobotOptions as a };
@@ -1,6 +1,6 @@
1
1
  import { R as RobotDescription } from './buildKinematicTree-D4R0hEtN.js';
2
2
  import { A as AssetResolver, U as UsdSource, B as BinarySource } from './bytes-MOJ2oN-u.js';
3
- import { T as ThreeUsdRobot } from './ThreeUsdRobot-CsjraHqP.js';
3
+ import { W as WorldUpAxis, T as ThreeUsdRobot } from './ThreeUsdRobot-BZ_vlr1R.js';
4
4
 
5
5
  type ThreeUsdRobotLoaderOptions = {
6
6
  /** Resolver for references / payloads / sublayers (default {@link DefaultAssetResolver}). */
@@ -18,7 +18,17 @@ type ThreeUsdRobotLoaderOptions = {
18
18
  loadSceneGeometry?: boolean;
19
19
  /** Load diffuse textures referenced by materials (default `true`). */
20
20
  loadTextures?: boolean;
21
- /** Up-axis correction strategy (M9). */
21
+ /**
22
+ * Target world up-axis. Any stage (Y-up or Z-up) is normalized into this
23
+ * convention: `"Y"` for a standard three.js scene (the default behavior),
24
+ * `"Z"` for a robotics-style Z-up world, `"keep"` to leave the authored
25
+ * orientation. Takes precedence over {@link upAxisConversion}.
26
+ */
27
+ worldUp?: WorldUpAxis;
28
+ /**
29
+ * Legacy up-axis correction (M9). Default `"auto"` ≡ `worldUp: "Y"`.
30
+ * @deprecated Use {@link worldUp}.
31
+ */
22
32
  upAxisConversion?: "auto" | "Y" | "Z" | "none";
23
33
  /** Extra uniform scale multiplied with `metersPerUnit` (M9). */
24
34
  unitScale?: number;
@@ -110,13 +110,18 @@ var ThreeUsdRobot = class extends THREE4.Object3D {
110
110
  this.applyStageNormalization(robot, options);
111
111
  if (options.applyInitialPose ?? true) this.applyInitialPose(robot);
112
112
  }
113
- /** Orient (Z-upY-up) and scale (metersPerUnit × unitScale) the robot root. */
113
+ /** Orient (authored upAxis target world up) and scale (metersPerUnit × unitScale) the root. */
114
114
  applyStageNormalization(robot, options) {
115
115
  const scale = (robot.metersPerUnit || 1) * (options.unitScale ?? 1);
116
116
  if (scale !== 1) this.scale.setScalar(scale);
117
+ const rotateX = (angle) => this.quaternion.setFromAxisAngle(new THREE4.Vector3(1, 0, 0), angle);
118
+ if (options.worldUp) {
119
+ if (options.worldUp === "Y" && robot.upAxis === "Z") rotateX(-Math.PI / 2);
120
+ else if (options.worldUp === "Z" && robot.upAxis === "Y") rotateX(Math.PI / 2);
121
+ return;
122
+ }
117
123
  const conv = options.upAxisConversion ?? "none";
118
- const toY = conv === "Z" || conv === "auto" && robot.upAxis === "Z";
119
- if (toY) this.quaternion.setFromAxisAngle(new THREE4.Vector3(1, 0, 0), -Math.PI / 2);
124
+ if (conv === "Z" || conv === "auto" && robot.upAxis === "Z") rotateX(-Math.PI / 2);
120
125
  }
121
126
  /** Apply each joint's authored initial value, if any. */
122
127
  applyInitialPose(robot) {
@@ -277,6 +282,14 @@ var ThreeUsdRobot = class extends THREE4.Object3D {
277
282
  getKinematicTree() {
278
283
  return this.tree;
279
284
  }
285
+ /** Authored stage up-axis (`"Y"` or `"Z"`) — unaffected by `worldUp` normalization. */
286
+ get upAxis() {
287
+ return this.robot.upAxis;
288
+ }
289
+ /** Authored stage scale in meters per unit (already applied to the root). */
290
+ get metersPerUnit() {
291
+ return this.robot.metersPerUnit;
292
+ }
280
293
  // -- Animation playback --------------------------------------------------
281
294
  /** Playback rate in time codes per second (from the stage; default 24). */
282
295
  getTimeCodesPerSecond() {
@@ -370,5 +383,5 @@ function setMatrix(obj, m) {
370
383
  }
371
384
 
372
385
  export { JointObject, LinkObject, ThreeUsdRobot, axisVector };
373
- //# sourceMappingURL=chunk-3CANZKP3.js.map
374
- //# sourceMappingURL=chunk-3CANZKP3.js.map
386
+ //# sourceMappingURL=chunk-FUPFJOXW.js.map
387
+ //# sourceMappingURL=chunk-FUPFJOXW.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-FUPFJOXW.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 { Axis, JointDescription, JointType } 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\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 }\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 { interpolate } from \"../kinematics/sampling.js\";\nimport { type Mat4, invert, multiply } 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 { 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\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 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 private dirty = true;\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.applyStageNormalization(robot, options);\n if (options.applyInitialPose ?? true) this.applyInitialPose(robot);\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 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. Returns whether it applied.\n */\n setJointValue(name: string, value: number): boolean {\n const joint = this.jointObjects.get(this.jointKey(name));\n if (!joint) return false;\n joint.setValue(value, this.clampJointLimits);\n this.dirty = true;\n return true;\n }\n\n /** Set several joint values at once (matrix update is coalesced). */\n setJointValues(values: Record<string, number>): void {\n for (const [name, value] of Object.entries(values)) {\n const joint = this.jointObjects.get(this.jointKey(name));\n if (joint) {\n joint.setValue(value, this.clampJointLimits);\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 // -- 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 /** Names of the articulated (controllable) joints. */\n getJointNames(): string[] {\n return [...this.jointObjects.keys()];\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 /** Sample every animated joint at time code `t` and apply the values. */\n setTime(t: number): void {\n for (const [key, joint] of Object.entries(this.robot.joints)) {\n if (joint.valueSamples) 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\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"]}
@@ -1,5 +1,5 @@
1
1
  import { getMaterialSubsets, resolveBoundMaterial, isRenderableGprim, COLLISION_API, isNonVisualPurpose, computeWorldTransform, computeLocalTransform, DefaultAssetResolver, toBytes, extractRobotDescription, isZip, CrateReader, openUsdz, buildKinematicTree, Stage, composeLayer, composeFile, crateToUsdaFile } from './chunk-PHHMWMCA.js';
2
- import { ThreeUsdRobot } from './chunk-3CANZKP3.js';
2
+ import { ThreeUsdRobot } from './chunk-FUPFJOXW.js';
3
3
  import { identity4, multiply } from './chunk-IYKPVUZ2.js';
4
4
  import * as THREE from 'three';
5
5
 
@@ -489,7 +489,7 @@ var ThreeUsdRobotLoader = class {
489
489
  }
490
490
  robotOptions() {
491
491
  return {
492
- upAxisConversion: this.options.upAxisConversion ?? "auto",
492
+ ...this.options.worldUp ? { worldUp: this.options.worldUp } : { upAxisConversion: this.options.upAxisConversion ?? "auto" },
493
493
  ...this.options.clampJointLimits !== void 0 ? { clampJointLimits: this.options.clampJointLimits } : {},
494
494
  ...this.options.unitScale !== void 0 ? { unitScale: this.options.unitScale } : {},
495
495
  ...this.options.applyDriveTargetsAsInitialPose !== void 0 ? { applyInitialPose: this.options.applyDriveTargetsAsInitialPose } : {}
@@ -504,5 +504,5 @@ var ThreeUsdRobotLoader = class {
504
504
  };
505
505
 
506
506
  export { ThreeUsdRobotLoader, bindRobotMeshes, bindSceneMeshes, buildGprimGeometry, buildMeshGeometry, buildMeshMaterial, createTextureProvider };
507
- //# sourceMappingURL=chunk-YX5GIEMT.js.map
508
- //# sourceMappingURL=chunk-YX5GIEMT.js.map
507
+ //# sourceMappingURL=chunk-JHOX3VUW.js.map
508
+ //# sourceMappingURL=chunk-JHOX3VUW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/three/MeshBinding.ts","../src/three/TextureBinding.ts","../src/three/ThreeUsdRobotLoader.ts"],"names":["begin","THREE2"],"mappings":";;;;;AAgCA,IAAM,aAAA,GAAgB,QAAA;AAiBf,SAAS,kBAAkB,QAAA,EAA6C;AAC7E,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,YAAA,CAAa,QAAQ,EAAE,GAAA,EAAI;AACnD,EAAA,IAAI,CAAC,WAAA,CAAY,MAAM,KAAK,MAAA,CAAO,MAAA,KAAW,GAAG,OAAO,IAAA;AAExD,EAAA,MAAM,QAAA,GAAW,IAAU,KAAA,CAAA,cAAA,EAAe;AAC1C,EAAA,QAAA,CAAS,YAAA,CAAa,YAAY,IAAU,KAAA,CAAA,sBAAA,CAAuB,MAAM,MAAM,CAAA,EAAG,CAAC,CAAC,CAAA;AAEpF,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,YAAA,CAAa,kBAAkB,EAAE,GAAA,EAAI;AAC7D,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,YAAA,CAAa,mBAAmB,EAAE,GAAA,EAAI;AAC/D,EAAA,IAAI,aAAA,CAAc,MAAM,CAAA,IAAK,aAAA,CAAc,OAAO,CAAA,EAAG;AACnD,IAAA,MAAM,OAAA,GAAU,mBAAmB,QAAQ,CAAA;AAC3C,IAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,MAAA,QAAA,CAAS,SAAS,mBAAA,CAAoB,QAAA,EAAU,MAAA,EAAQ,OAAA,EAAS,OAAO,CAAC,CAAA;AAAA,IAC3E,CAAA,MAAO;AACL,MAAA,QAAA,CAAS,QAAA,CAAS,WAAA,CAAY,MAAA,EAAQ,OAAO,CAAC,CAAA;AAAA,IAChD;AAAA,EACF,CAAA,MAAA,IAAW,aAAA,CAAc,OAAO,CAAA,EAAG;AACjC,IAAA,QAAA,CAAS,QAAA,CAAS,OAAA,CAAQ,KAAA,EAAO,CAAA;AAAA,EACnC;AAEA,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,YAAA,CAAa,SAAS,EAAE,GAAA,EAAI;AACrD,EAAA,IAAI,YAAY,OAAO,CAAA,IAAK,OAAA,CAAQ,MAAA,KAAW,OAAO,MAAA,EAAQ;AAC5D,IAAA,QAAA,CAAS,YAAA,CAAa,UAAU,IAAU,KAAA,CAAA,sBAAA,CAAuB,MAAM,OAAO,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,EACrF,CAAA,MAAO;AACL,IAAA,QAAA,CAAS,oBAAA,EAAqB;AAAA,EAChC;AAEA,EAAA,MAAM,EAAA,GAAK,QAAA,CAAS,YAAA,CAAa,aAAa,EAAE,GAAA,EAAI;AACpD,EAAA,IAAI,YAAY,EAAE,CAAA,IAAK,EAAA,CAAG,MAAA,KAAW,OAAO,MAAA,EAAQ;AAClD,IAAA,QAAA,CAAS,YAAA,CAAa,MAAM,IAAU,KAAA,CAAA,sBAAA,CAAuB,MAAM,EAAE,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,EAC5E;AAEA,EAAA,OAAO,QAAA;AACT;AASO,SAAS,mBAAmB,IAAA,EAAyC;AAC1E,EAAA,QAAQ,IAAA,CAAK,aAAY;AAAG,IAC1B,KAAK,MAAA;AACH,MAAA,OAAO,kBAAkB,IAAI,CAAA;AAAA,IAC/B,KAAK,MAAA,EAAQ;AACX,MAAA,MAAM,IAAA,GAAO,SAAA,CAAU,IAAA,EAAM,MAAM,CAAA,IAAK,CAAA;AACxC,MAAA,OAAO,IAAU,KAAA,CAAA,WAAA,CAAY,IAAA,EAAM,IAAA,EAAM,IAAI,CAAA;AAAA,IAC/C;AAAA,IACA,KAAK,QAAA;AACH,MAAA,OAAO,IAAU,qBAAe,SAAA,CAAU,IAAA,EAAM,QAAQ,CAAA,IAAK,CAAA,EAAG,IAAI,EAAE,CAAA;AAAA,IACxE,KAAK,UAAA,EAAY;AACf,MAAA,MAAM,MAAA,GAAS,SAAA,CAAU,IAAA,EAAM,QAAQ,CAAA,IAAK,CAAA;AAC5C,MAAA,MAAM,MAAA,GAAS,SAAA,CAAU,IAAA,EAAM,QAAQ,CAAA,IAAK,CAAA;AAC5C,MAAA,OAAO,WAAA,CAAY,IAAU,KAAA,CAAA,gBAAA,CAAiB,MAAA,EAAQ,QAAQ,MAAA,EAAQ,EAAE,GAAG,IAAI,CAAA;AAAA,IACjF;AAAA,IACA,KAAK,SAAA,EAAW;AACd,MAAA,MAAM,MAAA,GAAS,SAAA,CAAU,IAAA,EAAM,QAAQ,CAAA,IAAK,GAAA;AAC5C,MAAA,MAAM,MAAA,GAAS,SAAA,CAAU,IAAA,EAAM,QAAQ,CAAA,IAAK,CAAA;AAC5C,MAAA,OAAO,WAAA,CAAY,IAAU,KAAA,CAAA,eAAA,CAAgB,MAAA,EAAQ,QAAQ,CAAA,EAAG,EAAE,GAAG,IAAI,CAAA;AAAA,IAC3E;AAAA,IACA,KAAK,MAAA,EAAQ;AACX,MAAA,MAAM,MAAA,GAAS,SAAA,CAAU,IAAA,EAAM,QAAQ,CAAA,IAAK,CAAA;AAC5C,MAAA,MAAM,MAAA,GAAS,SAAA,CAAU,IAAA,EAAM,QAAQ,CAAA,IAAK,CAAA;AAC5C,MAAA,OAAO,YAAY,IAAU,KAAA,CAAA,YAAA,CAAa,QAAQ,MAAA,EAAQ,EAAE,GAAG,IAAI,CAAA;AAAA,IACrE;AAAA,IACA;AACE,MAAA,OAAO,IAAA;AAAA;AAEb;AAEA,SAAS,SAAA,CAAU,MAAY,IAAA,EAAkC;AAC/D,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,YAAA,CAAa,IAAI,EAAE,GAAA,EAAI;AACtC,EAAA,OAAO,OAAO,CAAA,KAAM,QAAA,GAAW,CAAA,GAAI,MAAA;AACrC;AAGA,SAAS,WAAA,CAAY,UAAgC,IAAA,EAAkC;AACrF,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,YAAA,CAAa,MAAM,EAAE,GAAA,EAAI;AAC3C,EAAA,IAAI,IAAA,KAAS,KAAK,OAAO,QAAA;AACzB,EAAA,IAAI,IAAA,KAAS,KAAK,OAAO,QAAA,CAAS,QAAQ,CAAC,IAAA,CAAK,KAAK,CAAC,CAAA;AACtD,EAAA,OAAO,QAAA,CAAS,OAAA,CAAQ,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA;AACrC;AAUO,SAAS,iBAAA,CACd,QAAA,EACA,KAAA,EACA,QAAA,EAEA,WAAA,EACgB;AAChB,EAAA,MAAM,KAAA,GAAQ,IAAU,KAAA,CAAA,KAAA,CAAM,aAAa,CAAA;AAC3C,EAAA,IAAI,OAAA,GAAU,CAAA;AAEd,EAAA,MAAM,QAAQ,KAAA,GAAQ,oBAAA,CAAqB,KAAA,EAAO,WAAA,IAAe,QAAQ,CAAA,GAAI,MAAA;AAC7E,EAAA,IAAI,OAAO,KAAA,EAAO;AAChB,IAAA,KAAA,CAAM,MAAA,CAAO,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,CAAM,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,CAAM,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,EAC7D,CAAA,MAAO;AACL,IAAA,MAAM,YAAA,GAAe,QAAA,CAAS,YAAA,CAAa,uBAAuB,EAAE,GAAA,EAAI;AACxE,IAAA,IAAI,WAAA,CAAY,YAAY,CAAA,IAAK,YAAA,CAAa,CAAC,CAAA,EAAG;AAChD,MAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,aAAa,CAAC,CAAA;AAChC,MAAA,KAAA,CAAM,MAAA,CAAO,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,IACtB;AAAA,EACF;AACA,EAAA,IAAI,KAAA,EAAO,OAAA,KAAY,MAAA,EAAW,OAAA,GAAU,KAAA,CAAM,OAAA;AAKlD,EAAA,MAAM,GAAA,GAAM,CAAC,EAAA,EAAiC,EAAA,KAC5C,MAAM,QAAA,GACF,QAAA,CAAS,GAAG,IAAA,EAAM;AAAA,IAChB,UAAA,EAAY,EAAA;AAAA,IACZ,GAAI,GAAG,KAAA,GAAQ,EAAE,OAAO,EAAA,CAAG,KAAA,KAAU,EAAC;AAAA,IACtC,GAAI,GAAG,KAAA,GAAQ,EAAE,OAAO,EAAA,CAAG,KAAA,KAAU,EAAC;AAAA,IACtC,GAAI,GAAG,SAAA,GAAY,EAAE,WAAW,EAAA,CAAG,SAAA,KAAc;AAAC,GACnD,CAAA,GACD,IAAA;AAEN,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,KAAA,EAAO,YAAA,EAAc,MAAM,CAAA;AAE3C,EAAA,IAAI,GAAA,EAAK;AACP,IAAA,MAAM,CAAA,GAAI,OAAO,YAAA,EAAc,KAAA;AAC/B,IAAA,IAAI,CAAA,EAAG,KAAA,CAAM,MAAA,CAAO,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,SAC/B,KAAA,CAAM,MAAA,CAAO,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,EAC3B;AACA,EAAA,MAAM,SAAA,GAAY,GAAA,CAAI,KAAA,EAAO,aAAA,EAAe,QAAQ,CAAA;AACpD,EAAA,MAAM,YAAA,GAAe,GAAA,CAAI,KAAA,EAAO,gBAAA,EAAkB,QAAQ,CAAA;AAC1D,EAAA,MAAM,YAAA,GAAe,GAAA,CAAI,KAAA,EAAO,gBAAA,EAAkB,QAAQ,CAAA;AAC1D,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,EAAO,gBAAA,EAAkB,QAAQ,CAAA;AACnD,EAAA,MAAM,WAAA,GAAc,GAAA,CAAI,KAAA,EAAO,eAAA,EAAiB,MAAM,CAAA;AAItD,EAAA,MAAM,SAAA,GACJ,OAAO,SAAA,IAAa,KAAA,EAAO,kBAAkB,KAAA,GAAQ,CAAC,CAAA,KAAM,YAAA,GAAe,CAAA,GAAI,GAAA,CAAA;AACjF,EAAA,MAAM,SAAA,GACJ,OAAO,SAAA,IAAa,KAAA,EAAO,kBAAkB,KAAA,GAAQ,CAAC,CAAA,KAAM,YAAA,GAAe,CAAA,GAAI,GAAA,CAAA;AAEjF,EAAA,MAAM,QAAA,GAAW,IAAU,KAAA,CAAA,KAAA,CAAM,CAAQ,CAAA;AACzC,EAAA,IAAI,OAAO,aAAA,EAAe;AACxB,IAAA,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,aAAA,CAAc,CAAC,CAAA,EAAG,KAAA,CAAM,aAAA,CAAc,CAAC,CAAA,EAAG,KAAA,CAAM,aAAA,CAAc,CAAC,CAAC,CAAA;AAAA,EACxF,WAAW,WAAA,EAAa;AACtB,IAAA,QAAA,CAAS,MAAA,CAAO,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,EACzB;AAMA,EAAA,MAAM,aAAa,KAAA,EAAO,cAAA;AAC1B,EAAA,MAAM,iBAAiB,CAAC,EAAE,cAAc,UAAA,CAAW,IAAA,KAAS,OAAO,YAAA,EAAc,IAAA,CAAA;AACjF,EAAA,MAAM,QAAA,GAAW,cAAA,GAAiB,IAAA,GAAO,GAAA,CAAI,YAAY,QAAQ,CAAA;AACjE,EAAA,MAAM,cAAA,GAAiB,OAAA,GAAU,CAAA,IAAK,cAAA,IAAkB,CAAC,CAAC,QAAA;AAC1D,EAAA,MAAM,YAAY,KAAA,EAAO,gBAAA;AACzB,EAAA,MAAM,SAAA,GAAY,SAAA,KAAc,MAAA,IAAa,SAAA,GAAY,IAAI,SAAA,GAAY,CAAA;AAGzE,EAAA,MAAM,WAAA,GAAc,cAAc,CAAA,IAAK,cAAA;AAEvC,EAAA,MAAM,cAAc,QAAA,CAAS,YAAA,CAAa,aAAa,CAAA,CAAE,KAAI,KAAM,IAAA;AACnE,EAAA,MAAM,QAAA,GAAW,IAAU,KAAA,CAAA,oBAAA,CAAqB;AAAA,IAC9C,KAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAA;AAAA,IACA,OAAA;AAAA,IACA,GAAI,SAAA,GAAY,CAAA,GAAI,EAAE,SAAA,KAAc,EAAC;AAAA,IACrC,IAAA,EAAM,cAAoB,KAAA,CAAA,UAAA,GAAmB,KAAA,CAAA,SAAA;AAAA,IAC7C,GAAI,GAAA,GAAM,EAAE,GAAA,KAAQ,EAAC;AAAA,IACrB,GAAI,QAAA,GAAW,EAAE,QAAA,KAAa,EAAC;AAAA,IAC/B,GAAI,SAAA,GAAY,EAAE,SAAA,KAAc,EAAC;AAAA,IACjC,GAAI,YAAA,GAAe,EAAE,YAAA,KAAiB,EAAC;AAAA,IACvC,GAAI,YAAA,GAAe,EAAE,YAAA,KAAiB,EAAC;AAAA,IACvC,GAAI,KAAA,GAAQ,EAAE,KAAA,KAAU,EAAC;AAAA,IACzB,GAAI,WAAA,GAAc,EAAE,WAAA,KAAgB;AAAC,GACtC,CAAA;AAED,EAAA,IAAI,KAAA,EAAO,IAAA,EAAM,QAAA,CAAS,IAAA,GAAO,KAAA,CAAM,IAAA;AACvC,EAAA,OAAO,QAAA;AACT;AAOO,SAAS,gBACd,KAAA,EACA,OAAA,EACA,IAAA,EACA,OAAA,GAA6B,EAAC,EACxB;AACN,EAAA,MAAM,WAAA,GAAc,QAAQ,WAAA,IAAe,IAAA;AAC3C,EAAA,MAAM,cAAA,GAAiB,QAAQ,cAAA,IAAkB,KAAA;AACjD,EAAA,MAAM,WAAW,OAAA,CAAQ,eAAA;AAEzB,EAAA,KAAA,MAAW,CAAC,KAAK,IAAI,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA,EAAG;AACpD,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,aAAA,CAAc,GAAG,CAAA;AACzC,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,aAAA,CAAc,IAAA,CAAK,QAAQ,CAAA;AAClD,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,QAAA,EAAU;AAG3B,IAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,IAAA,CAAK,WAAW,CAAA;AAE1C,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,KAAA,MAAW,QAAA,IAAY,KAAK,WAAA,EAAa;AACvC,QAAA,UAAA,CAAW,KAAA,EAAO,QAAA,EAAU,QAAA,EAAU,OAAA,EAAS,UAAU,QAAQ,CAAA;AAAA,MACnE;AAAA,IACF;AACA,IAAA,IAAI,cAAA,EAAgB;AAClB,MAAA,KAAA,MAAW,QAAA,IAAY,IAAA,CAAK,cAAA,IAAkB,EAAC,EAAG;AAChD,QAAA,IAAI,WAAA,IAAe,SAAA,CAAU,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC5C,QAAA,UAAA,CAAW,KAAA,EAAO,QAAA,EAAU,QAAA,EAAU,OAAA,EAAS,aAAa,QAAQ,CAAA;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AACF;AAQO,SAAS,gBACd,KAAA,EACA,OAAA,EACA,IAAA,EACA,OAAA,GAAiD,EAAC,EAC1C;AACR,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAC9B,EAAA,KAAA,MAAW,IAAA,IAAQ,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,EAAG;AAC5C,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,WAAA,EAAa,KAAA,CAAM,IAAI,IAAI,CAAA;AACnD,IAAA,KAAA,MAAW,QAAQ,IAAA,CAAK,cAAA,IAAkB,EAAC,EAAG,KAAA,CAAM,IAAI,IAAI,CAAA;AAC5D,IAAA,KAAA,CAAM,GAAA,CAAI,KAAK,QAAQ,CAAA;AAAA,EACzB;AAEA,EAAA,IAAI,QAAA,GAAW,CAAA;AACf,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,QAAA,EAAS,EAAG;AACnC,IAAA,IAAI,CAAC,kBAAkB,IAAI,CAAA,IAAK,MAAM,GAAA,CAAI,IAAA,CAAK,OAAA,EAAS,CAAA,EAAG;AAC3D,IAAA,IAAI,KAAK,MAAA,CAAO,aAAa,CAAA,IAAK,kBAAA,CAAmB,IAAI,CAAA,EAAG;AAE5D,IAAA,IAAI,CAAC,GAAG,KAAK,CAAA,CAAE,KAAK,CAAC,IAAA,KAAS,IAAA,CAAK,OAAA,GAAU,UAAA,CAAW,CAAA,EAAG,IAAI,CAAA,CAAA,CAAG,CAAC,CAAA,EAAG;AAEtE,IAAA,MAAM,QAAA,GAAW,mBAAmB,IAAI,CAAA;AACxC,IAAA,IAAI,CAAC,QAAA,EAAU;AACf,IAAA,MAAM,IAAA,GAAO,IAAU,KAAA,CAAA,IAAA,CAAK,QAAA,EAAU,kBAAkB,IAAA,EAAM,KAAA,EAAO,OAAA,CAAQ,eAAe,CAAC,CAAA;AAC7F,IAAA,IAAA,CAAK,IAAA,GAAO,KAAK,OAAA,EAAQ;AACzB,IAAA,IAAA,CAAK,SAAS,IAAA,GAAO,OAAA;AACrB,IAAA,IAAA,CAAK,QAAA,CAAS,QAAA,GAAW,IAAA,CAAK,OAAA,EAAQ;AACtC,IAAA,IAAA,CAAK,gBAAA,GAAmB,KAAA;AACxB,IAAA,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,qBAAA,CAAsB,IAAI,CAAC,CAAA;AACjD,IAAA,IAAA,CAAK,sBAAA,GAAyB,IAAA;AAC9B,IAAA,OAAA,CAAQ,IAAI,IAAI,CAAA;AAChB,IAAA,QAAA,EAAA;AAAA,EACF;AACA,EAAA,OAAO,QAAA;AACT;AAOO,SAAS,kBAAA,CACd,QAAA,EACA,KAAA,EACA,QAAA,EACmC;AACnC,EAAA,MAAM,OAAA,GAAU,KAAA,GAAQ,kBAAA,CAAmB,QAAQ,IAAI,EAAC;AACxD,EAAA,IAAI,QAAQ,MAAA,KAAW,CAAA,SAAU,iBAAA,CAAkB,QAAA,EAAU,OAAO,QAAQ,CAAA;AAC5E,EAAA,OAAO;AAAA,IACL,GAAG,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,iBAAA,CAAkB,QAAA,EAAU,KAAA,EAAO,QAAA,EAAU,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,IAC1E,iBAAA,CAAkB,QAAA,EAAU,KAAA,EAAO,QAAQ;AAAA,GAC7C;AACF;AAEA,SAAS,WACP,KAAA,EACA,QAAA,EACA,QAAA,EACA,MAAA,EACA,MACA,QAAA,EACM;AACN,EAAA,MAAM,QAAA,GAAW,KAAA,CAAM,aAAA,CAAc,QAAQ,CAAA;AAC7C,EAAA,IAAI,CAAC,QAAA,EAAU;AACf,EAAA,MAAM,QAAA,GAAW,mBAAmB,QAAQ,CAAA;AAC5C,EAAA,IAAI,CAAC,QAAA,EAAU;AAEf,EAAA,MAAM,IAAA,GAAO,IAAU,KAAA,CAAA,IAAA,CAAK,QAAA,EAAU,mBAAmB,QAAA,EAAU,KAAA,EAAO,QAAQ,CAAC,CAAA;AACnF,EAAA,IAAA,CAAK,IAAA,GAAO,SAAS,OAAA,EAAQ;AAC7B,EAAA,IAAA,CAAK,SAAS,IAAA,GAAO,IAAA;AACrB,EAAA,IAAA,CAAK,SAAS,QAAA,GAAW,QAAA;AAEzB,EAAA,IAAI,IAAA,KAAS,WAAA,EAAa,IAAA,CAAK,OAAA,GAAU,KAAA;AACzC,EAAA,IAAA,CAAK,gBAAA,GAAmB,KAAA;AACxB,EAAA,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,iBAAA,CAAkB,QAAA,EAAU,QAAQ,CAAC,CAAA;AAC3D,EAAA,IAAA,CAAK,sBAAA,GAAyB,IAAA;AAC9B,EAAA,MAAA,CAAO,IAAI,IAAI,CAAA;AACjB;AAGA,SAAS,iBAAA,CAAkB,UAAgB,QAAA,EAAsB;AAC/D,EAAA,MAAM,QAAgB,EAAC;AACvB,EAAA,IAAI,CAAA,GAAiB,QAAA;AACrB,EAAA,MAAM,IAAA,GAAO,SAAS,OAAA,EAAQ;AAC9B,EAAA,OAAO,CAAA,IAAK,CAAA,CAAE,OAAA,EAAQ,KAAM,IAAA,EAAM;AAChC,IAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AACZ,IAAA,CAAA,GAAI,EAAE,SAAA,EAAU;AAAA,EAClB;AACA,EAAA,KAAA,CAAM,OAAA,EAAQ;AAEd,EAAA,IAAI,IAAI,SAAA,EAAU;AAClB,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,CAAA,GAAI,QAAA,CAAS,CAAA,EAAG,qBAAA,CAAsB,IAAI,EAAE,MAAM,CAAA;AAAA,EACpD;AACA,EAAA,OAAO,CAAA;AACT;AAKA,SAAS,WAAA,CAAY,kBAA4B,iBAAA,EAAuC;AACtF,EAAA,MAAM,OAAiB,EAAC;AACxB,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,KAAA,MAAW,SAAS,gBAAA,EAAkB;AACpC,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC9B,MAAA,IAAA,CAAK,IAAA;AAAA,QACH,kBAAkB,MAAM,CAAA;AAAA,QACxB,iBAAA,CAAkB,MAAA,GAAS,CAAA,GAAI,CAAC,CAAA;AAAA,QAChC,iBAAA,CAAkB,SAAS,CAAC;AAAA,OAC9B;AAAA,IACF;AACA,IAAA,MAAA,IAAU,KAAA;AAAA,EACZ;AACA,EAAA,OAAO,IAAA;AACT;AAMA,SAAS,mBAAA,CACP,QAAA,EACA,gBAAA,EACA,iBAAA,EACA,OAAA,EACU;AACV,EAAA,MAAM,YAAsB,EAAC;AAC7B,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,KAAA,MAAW,SAAS,gBAAA,EAAkB;AACpC,IAAA,SAAA,CAAU,KAAK,MAAM,CAAA;AACrB,IAAA,MAAA,IAAU,KAAA;AAAA,EACZ;AAEA,EAAA,MAAM,OAAiB,EAAC;AACxB,EAAA,MAAM,IAAA,GAAO,CAAC,IAAA,KAAiB;AAC7B,IAAA,MAAM,KAAA,GAAQ,UAAU,IAAI,CAAA;AAC5B,IAAA,MAAM,KAAA,GAAQ,iBAAiB,IAAI,CAAA;AACnC,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC9B,MAAA,IAAA,CAAK,IAAA;AAAA,QACH,kBAAkB,KAAK,CAAA;AAAA,QACvB,iBAAA,CAAkB,KAAA,GAAQ,CAAA,GAAI,CAAC,CAAA;AAAA,QAC/B,iBAAA,CAAkB,QAAQ,CAAC;AAAA,OAC7B;AAAA,IACF;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,OAAA,GAAU,IAAI,UAAA,CAAW,gBAAA,CAAiB,MAAM,CAAA;AACtD,EAAA,OAAA,CAAQ,OAAA,CAAQ,CAAC,MAAA,EAAQ,KAAA,KAAU;AACjC,IAAA,MAAMA,SAAQ,IAAA,CAAK,MAAA;AACnB,IAAA,KAAA,MAAW,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/B,MAAA,IAAI,OAAO,CAAA,IAAK,IAAA,IAAQ,iBAAiB,MAAA,IAAU,OAAA,CAAQ,IAAI,CAAA,EAAG;AAClE,MAAA,OAAA,CAAQ,IAAI,CAAA,GAAI,CAAA;AAChB,MAAA,IAAA,CAAK,IAAI,CAAA;AAAA,IACX;AACA,IAAA,IAAI,IAAA,CAAK,SAASA,MAAAA,EAAO,QAAA,CAAS,SAASA,MAAAA,EAAO,IAAA,CAAK,MAAA,GAASA,MAAAA,EAAO,KAAK,CAAA;AAAA,EAC9E,CAAC,CAAA;AAED,EAAA,MAAM,QAAQ,IAAA,CAAK,MAAA;AACnB,EAAA,KAAA,IAAS,IAAA,GAAO,CAAA,EAAG,IAAA,GAAO,gBAAA,CAAiB,QAAQ,IAAA,EAAA,EAAQ;AACzD,IAAA,IAAI,CAAC,OAAA,CAAQ,IAAI,CAAA,OAAQ,IAAI,CAAA;AAAA,EAC/B;AACA,EAAA,IAAI,IAAA,CAAK,MAAA,GAAS,KAAA,EAAO,QAAA,CAAS,QAAA,CAAS,OAAO,IAAA,CAAK,MAAA,GAAS,KAAA,EAAO,OAAA,CAAQ,MAAM,CAAA;AAErF,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,MAAM,CAAA,EAAqB;AAClC,EAAA,MAAM,GAAA,GAAM,IAAI,KAAA,CAAc,CAAA,CAAE,SAAS,CAAC,CAAA;AAC1C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,QAAQ,CAAA,EAAA,EAAK;AACjC,IAAA,GAAA,CAAI,IAAI,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,EAAG,CAAC,CAAA;AACpB,IAAA,GAAA,CAAI,IAAI,CAAA,GAAI,CAAC,IAAI,CAAA,CAAE,CAAC,EAAG,CAAC,CAAA;AACxB,IAAA,GAAA,CAAI,IAAI,CAAA,GAAI,CAAC,IAAI,CAAA,CAAE,CAAC,EAAG,CAAC,CAAA;AAAA,EAC1B;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,MAAM,CAAA,EAAqB;AAClC,EAAA,MAAM,GAAA,GAAM,IAAI,KAAA,CAAc,CAAA,CAAE,SAAS,CAAC,CAAA;AAC1C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,QAAQ,CAAA,EAAA,EAAK;AACjC,IAAA,GAAA,CAAI,IAAI,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,EAAG,CAAC,CAAA;AACpB,IAAA,GAAA,CAAI,IAAI,CAAA,GAAI,CAAC,IAAI,CAAA,CAAE,CAAC,EAAG,CAAC,CAAA;AAAA,EAC1B;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,cAAc,CAAA,EAA2B;AAChD,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,CAAA,CAAE,MAAM,CAAC,CAAA,KAAM,OAAO,CAAA,KAAM,QAAQ,CAAA;AACjE;AAEA,SAAS,YAAY,CAAA,EAAyB;AAC5C,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,EAAE,KAAA,CAAM,CAAC,CAAA,KAAM,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,CAAA,CAAE,WAAW,CAAC,CAAA;AAC9E;AAEA,SAAS,YAAY,CAAA,EAAyB;AAC5C,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,EAAE,KAAA,CAAM,CAAC,CAAA,KAAM,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,CAAA,CAAE,WAAW,CAAC,CAAA;AAC9E;AC5bA,IAAM,OAAA,GAAU,KAAK,EAAA,GAAK,GAAA;AAQnB,SAAS,qBAAA,CAAsB,UAAyB,OAAA,EAAkC;AAC/F,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAqC;AAExD,EAAA,MAAM,QAAA,GAAW,CAAC,GAAA,KAAyC;AACzD,IAAA,IAAI,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA;AACtB,IAAA,IAAI,CAAC,CAAA,EAAG;AACN,MAAA,CAAA,GAAI,SAAA,CAAU,UAAU,GAAG,CAAA;AAC3B,MAAA,MAAA,CAAO,GAAA,CAAI,KAAK,CAAC,CAAA;AAAA,IACnB;AACA,IAAA,OAAO,CAAA;AAAA,EACT,CAAA;AAEA,EAAA,OAAO,CAAC,SAAA,EAAmB,OAAA,GAA0B,EAAC,KAAM;AAC1D,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,QAAA,CAAS,OAAA,CAAQ,SAAA,EAAW,OAAO,CAAA;AAAA,IAC3C,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,OAAA,GAAU,IAAUC,KAAA,CAAA,OAAA,EAAQ;AAClC,IAAA,OAAA,CAAQ,UAAA,GACN,OAAA,CAAQ,UAAA,KAAe,QAAA,GAAiBA,KAAA,CAAA,YAAA,GAAqBA,KAAA,CAAA,cAAA;AAC/D,IAAA,OAAA,CAAQ,KAAA,GAAQ,WAAA,CAAY,OAAA,CAAQ,KAAK,CAAA;AACzC,IAAA,OAAA,CAAQ,KAAA,GAAQ,WAAA,CAAY,OAAA,CAAQ,KAAK,CAAA;AACzC,IAAA,cAAA,CAAe,OAAA,EAAS,QAAQ,SAAS,CAAA;AAEzC,IAAA,QAAA,CAAS,GAAG,CAAA,CACT,IAAA,CAAK,CAAC,KAAA,KAAU;AACf,MAAA,OAAA,CAAQ,KAAA,GAAQ,KAAA;AAChB,MAAA,OAAA,CAAQ,WAAA,GAAc,IAAA;AAAA,IACxB,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AAAA,IAEb,CAAC,CAAA;AACH,IAAA,OAAO,OAAA;AAAA,EACT,CAAA;AACF;AAOA,eAAe,SAAA,CAAU,UAAyB,GAAA,EAAsC;AACtF,EAAA,MAAM,QAAQ,QAAA,CAAS,UAAA,GACnB,MAAM,QAAA,CAAS,WAAW,GAAG,CAAA,GAC7B,IAAI,WAAA,GAAc,MAAA,CAAO,MAAM,QAAA,CAAS,SAAA,CAAU,GAAG,CAAC,CAAA;AAC1D,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,CAAC,KAAiB,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,GAAG,CAAA,EAAG,CAAA;AAChE,EAAA,MAAM,SAAA,GAAY,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AAC1C,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,IAAI,OAAA,CAA0B,CAAC,SAAS,MAAA,KAAW;AAC9D,MAAA,MAAM,GAAA,GAAM,IAAI,KAAA,EAAM;AACtB,MAAA,GAAA,CAAI,MAAA,GAAS,MAAM,OAAA,CAAQ,GAAG,CAAA;AAC9B,MAAA,GAAA,CAAI,OAAA,GAAU,MAAM,MAAA,CAAO,IAAI,MAAM,CAAA,0BAAA,EAA6B,GAAG,EAAE,CAAC,CAAA;AACxE,MAAA,GAAA,CAAI,GAAA,GAAM,SAAA;AAAA,IACZ,CAAC,CAAA;AAAA,EACH,CAAA,SAAE;AAEA,IAAA,GAAA,CAAI,gBAAgB,SAAS,CAAA;AAAA,EAC/B;AACF;AAEA,SAAS,YAAY,IAAA,EAA+C;AAClE,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,OAAA;AAAA,IACL,KAAK,OAAA;AACH,MAAA,OAAaA,KAAA,CAAA,mBAAA;AAAA,IACf,KAAK,QAAA;AACH,MAAA,OAAaA,KAAA,CAAA,sBAAA;AAAA,IACf;AACE,MAAA,OAAaA,KAAA,CAAA,cAAA;AAAA;AAEnB;AAGA,SAAS,cAAA,CAAe,SAAwB,CAAA,EAAuC;AACrF,EAAA,IAAI,CAAC,CAAA,EAAG;AACR,EAAA,IAAI,CAAA,CAAE,KAAA,EAAO,OAAA,CAAQ,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA;AACtD,EAAA,IAAI,CAAA,CAAE,WAAA,EAAa,OAAA,CAAQ,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,WAAA,CAAY,CAAC,CAAA,EAAG,CAAA,CAAE,WAAA,CAAY,CAAC,CAAC,CAAA;AACxE,EAAA,IAAI,CAAA,CAAE,aAAa,MAAA,EAAW;AAC5B,IAAA,OAAA,CAAQ,QAAA,GAAW,EAAE,QAAA,GAAW,OAAA;AAChC,IAAA,OAAA,CAAQ,MAAA,CAAO,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA;AAAA,EACzB;AACF;AAEA,SAAS,OAAO,GAAA,EAAqB;AACnC,EAAA,IAAI,WAAA,CAAY,IAAA,CAAK,GAAG,CAAA,EAAG,OAAO,YAAA;AAClC,EAAA,IAAI,UAAA,CAAW,IAAA,CAAK,GAAG,CAAA,EAAG,OAAO,YAAA;AACjC,EAAA,OAAO,WAAA;AACT;;;AClEO,IAAM,sBAAN,MAA0B;AAAA,EACtB,OAAA;AAAA,EAET,WAAA,CAAY,OAAA,GAAsC,EAAC,EAAG;AACpD,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAEA,IAAY,QAAA,GAA0B;AACpC,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,aAAA,IAAiB,IAAI,oBAAA,EAAqB;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,UAAU,GAAA,EAAqC;AACnD,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,cAAA,CAAe,GAAG,CAAA;AAG3C,IAAA,IAAI,WAAW,IAAA,CAAK,GAAG,GAAG,OAAO,IAAA,CAAK,UAAU,KAAK,CAAA;AACrD,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,KAAA,EAAO,GAAG,CAAA;AAAA,EAC9B;AAAA,EAEA,MAAc,eAAe,GAAA,EAAkC;AAC7D,IAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AACtB,IAAA,IAAI,QAAA,CAAS,UAAA,EAAY,OAAO,QAAA,CAAS,WAAW,GAAG,CAAA;AACvD,IAAA,OAAO,IAAI,aAAY,CAAE,MAAA,CAAO,MAAM,QAAA,CAAS,SAAA,CAAU,GAAG,CAAC,CAAA;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,KAAA,CAAM,IAAA,EAAiB,OAAA,GAAU,EAAA,EAA4B;AACjE,IAAA,OAAO,KAAK,cAAA,CAAe,MAAM,KAAK,UAAA,CAAW,IAAA,EAAM,OAAO,CAAC,CAAA;AAAA,EACjE;AAAA;AAAA,EAGA,MAAM,UAAU,IAAA,EAA4C;AAC1D,IAAA,OAAO,IAAA,CAAK,eAAe,MAAM,IAAA,CAAK,cAAc,MAAM,OAAA,CAAQ,IAAI,CAAC,CAAC,CAAA;AAAA,EAC1E;AAAA;AAAA,EAGA,MAAM,UAAA,CAAW,IAAA,EAAoB,OAAA,GAAU,EAAA,EAA4B;AACzE,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,qBAAA,CAAsB,MAAM,QAAQ,IAAI,CAAA,EAAG,OAAA,EAAS,IAAA,CAAK,QAAQ,CAAA;AAC1F,IAAA,OAAO,IAAA,CAAK,eAAe,EAAE,KAAA,EAAO,SAAS,QAAA,EAAU,IAAA,CAAK,UAAU,CAAA;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,qBAAA,CAAsB,IAAA,EAAiB,OAAA,GAAU,EAAA,EAA+B;AACpF,IAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,IAAA,CAAK,UAAA,CAAW,MAAM,OAAO,CAAA;AACrD,IAAA,OAAO,uBAAA,CAAwB,KAAA,EAAO,IAAA,CAAK,cAAA,EAAgB,CAAA;AAAA,EAC7D;AAAA;AAAA,EAGA,MAAc,UAAA,CAAW,IAAA,EAAiB,OAAA,EAAuC;AAC/E,IAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AACtB,IAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,MAAA,OAAO,EAAE,KAAA,EAAO,MAAM,IAAA,CAAK,YAAA,CAAa,MAAM,OAAA,EAAS,QAAQ,CAAA,EAAG,OAAA,EAAS,QAAA,EAAS;AAAA,IACtF;AACA,IAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,IAAI,CAAA;AAChC,IAAA,IAAI,MAAM,KAAK,CAAA,EAAG,OAAO,IAAA,CAAK,cAAc,KAAK,CAAA;AACjD,IAAA,MAAM,KAAA,GAAQ,YAAY,OAAA,CAAQ,KAAK,IACnC,MAAM,IAAA,CAAK,qBAAA,CAAsB,KAAA,EAAO,OAAA,EAAS,QAAQ,IACzD,MAAM,IAAA,CAAK,aAAa,IAAI,WAAA,GAAc,MAAA,CAAO,KAAK,CAAA,EAAG,OAAA,EAAS,QAAQ,CAAA;AAC9E,IAAA,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,QAAA,EAAS;AAAA,EACpC;AAAA,EAEA,MAAc,cAAc,KAAA,EAAyC;AACnE,IAAA,MAAM,GAAA,GAAM,SAAS,KAAK,CAAA;AAE1B,IAAA,MAAM,YAAY,MAAM,GAAA,CAAI,QAAA,CAAS,UAAA,CAAW,IAAI,SAAS,CAAA;AAC7D,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,qBAAA,CAAsB,WAAW,GAAA,CAAI,SAAA,EAAW,IAAI,QAAQ,CAAA;AACrF,IAAA,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,IAAI,SAAA,EAAW,QAAA,EAAU,IAAI,QAAA,EAAS;AAAA,EACjE;AAAA,EAEQ,cAAA,CAAe,EAAE,KAAA,EAAO,OAAA,EAAS,UAAS,EAA+B;AAC/E,IAAA,MAAM,KAAA,GAAQ,uBAAA,CAAwB,KAAA,EAAO,IAAA,CAAK,gBAAgB,CAAA;AAClE,IAAA,MAAM,IAAA,GAAO,mBAAmB,KAAK,CAAA;AACrC,IAAA,MAAM,UAAU,IAAI,aAAA,CAAc,OAAO,IAAA,EAAM,IAAA,CAAK,cAAc,CAAA;AAElE,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,OAAA,CAAQ,WAAA,IAAe,IAAA;AAChD,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,OAAA,CAAQ,cAAA,IAAkB,KAAA;AAGtD,IAAA,MAAM,aAAA,GACJ,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA,CAAE,MAAA,KAAW,CAAA,IAAK,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,MAAM,EAAE,MAAA,KAAW,CAAA;AAChF,IAAA,IAAI,aAAA,IAAiB,IAAA,CAAK,OAAA,CAAQ,iBAAA,KAAsB,MAAA,EAAW;AACjE,MAAA,IAAA,CAAK,OAAA,CAAQ,MAAA;AAAA,QACX;AAAA,OACF;AAAA,IACF;AACA,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,OAAA,CAAQ,iBAAA,IAAqB,aAAA;AACpD,IAAA,IAAI,WAAA,IAAe,kBAAkB,SAAA,EAAW;AAC9C,MAAA,MAAM,eAAA,GACH,KAAK,OAAA,CAAQ,YAAA,IAAgB,OAAQ,qBAAA,CAAsB,QAAA,EAAU,OAAO,CAAA,GAAI,MAAA;AACnF,MAAA,IAAI,eAAe,cAAA,EAAgB;AACjC,QAAA,eAAA,CAAgB,KAAA,EAAO,SAAS,KAAA,EAAO;AAAA,UACrC,WAAA;AAAA,UACA,cAAA;AAAA,UACA,GAAI,eAAA,GAAkB,EAAE,eAAA,KAAoB;AAAC,SAC9C,CAAA;AAAA,MACH;AACA,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,eAAA,CAAgB,KAAA,EAAO,SAAS,KAAA,EAAO;AAAA,UACrC,GAAI,eAAA,GAAkB,EAAE,eAAA,KAAoB;AAAC,SAC9C,CAAA;AAAA,MACH;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAc,YAAA,CACZ,IAAA,EACA,OAAA,EACA,QAAA,EACgB;AAChB,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,OAAA,CAAQ,MAAA,GAAS,EAAE,QAAQ,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAO,GAAI,EAAC;AAChF,IAAA,OAAO,KAAA,CAAM,aAAa,MAAM,YAAA,CAAa,MAAM,OAAA,EAAS,QAAA,EAAU,cAAc,CAAC,CAAA;AAAA,EACvF;AAAA;AAAA,EAGA,MAAc,qBAAA,CACZ,KAAA,EACA,OAAA,EACA,QAAA,EACgB;AAChB,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,OAAA,CAAQ,MAAA,GAAS,EAAE,QAAQ,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAO,GAAI,EAAC;AAChF,IAAA,MAAM,QAAA,GAAW,WAAA,CAAY,OAAA,CAAQ,KAAK,IACtC,MAAM,WAAA;AAAA,MACJ,eAAA,CAAgB,IAAI,WAAA,CAAY,KAAK,CAAC,CAAA;AAAA,MACtC,OAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF,GACA,MAAM,YAAA,CAAa,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,KAAK,CAAA,EAAG,OAAA,EAAS,QAAA,EAAU,cAAc,CAAA;AACzF,IAAA,OAAO,KAAA,CAAM,aAAa,QAAQ,CAAA;AAAA,EACpC;AAAA,EAEQ,YAAA,GAAqC;AAC3C,IAAA,OAAO;AAAA,MACL,GAAI,IAAA,CAAK,OAAA,CAAQ,OAAA,GACb,EAAE,OAAA,EAAS,IAAA,CAAK,OAAA,CAAQ,OAAA,KACxB,EAAE,gBAAA,EAAkB,IAAA,CAAK,OAAA,CAAQ,oBAAoB,MAAA,EAAO;AAAA,MAChE,GAAI,IAAA,CAAK,OAAA,CAAQ,gBAAA,KAAqB,MAAA,GAClC,EAAE,gBAAA,EAAkB,IAAA,CAAK,OAAA,CAAQ,gBAAA,EAAiB,GAClD,EAAC;AAAA,MACL,GAAI,IAAA,CAAK,OAAA,CAAQ,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,EAAW,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAU,GAAI,EAAC;AAAA,MACpF,GAAI,IAAA,CAAK,OAAA,CAAQ,8BAAA,KAAmC,MAAA,GAChD,EAAE,gBAAA,EAAkB,IAAA,CAAK,OAAA,CAAQ,8BAAA,EAA+B,GAChE;AAAC,KACP;AAAA,EACF;AAAA,EAEQ,cAAA,GAA6E;AACnF,IAAA,OAAO;AAAA,MACL,GAAI,IAAA,CAAK,OAAA,CAAQ,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,EAAW,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAU,GAAI,EAAC;AAAA,MACpF,GAAI,IAAA,CAAK,OAAA,CAAQ,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,EAAQ,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAO,GAAI;AAAC,KAC7E;AAAA,EACF;AACF","file":"chunk-JHOX3VUW.js","sourcesContent":["/**\n * Binds renderable gprims — `UsdGeom.Mesh` plus the parametric solids (`Cube` /\n * `Sphere` / `Cylinder` / `Capsule` / `Cone`) — to Three.js geometry and\n * attaches them under the robot's link objects.\n *\n * Meshes are triangulated with a simple fan, use authored per-vertex normals\n * when present (else computed smooth normals), and read `primvars:st` UVs and\n * `primvars:displayColor`. Solids tessellate from their schema attributes.\n * Geometry is left in stage units; the global `metersPerUnit` scale is applied\n * at the root in M9.\n */\n\nimport * as THREE from \"three\";\nimport { type Mat4, identity4, multiply } from \"../kinematics/transforms.js\";\nimport type { Vec2, Vec3 } from \"../parser/ast.js\";\nimport type { RobotDescription } from \"../robot/RobotDescription.js\";\nimport {\n type MaterialSubset,\n getMaterialSubsets,\n isNonVisualPurpose,\n isRenderableGprim,\n} from \"../schemas/usdGeom.js\";\nimport { COLLISION_API } from \"../schemas/usdPhysics.js\";\nimport type { Prim } from \"../usd/Prim.js\";\nimport type { Stage } from \"../usd/Stage.js\";\nimport { computeLocalTransform, computeWorldTransform } from \"../usd/xformOps.js\";\nimport { type ResolvedTexture, resolveBoundMaterial } from \"./MaterialBinding.js\";\nimport type { TextureProvider } from \"./TextureBinding.js\";\nimport type { ThreeUsdRobot } from \"./ThreeUsdRobot.js\";\n\nexport type MeshKind = \"visual\" | \"collision\";\n\nconst DEFAULT_COLOR = 0x9a9a9a;\n\nexport type BindMeshesOptions = {\n loadVisuals?: boolean;\n loadCollisions?: boolean;\n /** Resolves diffuse texture asset paths to `THREE.Texture` (M-tex). */\n textureProvider?: TextureProvider;\n};\n\n/**\n * Build a `BufferGeometry` from a Mesh prim, or `null` if it has no points.\n *\n * When the mesh carries `materialBind` face subsets, the triangles are ordered\n * subset by subset and a geometry group is added for each — so the mesh can be\n * drawn with one material per subset (see {@link buildMeshMaterials}). Group\n * order matches {@link getMaterialSubsets}, with any unassigned faces last.\n */\nexport function buildMeshGeometry(meshPrim: Prim): THREE.BufferGeometry | null {\n const points = meshPrim.GetAttribute(\"points\").Get();\n if (!isVec3Array(points) || points.length === 0) return null;\n\n const geometry = new THREE.BufferGeometry();\n geometry.setAttribute(\"position\", new THREE.Float32BufferAttribute(flat3(points), 3));\n\n const counts = meshPrim.GetAttribute(\"faceVertexCounts\").Get();\n const indices = meshPrim.GetAttribute(\"faceVertexIndices\").Get();\n if (isNumberArray(counts) && isNumberArray(indices)) {\n const subsets = getMaterialSubsets(meshPrim);\n if (subsets.length > 0) {\n geometry.setIndex(triangulateBySubset(geometry, counts, indices, subsets));\n } else {\n geometry.setIndex(triangulate(counts, indices));\n }\n } else if (isNumberArray(indices)) {\n geometry.setIndex(indices.slice());\n }\n\n const normals = meshPrim.GetAttribute(\"normals\").Get();\n if (isVec3Array(normals) && normals.length === points.length) {\n geometry.setAttribute(\"normal\", new THREE.Float32BufferAttribute(flat3(normals), 3));\n } else {\n geometry.computeVertexNormals();\n }\n\n const st = meshPrim.GetAttribute(\"primvars:st\").Get();\n if (isVec2Array(st) && st.length === points.length) {\n geometry.setAttribute(\"uv\", new THREE.Float32BufferAttribute(flat2(st), 2));\n }\n\n return geometry;\n}\n\n/**\n * Build geometry for any renderable gprim: `Mesh` via {@link buildMeshGeometry},\n * parametric solids from their schema attributes. Solids follow UsdGeom\n * semantics — sizes in stage units, centered at the origin, `axis` (default\n * `\"Z\"`) along the spine, and a capsule's `height` spans only its cylindrical\n * section. Returns `null` for unsupported prim types.\n */\nexport function buildGprimGeometry(prim: Prim): THREE.BufferGeometry | null {\n switch (prim.GetTypeName()) {\n case \"Mesh\":\n return buildMeshGeometry(prim);\n case \"Cube\": {\n const size = getNumber(prim, \"size\") ?? 2;\n return new THREE.BoxGeometry(size, size, size);\n }\n case \"Sphere\":\n return new THREE.SphereGeometry(getNumber(prim, \"radius\") ?? 1, 32, 16);\n case \"Cylinder\": {\n const radius = getNumber(prim, \"radius\") ?? 1;\n const height = getNumber(prim, \"height\") ?? 2;\n return orientSpine(new THREE.CylinderGeometry(radius, radius, height, 32), prim);\n }\n case \"Capsule\": {\n const radius = getNumber(prim, \"radius\") ?? 0.5;\n const height = getNumber(prim, \"height\") ?? 1;\n return orientSpine(new THREE.CapsuleGeometry(radius, height, 8, 32), prim);\n }\n case \"Cone\": {\n const radius = getNumber(prim, \"radius\") ?? 1;\n const height = getNumber(prim, \"height\") ?? 2;\n return orientSpine(new THREE.ConeGeometry(radius, height, 32), prim);\n }\n default:\n return null;\n }\n}\n\nfunction getNumber(prim: Prim, name: string): number | undefined {\n const v = prim.GetAttribute(name).Get();\n return typeof v === \"number\" ? v : undefined;\n}\n\n/** Rotate a Y-spined three.js primitive onto the prim's `axis` (USD default `Z`). */\nfunction orientSpine(geometry: THREE.BufferGeometry, prim: Prim): THREE.BufferGeometry {\n const axis = prim.GetAttribute(\"axis\").Get();\n if (axis === \"Y\") return geometry;\n if (axis === \"X\") return geometry.rotateZ(-Math.PI / 2);\n return geometry.rotateX(Math.PI / 2);\n}\n\n/**\n * Build a material for a gprim. Color priority: bound `UsdShade` material\n * (when `stage` is given) → `primvars:displayColor` → default gray. Textures\n * (via `textures`) become the matching `MeshStandardMaterial` maps — diffuse →\n * `map` (sRGB), plus `normalMap` / `roughnessMap` / `metalnessMap` / `aoMap`\n * (linear data) and emissive `emissiveMap`. Metalness / roughness / opacity /\n * emissive constants come from the bound material when present.\n */\nexport function buildMeshMaterial(\n meshPrim: Prim,\n stage?: Stage,\n textures?: TextureProvider,\n /** Resolve the material binding from here instead (a `GeomSubset`). */\n bindingPrim?: Prim,\n): THREE.Material {\n const color = new THREE.Color(DEFAULT_COLOR);\n let opacity = 1;\n\n const bound = stage ? resolveBoundMaterial(stage, bindingPrim ?? meshPrim) : undefined;\n if (bound?.color) {\n color.setRGB(bound.color[0], bound.color[1], bound.color[2]);\n } else {\n const displayColor = meshPrim.GetAttribute(\"primvars:displayColor\").Get();\n if (isVec3Array(displayColor) && displayColor[0]) {\n const [r, g, b] = displayColor[0];\n color.setRGB(r, g, b);\n }\n }\n if (bound?.opacity !== undefined) opacity = bound.opacity;\n\n // Resolve a channel's `THREE.Texture`, forwarding its wrap modes and\n // `UsdTransform2d` (the `UsdUVTexture.inputs:scale`/`bias` are folded into the\n // material factors below, not the sampler).\n const tex = (rt: ResolvedTexture | undefined, cs: \"srgb\" | \"linear\") =>\n rt && textures\n ? textures(rt.path, {\n colorSpace: cs,\n ...(rt.wrapS ? { wrapS: rt.wrapS } : {}),\n ...(rt.wrapT ? { wrapT: rt.wrapT } : {}),\n ...(rt.transform ? { transform: rt.transform } : {}),\n })\n : null;\n\n const map = tex(bound?.colorTexture, \"srgb\");\n // `inputs:scale` on the diffuse texture tints the map; otherwise pass through.\n if (map) {\n const s = bound?.colorTexture?.scale;\n if (s) color.setRGB(s[0], s[1], s[2]);\n else color.setRGB(1, 1, 1);\n }\n const normalMap = tex(bound?.normalTexture, \"linear\");\n const roughnessMap = tex(bound?.roughnessTexture, \"linear\");\n const metalnessMap = tex(bound?.metalnessTexture, \"linear\");\n const aoMap = tex(bound?.occlusionTexture, \"linear\");\n const emissiveMap = tex(bound?.emissiveTexture, \"srgb\");\n\n // A scalar map's `inputs:scale[0]` (or an authored constant) becomes three's\n // factor; three multiplies factor × map, so default to 1 to pass it through.\n const metalness =\n bound?.metalness ?? bound?.metalnessTexture?.scale?.[0] ?? (metalnessMap ? 1 : 0.1);\n const roughness =\n bound?.roughness ?? bound?.roughnessTexture?.scale?.[0] ?? (roughnessMap ? 1 : 0.8);\n\n const emissive = new THREE.Color(0x000000);\n if (bound?.emissiveColor) {\n emissive.setRGB(bound.emissiveColor[0], bound.emissiveColor[1], bound.emissiveColor[2]);\n } else if (emissiveMap) {\n emissive.setRGB(1, 1, 1); // let the map drive emission\n }\n\n // Opacity sourcing: a dedicated opacity texture → `alphaMap`; an opacity input\n // wired to the *same* image as the diffuse map → that map's own alpha channel\n // (no separate map needed). `opacityThreshold > 0` means alpha clip (a binary\n // cutout rendered in the opaque pass); otherwise sub-unit alpha blends.\n const opacityTex = bound?.opacityTexture;\n const sharesColorMap = !!(opacityTex && opacityTex.path === bound?.colorTexture?.path);\n const alphaMap = sharesColorMap ? null : tex(opacityTex, \"linear\");\n const hasAlphaSource = opacity < 1 || sharesColorMap || !!alphaMap;\n const threshold = bound?.opacityThreshold;\n const alphaTest = threshold !== undefined && threshold > 0 ? threshold : 0;\n // Alpha-clip masks render opaque (depth-written, discarded below the cutoff);\n // only true translucency uses the transparent/blended pass.\n const transparent = alphaTest === 0 && hasAlphaSource;\n\n const doubleSided = meshPrim.GetAttribute(\"doubleSided\").Get() === true;\n const material = new THREE.MeshStandardMaterial({\n color,\n metalness,\n roughness,\n emissive,\n transparent,\n opacity,\n ...(alphaTest > 0 ? { alphaTest } : {}),\n side: doubleSided ? THREE.DoubleSide : THREE.FrontSide,\n ...(map ? { map } : {}),\n ...(alphaMap ? { alphaMap } : {}),\n ...(normalMap ? { normalMap } : {}),\n ...(roughnessMap ? { roughnessMap } : {}),\n ...(metalnessMap ? { metalnessMap } : {}),\n ...(aoMap ? { aoMap } : {}),\n ...(emissiveMap ? { emissiveMap } : {}),\n });\n // Carry the USD material name so re-exports keep it (and dedupe by it).\n if (bound?.name) material.name = bound.name;\n return material;\n}\n\n/**\n * Attach visual (and optionally collision) meshes to every link of a built\n * {@link ThreeUsdRobot}. Each mesh is positioned by its transform relative to\n * the owning link prim.\n */\nexport function bindRobotMeshes(\n stage: Stage,\n robot3d: ThreeUsdRobot,\n desc: RobotDescription,\n options: BindMeshesOptions = {},\n): void {\n const loadVisuals = options.loadVisuals ?? true;\n const loadCollisions = options.loadCollisions ?? false;\n const textures = options.textureProvider;\n\n for (const [key, link] of Object.entries(desc.links)) {\n const linkObj = robot3d.getLinkObject(key);\n const linkPrim = stage.GetPrimAtPath(link.primPath);\n if (!linkObj || !linkPrim) continue;\n\n // A mesh may be both visual and collision; attach it once, as visual.\n const visualSet = new Set(link.visualPrims);\n\n if (loadVisuals) {\n for (const meshPath of link.visualPrims) {\n attachMesh(stage, linkPrim, meshPath, linkObj, \"visual\", textures);\n }\n }\n if (loadCollisions) {\n for (const meshPath of link.collisionPrims ?? []) {\n if (loadVisuals && visualSet.has(meshPath)) continue;\n attachMesh(stage, linkPrim, meshPath, linkObj, \"collision\", textures);\n }\n }\n }\n}\n\n/**\n * Attach the gprims that belong to no link — the static scenery of a cell that\n * also contains robots. They are placed by their authored stage transform\n * under the robot root, so the loader's up-axis and unit normalization applies\n * to them too. Collision-only and guide/proxy prims are skipped.\n */\nexport function bindSceneMeshes(\n stage: Stage,\n robot3d: ThreeUsdRobot,\n desc: RobotDescription,\n options: { textureProvider?: TextureProvider } = {},\n): number {\n const owned = new Set<string>();\n for (const link of Object.values(desc.links)) {\n for (const path of link.visualPrims) owned.add(path);\n for (const path of link.collisionPrims ?? []) owned.add(path);\n owned.add(link.primPath);\n }\n\n let attached = 0;\n for (const prim of stage.Traverse()) {\n if (!isRenderableGprim(prim) || owned.has(prim.GetPath())) continue;\n if (prim.HasAPI(COLLISION_API) || isNonVisualPurpose(prim)) continue;\n // Skip gprims under a link (already bound relative to their link).\n if ([...owned].some((path) => prim.GetPath().startsWith(`${path}/`))) continue;\n\n const geometry = buildGprimGeometry(prim);\n if (!geometry) continue;\n const mesh = new THREE.Mesh(geometry, buildMeshMaterial(prim, stage, options.textureProvider));\n mesh.name = prim.GetName();\n mesh.userData.kind = \"scene\";\n mesh.userData.primPath = prim.GetPath();\n mesh.matrixAutoUpdate = false;\n mesh.matrix.fromArray(computeWorldTransform(prim));\n mesh.matrixWorldNeedsUpdate = true;\n robot3d.add(mesh);\n attached++;\n }\n return attached;\n}\n\n/**\n * Materials for a mesh: one per `materialBind` face subset (matching the\n * geometry groups {@link buildMeshGeometry} adds) plus a trailing fallback for\n * faces no subset claims. A mesh without subsets gets a single material.\n */\nexport function buildMeshMaterials(\n meshPrim: Prim,\n stage?: Stage,\n textures?: TextureProvider,\n): THREE.Material | THREE.Material[] {\n const subsets = stage ? getMaterialSubsets(meshPrim) : [];\n if (subsets.length === 0) return buildMeshMaterial(meshPrim, stage, textures);\n return [\n ...subsets.map((s) => buildMeshMaterial(meshPrim, stage, textures, s.prim)),\n buildMeshMaterial(meshPrim, stage, textures),\n ];\n}\n\nfunction attachMesh(\n stage: Stage,\n linkPrim: Prim,\n meshPath: string,\n parent: THREE.Object3D,\n kind: MeshKind,\n textures: TextureProvider | undefined,\n): void {\n const meshPrim = stage.GetPrimAtPath(meshPath);\n if (!meshPrim) return;\n const geometry = buildGprimGeometry(meshPrim);\n if (!geometry) return;\n\n const mesh = new THREE.Mesh(geometry, buildMeshMaterials(meshPrim, stage, textures));\n mesh.name = meshPrim.GetName();\n mesh.userData.kind = kind;\n mesh.userData.primPath = meshPath;\n // Collision meshes are loaded hidden; reveal via `robot.showCollision = true`.\n if (kind === \"collision\") mesh.visible = false;\n mesh.matrixAutoUpdate = false;\n mesh.matrix.fromArray(relativeTransform(linkPrim, meshPrim));\n mesh.matrixWorldNeedsUpdate = true;\n parent.add(mesh);\n}\n\n/** Accumulated local transform from `linkPrim` (exclusive) down to `meshPrim` (inclusive). */\nfunction relativeTransform(linkPrim: Prim, meshPrim: Prim): Mat4 {\n const chain: Prim[] = [];\n let p: Prim | null = meshPrim;\n const stop = linkPrim.GetPath();\n while (p && p.GetPath() !== stop) {\n chain.push(p);\n p = p.GetParent();\n }\n chain.reverse(); // top-most (just under link) → mesh\n\n let m = identity4();\n for (const prim of chain) {\n m = multiply(m, computeLocalTransform(prim).matrix);\n }\n return m;\n}\n\n// --- triangulation & typed-array helpers -----------------------------------\n\n/** Fan-triangulate USD polygon faces into a flat triangle index list. */\nfunction triangulate(faceVertexCounts: number[], faceVertexIndices: number[]): number[] {\n const tris: number[] = [];\n let offset = 0;\n for (const count of faceVertexCounts) {\n for (let k = 2; k < count; k++) {\n tris.push(\n faceVertexIndices[offset]!,\n faceVertexIndices[offset + k - 1]!,\n faceVertexIndices[offset + k]!,\n );\n }\n offset += count;\n }\n return tris;\n}\n\n/**\n * Triangulate subset by subset so each subset owns a contiguous run of the\n * index buffer, and register that run as a geometry group.\n */\nfunction triangulateBySubset(\n geometry: THREE.BufferGeometry,\n faceVertexCounts: number[],\n faceVertexIndices: number[],\n subsets: MaterialSubset[],\n): number[] {\n const faceStart: number[] = [];\n let offset = 0;\n for (const count of faceVertexCounts) {\n faceStart.push(offset);\n offset += count;\n }\n\n const tris: number[] = [];\n const emit = (face: number) => {\n const start = faceStart[face]!;\n const count = faceVertexCounts[face]!;\n for (let k = 2; k < count; k++) {\n tris.push(\n faceVertexIndices[start]!,\n faceVertexIndices[start + k - 1]!,\n faceVertexIndices[start + k]!,\n );\n }\n };\n\n const claimed = new Uint8Array(faceVertexCounts.length);\n subsets.forEach((subset, index) => {\n const begin = tris.length;\n for (const face of subset.faces) {\n if (face < 0 || face >= faceVertexCounts.length || claimed[face]) continue;\n claimed[face] = 1;\n emit(face);\n }\n if (tris.length > begin) geometry.addGroup(begin, tris.length - begin, index);\n });\n\n const begin = tris.length;\n for (let face = 0; face < faceVertexCounts.length; face++) {\n if (!claimed[face]) emit(face);\n }\n if (tris.length > begin) geometry.addGroup(begin, tris.length - begin, subsets.length);\n\n return tris;\n}\n\nfunction flat3(v: Vec3[]): number[] {\n const out = new Array<number>(v.length * 3);\n for (let i = 0; i < v.length; i++) {\n out[i * 3] = v[i]![0];\n out[i * 3 + 1] = v[i]![1];\n out[i * 3 + 2] = v[i]![2];\n }\n return out;\n}\n\nfunction flat2(v: Vec2[]): number[] {\n const out = new Array<number>(v.length * 2);\n for (let i = 0; i < v.length; i++) {\n out[i * 2] = v[i]![0];\n out[i * 2 + 1] = v[i]![1];\n }\n return out;\n}\n\nfunction isNumberArray(v: unknown): v is number[] {\n return Array.isArray(v) && v.every((n) => typeof n === \"number\");\n}\n\nfunction isVec3Array(v: unknown): v is Vec3[] {\n return Array.isArray(v) && v.every((e) => Array.isArray(e) && e.length === 3);\n}\n\nfunction isVec2Array(v: unknown): v is Vec2[] {\n return Array.isArray(v) && v.every((e) => Array.isArray(e) && e.length === 2);\n}\n","/**\n * Loads texture image assets referenced by `UsdShade` materials.\n *\n * A {@link TextureProvider} maps an authored asset path (plus sampler/transform\n * options) to a `THREE.Texture`. The default provider fetches the image **bytes**\n * through the {@link AssetResolver} and decodes them via a blob URL — so it works\n * uniformly for textures served over HTTP and for images embedded inside a\n * `.usdz` package (whose resolver serves zip entries, not real URLs). Decoded\n * images are cached per resolved URL and shared across every texture that uses\n * them; each `THREE.Texture` carries its own color space / wrap / transform.\n */\n\nimport * as THREE from \"three\";\nimport type { AssetResolver } from \"../usd/AssetResolver.js\";\nimport type { TextureTransform, TextureWrap } from \"./MaterialBinding.js\";\n\n/**\n * Color space to interpret a texture in. Color/albedo and emissive maps are\n * `\"srgb\"`; data maps (normal, roughness, metalness, occlusion) are `\"linear\"`.\n */\nexport type TextureColorSpace = \"srgb\" | \"linear\";\n\n/** Per-use sampler state applied to the returned `THREE.Texture`. */\nexport type TextureOptions = {\n /** Defaults to `\"srgb\"`. */\n colorSpace?: TextureColorSpace;\n wrapS?: TextureWrap;\n wrapT?: TextureWrap;\n transform?: TextureTransform;\n};\n\n/** Resolve an authored texture asset path to a `THREE.Texture` (or `null`). */\nexport type TextureProvider = (assetPath: string, options?: TextureOptions) => THREE.Texture | null;\n\nconst DEG2RAD = Math.PI / 180;\n\n/**\n * A {@link TextureProvider} backed by the {@link AssetResolver}, resolving paths\n * against `baseUrl`. Image bytes are fetched once per URL (works for HTTP and\n * `.usdz` entries alike) and the decoded image is shared; each call returns a\n * distinct `THREE.Texture` carrying the requested color space / wrap / transform.\n */\nexport function createTextureProvider(resolver: AssetResolver, baseUrl: string): TextureProvider {\n const images = new Map<string, Promise<TexImageSource>>();\n\n const imageFor = (url: string): Promise<TexImageSource> => {\n let p = images.get(url);\n if (!p) {\n p = loadImage(resolver, url);\n images.set(url, p);\n }\n return p;\n };\n\n return (assetPath: string, options: TextureOptions = {}) => {\n let url: string;\n try {\n url = resolver.resolve(assetPath, baseUrl);\n } catch {\n return null;\n }\n\n const texture = new THREE.Texture();\n texture.colorSpace =\n options.colorSpace === \"linear\" ? THREE.NoColorSpace : THREE.SRGBColorSpace;\n texture.wrapS = toThreeWrap(options.wrapS);\n texture.wrapT = toThreeWrap(options.wrapT);\n applyTransform(texture, options.transform);\n\n imageFor(url)\n .then((image) => {\n texture.image = image;\n texture.needsUpdate = true;\n })\n .catch(() => {\n /* leave the texture blank if the image can't be decoded */\n });\n return texture;\n };\n}\n\n/**\n * Fetch image bytes through the resolver and decode them via a blob URL into an\n * `HTMLImageElement` (so three's default `flipY = true` orients USD's bottom-left\n * `st` origin correctly, matching the prior `TextureLoader` HTTP path).\n */\nasync function loadImage(resolver: AssetResolver, url: string): Promise<TexImageSource> {\n const bytes = resolver.fetchBytes\n ? await resolver.fetchBytes(url)\n : new TextEncoder().encode(await resolver.fetchText(url));\n const blob = new Blob([bytes as BlobPart], { type: mimeOf(url) });\n const objectUrl = URL.createObjectURL(blob);\n try {\n return await new Promise<HTMLImageElement>((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error(`failed to decode texture: ${url}`));\n img.src = objectUrl;\n });\n } finally {\n // The decoded image keeps its pixels; the blob URL can be released.\n URL.revokeObjectURL(objectUrl);\n }\n}\n\nfunction toThreeWrap(wrap: TextureWrap | undefined): THREE.Wrapping {\n switch (wrap) {\n case \"clamp\":\n case \"black\": // three has no border color; clamp is the closest mode\n return THREE.ClampToEdgeWrapping;\n case \"mirror\":\n return THREE.MirroredRepeatWrapping;\n default:\n return THREE.RepeatWrapping;\n }\n}\n\n/** Map a `UsdTransform2d` onto a texture's offset / repeat / rotation. */\nfunction applyTransform(texture: THREE.Texture, t: TextureTransform | undefined): void {\n if (!t) return;\n if (t.scale) texture.repeat.set(t.scale[0], t.scale[1]);\n if (t.translation) texture.offset.set(t.translation[0], t.translation[1]);\n if (t.rotation !== undefined) {\n texture.rotation = t.rotation * DEG2RAD;\n texture.center.set(0, 0); // UsdTransform2d rotates about the origin\n }\n}\n\nfunction mimeOf(url: string): string {\n if (/\\.jpe?g$/i.test(url)) return \"image/jpeg\";\n if (/\\.webp$/i.test(url)) return \"image/webp\";\n return \"image/png\";\n}\n","import type { RobotDescription } from \"../robot/RobotDescription.js\";\nimport { extractRobotDescription } from \"../robot/RobotExtractor.js\";\nimport { buildKinematicTree } from \"../robot/buildKinematicTree.js\";\nimport { type AssetResolver, DefaultAssetResolver } from \"../usd/AssetResolver.js\";\nimport { Stage } from \"../usd/Stage.js\";\nimport { type BinarySource, type UsdSource, toBytes } from \"../usd/bytes.js\";\nimport { composeFile, composeLayer } from \"../usd/composition.js\";\nimport { CrateReader } from \"../usd/crate/CrateReader.js\";\nimport { crateToUsdaFile } from \"../usd/crate/toUsdaFile.js\";\nimport { isZip, openUsdz } from \"../usd/usdz.js\";\nimport { bindRobotMeshes, bindSceneMeshes } from \"./MeshBinding.js\";\nimport { createTextureProvider } from \"./TextureBinding.js\";\nimport { ThreeUsdRobot, type ThreeUsdRobotOptions, type WorldUpAxis } from \"./ThreeUsdRobot.js\";\n\nexport type ThreeUsdRobotLoaderOptions = {\n /** Resolver for references / payloads / sublayers (default {@link DefaultAssetResolver}). */\n assetResolver?: AssetResolver;\n /** Render visual meshes (M6). */\n loadVisuals?: boolean;\n /** Render collision meshes (M6). */\n loadCollisions?: boolean;\n /**\n * Also render gprims that belong to no link — the static scenery of a cell\n * that contains robots (floor, guarding, racking, …). Placed by their\n * authored stage transform. Default `false`; a stage with no articulation at\n * all (a pure static scene) defaults to `true` so it renders out of the box.\n */\n loadSceneGeometry?: boolean;\n /** Load diffuse textures referenced by materials (default `true`). */\n loadTextures?: boolean;\n /**\n * Target world up-axis. Any stage (Y-up or Z-up) is normalized into this\n * convention: `\"Y\"` for a standard three.js scene (the default behavior),\n * `\"Z\"` for a robotics-style Z-up world, `\"keep\"` to leave the authored\n * orientation. Takes precedence over {@link upAxisConversion}.\n */\n worldUp?: WorldUpAxis;\n /**\n * Legacy up-axis correction (M9). Default `\"auto\"` ≡ `worldUp: \"Y\"`.\n * @deprecated Use {@link worldUp}.\n */\n upAxisConversion?: \"auto\" | \"Y\" | \"Z\" | \"none\";\n /** Extra uniform scale multiplied with `metersPerUnit` (M9). */\n unitScale?: number;\n /** Clamp `setJointValue` to authored limits (default `true`). */\n clampJointLimits?: boolean;\n /** Seed joints from drive targets / joint state (M9). */\n applyDriveTargetsAsInitialPose?: boolean;\n /** Override the robot name. */\n robotName?: string;\n /** Receives non-fatal load diagnostics. */\n onWarn?: (message: string) => void;\n};\n\n/** A composed stage plus the context needed to bind its meshes and textures. */\ntype OpenedStage = { stage: Stage; baseUrl: string; resolver: AssetResolver };\n\n/**\n * Loads Isaac Sim / OpenUSD robot assets into a controllable {@link ThreeUsdRobot}.\n *\n * Assets load by URL ({@link loadAsync}) or from in-memory content\n * ({@link parse} — USDA text, `ArrayBuffer`, typed array, or `Blob`/`File`).\n * Composition (references / payloads / sublayers, M8) is resolved through an\n * {@link AssetResolver}. Mesh rendering is M6; unit / up-axis / initial-pose\n * handling is M9; USDC and variants are M10.\n */\nexport class ThreeUsdRobotLoader {\n readonly options: ThreeUsdRobotLoaderOptions;\n\n constructor(options: ThreeUsdRobotLoaderOptions = {}) {\n this.options = options;\n }\n\n private get resolver(): AssetResolver {\n return this.options.assetResolver ?? new DefaultAssetResolver();\n }\n\n /**\n * Fetch an asset by URL and build the robot. `.usdz` packages are unzipped and\n * composed from their entries; everything else is sniffed for the zip / crate\n * magic and parsed as USDZ, binary USDC, or USDA text.\n */\n async loadAsync(url: string): Promise<ThreeUsdRobot> {\n const bytes = await this.fetchRootBytes(url);\n // Extension first: sniffing only sees offset 0, the extension also covers\n // zip archives with a prefix (fflate reads the central directory anyway).\n if (/\\.usdz$/i.test(url)) return this.parseUsdz(bytes);\n return this.parse(bytes, url);\n }\n\n private async fetchRootBytes(url: string): Promise<Uint8Array> {\n const resolver = this.resolver;\n if (resolver.fetchBytes) return resolver.fetchBytes(url);\n return new TextEncoder().encode(await resolver.fetchText(url));\n }\n\n /**\n * Build a robot from in-memory content — no fetch involved. Accepts USDA\n * source text, or an `ArrayBuffer` / typed array / `Blob` (e.g. a dropped\n * `File`) holding USDA text, a binary crate, or a `.usdz` package; binary\n * input is sniffed for the zip / crate magic. `baseUrl` anchors relative\n * references, payloads, and texture paths of non-package input.\n */\n async parse(data: UsdSource, baseUrl = \"\"): Promise<ThreeUsdRobot> {\n return this.buildFromStage(await this.openSource(data, baseUrl));\n }\n\n /** Build a robot from a `.usdz` package (bytes, `ArrayBuffer`, or `Blob`). */\n async parseUsdz(data: BinarySource): Promise<ThreeUsdRobot> {\n return this.buildFromStage(await this.openUsdzStage(await toBytes(data)));\n }\n\n /** Build a robot from a binary crate (`.usdc` / binary `.usd`). */\n async parseCrate(data: BinarySource, baseUrl = \"\"): Promise<ThreeUsdRobot> {\n const stage = await this.composeStageFromBytes(await toBytes(data), baseUrl, this.resolver);\n return this.buildFromStage({ stage, baseUrl, resolver: this.resolver });\n }\n\n /**\n * Parse + compose in-memory content (same formats as {@link parse}) into the\n * Three.js-independent robot IR.\n */\n async parseRobotDescription(data: UsdSource, baseUrl = \"\"): Promise<RobotDescription> {\n const { stage } = await this.openSource(data, baseUrl);\n return extractRobotDescription(stage, this.extractOptions());\n }\n\n /** Sniff in-memory content (text / zip / crate) and compose it into a stage. */\n private async openSource(data: UsdSource, baseUrl: string): Promise<OpenedStage> {\n const resolver = this.resolver;\n if (typeof data === \"string\") {\n return { stage: await this.composeStage(data, baseUrl, resolver), baseUrl, resolver };\n }\n const bytes = await toBytes(data);\n if (isZip(bytes)) return this.openUsdzStage(bytes);\n const stage = CrateReader.isCrate(bytes)\n ? await this.composeStageFromBytes(bytes, baseUrl, resolver)\n : await this.composeStage(new TextDecoder().decode(bytes), baseUrl, resolver);\n return { stage, baseUrl, resolver };\n }\n\n private async openUsdzStage(bytes: Uint8Array): Promise<OpenedStage> {\n const pkg = openUsdz(bytes);\n // The root layer of a usdz is typically binary USDC — sniff, don't assume text.\n const rootBytes = await pkg.resolver.fetchBytes(pkg.rootEntry);\n const stage = await this.composeStageFromBytes(rootBytes, pkg.rootEntry, pkg.resolver);\n return { stage, baseUrl: pkg.rootEntry, resolver: pkg.resolver };\n }\n\n private buildFromStage({ stage, baseUrl, resolver }: OpenedStage): ThreeUsdRobot {\n const robot = extractRobotDescription(stage, this.extractOptions());\n const tree = buildKinematicTree(robot);\n const robot3d = new ThreeUsdRobot(robot, tree, this.robotOptions());\n\n const loadVisuals = this.options.loadVisuals ?? true;\n const loadCollisions = this.options.loadCollisions ?? false;\n // A stage with no articulation at all is a pure static scene; default to\n // drawing its geometry — otherwise the load would be silently empty.\n const isStaticScene =\n Object.keys(robot.links).length === 0 && Object.keys(robot.joints).length === 0;\n if (isStaticScene && this.options.loadSceneGeometry === undefined) {\n this.options.onWarn?.(\n \"no articulation found (0 links / 0 joints); rendering the stage as static scene geometry\",\n );\n }\n const loadScene = this.options.loadSceneGeometry ?? isStaticScene;\n if (loadVisuals || loadCollisions || loadScene) {\n const textureProvider =\n (this.options.loadTextures ?? true) ? createTextureProvider(resolver, baseUrl) : undefined;\n if (loadVisuals || loadCollisions) {\n bindRobotMeshes(stage, robot3d, robot, {\n loadVisuals,\n loadCollisions,\n ...(textureProvider ? { textureProvider } : {}),\n });\n }\n if (loadScene) {\n bindSceneMeshes(stage, robot3d, robot, {\n ...(textureProvider ? { textureProvider } : {}),\n });\n }\n }\n return robot3d;\n }\n\n private async composeStage(\n text: string,\n baseUrl: string,\n resolver: AssetResolver,\n ): Promise<Stage> {\n const composeOptions = this.options.onWarn ? { onWarn: this.options.onWarn } : {};\n return Stage.OpenFromFile(await composeLayer(text, baseUrl, resolver, composeOptions));\n }\n\n /** Compose a layer from raw bytes, sniffing binary crate vs USDA text. */\n private async composeStageFromBytes(\n bytes: Uint8Array,\n baseUrl: string,\n resolver: AssetResolver,\n ): Promise<Stage> {\n const composeOptions = this.options.onWarn ? { onWarn: this.options.onWarn } : {};\n const composed = CrateReader.isCrate(bytes)\n ? await composeFile(\n crateToUsdaFile(new CrateReader(bytes)),\n baseUrl,\n resolver,\n composeOptions,\n )\n : await composeLayer(new TextDecoder().decode(bytes), baseUrl, resolver, composeOptions);\n return Stage.OpenFromFile(composed);\n }\n\n private robotOptions(): ThreeUsdRobotOptions {\n return {\n ...(this.options.worldUp\n ? { worldUp: this.options.worldUp }\n : { upAxisConversion: this.options.upAxisConversion ?? \"auto\" }),\n ...(this.options.clampJointLimits !== undefined\n ? { clampJointLimits: this.options.clampJointLimits }\n : {}),\n ...(this.options.unitScale !== undefined ? { unitScale: this.options.unitScale } : {}),\n ...(this.options.applyDriveTargetsAsInitialPose !== undefined\n ? { applyInitialPose: this.options.applyDriveTargetsAsInitialPose }\n : {}),\n };\n }\n\n private extractOptions(): { robotName?: string; onWarn?: (message: string) => void } {\n return {\n ...(this.options.robotName !== undefined ? { robotName: this.options.robotName } : {}),\n ...(this.options.onWarn !== undefined ? { onWarn: this.options.onWarn } : {}),\n };\n }\n}\n"]}
package/dist/extras.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { T as ThreeUsdRobot } from './ThreeUsdRobot-CsjraHqP.js';
1
+ import { T as ThreeUsdRobot } from './ThreeUsdRobot-BZ_vlr1R.js';
2
2
  import 'three';
3
3
  import './buildKinematicTree-D4R0hEtN.js';
4
4
 
package/dist/helpers.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as THREE from 'three';
2
- import { T as ThreeUsdRobot, J as JointObject } from './ThreeUsdRobot-CsjraHqP.js';
2
+ import { T as ThreeUsdRobot, J as JointObject } from './ThreeUsdRobot-BZ_vlr1R.js';
3
3
  import './buildKinematicTree-D4R0hEtN.js';
4
4
 
5
5
  /**
package/dist/helpers.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ThreeUsdRobot } from './chunk-3CANZKP3.js';
1
+ import { ThreeUsdRobot } from './chunk-FUPFJOXW.js';
2
2
  import './chunk-IYKPVUZ2.js';
3
3
  import * as THREE3 from 'three';
4
4
 
package/dist/index.d.ts CHANGED
@@ -3,11 +3,11 @@ export { ARTICULATION_ROOT_API, Attribute, COLLISION_API, ComposeOptions, CrateR
3
3
  import * as THREE from 'three';
4
4
  import { A as Axis, V as Vec2, b as Vec3, R as RobotDescription, c as JointDriveDescription, d as LinkInertialDescription, K as KinematicTree, U as UsdaFile, M as Mat4 } from './buildKinematicTree-D4R0hEtN.js';
5
5
  export { e as AssetPath, f as AttributeSpec, B as BuildTreeOptions, C as CompositionArc, D as DEG2RAD, a as JointDescription, J as JointType, g as KinematicNode, L as LinkDescription, h as ListOp, i as MetadataMap, P as PrimSpec, j as PropertySpec, Q as Quat, k as RAD2DEG, l as RelationshipSpec, S as SampleChannel, m as SdfPath, n as Specifier, T as TreeEdge, o as UsdDictionary, p as UsdMatrix, q as UsdValue, r as Variability, s as Vec4, t as buildKinematicTree, u as channelFromSamples, v as decomposeRigid, w as fromUsdMatrix, x as getTranslation, y as identity4, z as interpolate, E as invert, F as makeEuler, G as makeRotationFromQuat, H as makeRotationX, I as makeRotationY, N as makeRotationZ, O as makeScale, W as makeTranslation, X as multiply, Y as multiplyAll, Z as toUsdMatrix } from './buildKinematicTree-D4R0hEtN.js';
6
- import { T as ThreeUsdRobot } from './ThreeUsdRobot-CsjraHqP.js';
7
- export { J as JointObject, L as LinkObject, a as ThreeUsdRobotOptions } from './ThreeUsdRobot-CsjraHqP.js';
6
+ import { T as ThreeUsdRobot } from './ThreeUsdRobot-BZ_vlr1R.js';
7
+ export { J as JointObject, L as LinkObject, a as ThreeUsdRobotOptions, W as WorldUpAxis } from './ThreeUsdRobot-BZ_vlr1R.js';
8
8
  import { A as AssetResolver } from './bytes-MOJ2oN-u.js';
9
9
  export { B as BinarySource, D as DefaultAssetResolver, U as UsdSource, c as createMemoryResolver, j as joinPosix, t as toBytes } from './bytes-MOJ2oN-u.js';
10
- export { a as ThreeUsdRobotLoader, T as ThreeUsdRobotLoaderOptions } from './ThreeUsdRobotLoader-CxOGRLXH.js';
10
+ export { a as ThreeUsdRobotLoader, T as ThreeUsdRobotLoaderOptions } from './ThreeUsdRobotLoader-HteyMZf1.js';
11
11
 
12
12
  /** Unit vector for a USD joint axis token. Returns a fresh vector each call. */
13
13
  declare function axisVector(axis: Axis): THREE.Vector3;
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { stageGeometryProvider, exportRobotUsda } from './chunk-P6CHTMGW.js';
2
2
  export { PACKAGE_NAME, VERSION, exportRobotUsda, stageGeometryProvider, validateRobotDescription, writeUsdz } from './chunk-P6CHTMGW.js';
3
- export { ThreeUsdRobotLoader, bindRobotMeshes, bindSceneMeshes, buildGprimGeometry, buildMeshGeometry, buildMeshMaterial, createTextureProvider } from './chunk-YX5GIEMT.js';
3
+ export { ThreeUsdRobotLoader, bindRobotMeshes, bindSceneMeshes, buildGprimGeometry, buildMeshGeometry, buildMeshMaterial, createTextureProvider } from './chunk-JHOX3VUW.js';
4
4
  import { refineJointType, buildKinematicTree } from './chunk-PHHMWMCA.js';
5
5
  export { ARTICULATION_ROOT_API, Attribute, COLLISION_API, CrateReader, DEFAULT_METERS_PER_UNIT, DefaultAssetResolver, Layer, MASS_API, MESH_COLLISION_API, PHYSICS_MATERIAL_API, ParseError, Prim, RIGID_BODY_API, Relationship, Stage, TokenizeError, buildKinematicTree, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, createMemoryResolver, driveKindFor, extractRobotDescription, gatherGprimDescendants, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, isMesh, isRenderableGprim, isScope, isSolidGprim, isXform, isZip, iterDescendants, joinPosix, jointValueFromSI, jointValueToSI, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, resolveBoundMaterial, serializeUsda, toBytes, tokenize } from './chunk-PHHMWMCA.js';
6
- export { JointObject, LinkObject, ThreeUsdRobot, axisVector } from './chunk-3CANZKP3.js';
6
+ export { JointObject, LinkObject, ThreeUsdRobot, axisVector } from './chunk-FUPFJOXW.js';
7
7
  import { identity4, multiply, invert } from './chunk-IYKPVUZ2.js';
8
8
  export { AssetPath, DEG2RAD, Quat, RAD2DEG, UsdMatrix, channelFromSamples, decomposeRigid, fromUsdMatrix, getTranslation, identity4, interpolate, invert, makeEuler, makeRotationFromQuat, makeRotationX, makeRotationY, makeRotationZ, makeScale, makeTranslation, multiply, multiplyAll, toUsdMatrix } from './chunk-IYKPVUZ2.js';
9
9
  import * as THREE from 'three';
package/dist/react.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as _react_three_fiber from '@react-three/fiber';
2
2
  import { ThreeElements } from '@react-three/fiber';
3
3
  import * as React from 'react';
4
- import { T as ThreeUsdRobot } from './ThreeUsdRobot-CsjraHqP.js';
5
- import { T as ThreeUsdRobotLoaderOptions } from './ThreeUsdRobotLoader-CxOGRLXH.js';
4
+ import { T as ThreeUsdRobot } from './ThreeUsdRobot-BZ_vlr1R.js';
5
+ import { T as ThreeUsdRobotLoaderOptions } from './ThreeUsdRobotLoader-HteyMZf1.js';
6
6
  import 'three';
7
7
  import './buildKinematicTree-D4R0hEtN.js';
8
8
  import './bytes-MOJ2oN-u.js';
package/dist/react.js CHANGED
@@ -1,6 +1,6 @@
1
- import { ThreeUsdRobotLoader } from './chunk-YX5GIEMT.js';
1
+ import { ThreeUsdRobotLoader } from './chunk-JHOX3VUW.js';
2
2
  import './chunk-PHHMWMCA.js';
3
- import './chunk-3CANZKP3.js';
3
+ import './chunk-FUPFJOXW.js';
4
4
  import './chunk-IYKPVUZ2.js';
5
5
  import { useFrame } from '@react-three/fiber';
6
6
  import * as React from 'react';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "three-usd-robot",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "Kinematic OpenUSD robot loader for Three.js — load Isaac Sim / OpenUSD robot assets, extract joints and links, and control articulations in the browser.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1 +0,0 @@
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-3CANZKP3.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 { Axis, JointDescription, JointType } 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\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 }\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 { interpolate } from \"../kinematics/sampling.js\";\nimport { type Mat4, invert, multiply } 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 { JointObject } from \"./JointObject.js\";\nimport { LinkObject } from \"./LinkObject.js\";\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 * Up-axis correction applied at the robot root. `\"auto\"` rotates Z-up assets\n * into the Three.js Y-up scene; `\"Z\"` forces it, `\"Y\"`/`\"none\"` leave the\n * orientation as authored. Default `\"none\"` (the loader defaults to `\"auto\"`).\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\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 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 private dirty = true;\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.applyStageNormalization(robot, options);\n if (options.applyInitialPose ?? true) this.applyInitialPose(robot);\n }\n\n /** Orient (Z-up → Y-up) and scale (metersPerUnit × unitScale) the robot 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 conv = options.upAxisConversion ?? \"none\";\n const toY = conv === \"Z\" || (conv === \"auto\" && robot.upAxis === \"Z\");\n if (toY) this.quaternion.setFromAxisAngle(new THREE.Vector3(1, 0, 0), -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 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. Returns whether it applied.\n */\n setJointValue(name: string, value: number): boolean {\n const joint = this.jointObjects.get(this.jointKey(name));\n if (!joint) return false;\n joint.setValue(value, this.clampJointLimits);\n this.dirty = true;\n return true;\n }\n\n /** Set several joint values at once (matrix update is coalesced). */\n setJointValues(values: Record<string, number>): void {\n for (const [name, value] of Object.entries(values)) {\n const joint = this.jointObjects.get(this.jointKey(name));\n if (joint) {\n joint.setValue(value, this.clampJointLimits);\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 // -- 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 /** Names of the articulated (controllable) joints. */\n getJointNames(): string[] {\n return [...this.jointObjects.keys()];\n }\n\n getLinkNames(): string[] {\n return [...this.linkObjects.keys()];\n }\n\n getKinematicTree(): KinematicTree {\n return this.tree;\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 /** Sample every animated joint at time code `t` and apply the values. */\n setTime(t: number): void {\n for (const [key, joint] of Object.entries(this.robot.joints)) {\n if (joint.valueSamples) 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\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"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/three/MeshBinding.ts","../src/three/TextureBinding.ts","../src/three/ThreeUsdRobotLoader.ts"],"names":["begin","THREE2"],"mappings":"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","file":"chunk-YX5GIEMT.js","sourcesContent":["/**\n * Binds renderable gprims — `UsdGeom.Mesh` plus the parametric solids (`Cube` /\n * `Sphere` / `Cylinder` / `Capsule` / `Cone`) — to Three.js geometry and\n * attaches them under the robot's link objects.\n *\n * Meshes are triangulated with a simple fan, use authored per-vertex normals\n * when present (else computed smooth normals), and read `primvars:st` UVs and\n * `primvars:displayColor`. Solids tessellate from their schema attributes.\n * Geometry is left in stage units; the global `metersPerUnit` scale is applied\n * at the root in M9.\n */\n\nimport * as THREE from \"three\";\nimport { type Mat4, identity4, multiply } from \"../kinematics/transforms.js\";\nimport type { Vec2, Vec3 } from \"../parser/ast.js\";\nimport type { RobotDescription } from \"../robot/RobotDescription.js\";\nimport {\n type MaterialSubset,\n getMaterialSubsets,\n isNonVisualPurpose,\n isRenderableGprim,\n} from \"../schemas/usdGeom.js\";\nimport { COLLISION_API } from \"../schemas/usdPhysics.js\";\nimport type { Prim } from \"../usd/Prim.js\";\nimport type { Stage } from \"../usd/Stage.js\";\nimport { computeLocalTransform, computeWorldTransform } from \"../usd/xformOps.js\";\nimport { type ResolvedTexture, resolveBoundMaterial } from \"./MaterialBinding.js\";\nimport type { TextureProvider } from \"./TextureBinding.js\";\nimport type { ThreeUsdRobot } from \"./ThreeUsdRobot.js\";\n\nexport type MeshKind = \"visual\" | \"collision\";\n\nconst DEFAULT_COLOR = 0x9a9a9a;\n\nexport type BindMeshesOptions = {\n loadVisuals?: boolean;\n loadCollisions?: boolean;\n /** Resolves diffuse texture asset paths to `THREE.Texture` (M-tex). */\n textureProvider?: TextureProvider;\n};\n\n/**\n * Build a `BufferGeometry` from a Mesh prim, or `null` if it has no points.\n *\n * When the mesh carries `materialBind` face subsets, the triangles are ordered\n * subset by subset and a geometry group is added for each — so the mesh can be\n * drawn with one material per subset (see {@link buildMeshMaterials}). Group\n * order matches {@link getMaterialSubsets}, with any unassigned faces last.\n */\nexport function buildMeshGeometry(meshPrim: Prim): THREE.BufferGeometry | null {\n const points = meshPrim.GetAttribute(\"points\").Get();\n if (!isVec3Array(points) || points.length === 0) return null;\n\n const geometry = new THREE.BufferGeometry();\n geometry.setAttribute(\"position\", new THREE.Float32BufferAttribute(flat3(points), 3));\n\n const counts = meshPrim.GetAttribute(\"faceVertexCounts\").Get();\n const indices = meshPrim.GetAttribute(\"faceVertexIndices\").Get();\n if (isNumberArray(counts) && isNumberArray(indices)) {\n const subsets = getMaterialSubsets(meshPrim);\n if (subsets.length > 0) {\n geometry.setIndex(triangulateBySubset(geometry, counts, indices, subsets));\n } else {\n geometry.setIndex(triangulate(counts, indices));\n }\n } else if (isNumberArray(indices)) {\n geometry.setIndex(indices.slice());\n }\n\n const normals = meshPrim.GetAttribute(\"normals\").Get();\n if (isVec3Array(normals) && normals.length === points.length) {\n geometry.setAttribute(\"normal\", new THREE.Float32BufferAttribute(flat3(normals), 3));\n } else {\n geometry.computeVertexNormals();\n }\n\n const st = meshPrim.GetAttribute(\"primvars:st\").Get();\n if (isVec2Array(st) && st.length === points.length) {\n geometry.setAttribute(\"uv\", new THREE.Float32BufferAttribute(flat2(st), 2));\n }\n\n return geometry;\n}\n\n/**\n * Build geometry for any renderable gprim: `Mesh` via {@link buildMeshGeometry},\n * parametric solids from their schema attributes. Solids follow UsdGeom\n * semantics — sizes in stage units, centered at the origin, `axis` (default\n * `\"Z\"`) along the spine, and a capsule's `height` spans only its cylindrical\n * section. Returns `null` for unsupported prim types.\n */\nexport function buildGprimGeometry(prim: Prim): THREE.BufferGeometry | null {\n switch (prim.GetTypeName()) {\n case \"Mesh\":\n return buildMeshGeometry(prim);\n case \"Cube\": {\n const size = getNumber(prim, \"size\") ?? 2;\n return new THREE.BoxGeometry(size, size, size);\n }\n case \"Sphere\":\n return new THREE.SphereGeometry(getNumber(prim, \"radius\") ?? 1, 32, 16);\n case \"Cylinder\": {\n const radius = getNumber(prim, \"radius\") ?? 1;\n const height = getNumber(prim, \"height\") ?? 2;\n return orientSpine(new THREE.CylinderGeometry(radius, radius, height, 32), prim);\n }\n case \"Capsule\": {\n const radius = getNumber(prim, \"radius\") ?? 0.5;\n const height = getNumber(prim, \"height\") ?? 1;\n return orientSpine(new THREE.CapsuleGeometry(radius, height, 8, 32), prim);\n }\n case \"Cone\": {\n const radius = getNumber(prim, \"radius\") ?? 1;\n const height = getNumber(prim, \"height\") ?? 2;\n return orientSpine(new THREE.ConeGeometry(radius, height, 32), prim);\n }\n default:\n return null;\n }\n}\n\nfunction getNumber(prim: Prim, name: string): number | undefined {\n const v = prim.GetAttribute(name).Get();\n return typeof v === \"number\" ? v : undefined;\n}\n\n/** Rotate a Y-spined three.js primitive onto the prim's `axis` (USD default `Z`). */\nfunction orientSpine(geometry: THREE.BufferGeometry, prim: Prim): THREE.BufferGeometry {\n const axis = prim.GetAttribute(\"axis\").Get();\n if (axis === \"Y\") return geometry;\n if (axis === \"X\") return geometry.rotateZ(-Math.PI / 2);\n return geometry.rotateX(Math.PI / 2);\n}\n\n/**\n * Build a material for a gprim. Color priority: bound `UsdShade` material\n * (when `stage` is given) → `primvars:displayColor` → default gray. Textures\n * (via `textures`) become the matching `MeshStandardMaterial` maps — diffuse →\n * `map` (sRGB), plus `normalMap` / `roughnessMap` / `metalnessMap` / `aoMap`\n * (linear data) and emissive `emissiveMap`. Metalness / roughness / opacity /\n * emissive constants come from the bound material when present.\n */\nexport function buildMeshMaterial(\n meshPrim: Prim,\n stage?: Stage,\n textures?: TextureProvider,\n /** Resolve the material binding from here instead (a `GeomSubset`). */\n bindingPrim?: Prim,\n): THREE.Material {\n const color = new THREE.Color(DEFAULT_COLOR);\n let opacity = 1;\n\n const bound = stage ? resolveBoundMaterial(stage, bindingPrim ?? meshPrim) : undefined;\n if (bound?.color) {\n color.setRGB(bound.color[0], bound.color[1], bound.color[2]);\n } else {\n const displayColor = meshPrim.GetAttribute(\"primvars:displayColor\").Get();\n if (isVec3Array(displayColor) && displayColor[0]) {\n const [r, g, b] = displayColor[0];\n color.setRGB(r, g, b);\n }\n }\n if (bound?.opacity !== undefined) opacity = bound.opacity;\n\n // Resolve a channel's `THREE.Texture`, forwarding its wrap modes and\n // `UsdTransform2d` (the `UsdUVTexture.inputs:scale`/`bias` are folded into the\n // material factors below, not the sampler).\n const tex = (rt: ResolvedTexture | undefined, cs: \"srgb\" | \"linear\") =>\n rt && textures\n ? textures(rt.path, {\n colorSpace: cs,\n ...(rt.wrapS ? { wrapS: rt.wrapS } : {}),\n ...(rt.wrapT ? { wrapT: rt.wrapT } : {}),\n ...(rt.transform ? { transform: rt.transform } : {}),\n })\n : null;\n\n const map = tex(bound?.colorTexture, \"srgb\");\n // `inputs:scale` on the diffuse texture tints the map; otherwise pass through.\n if (map) {\n const s = bound?.colorTexture?.scale;\n if (s) color.setRGB(s[0], s[1], s[2]);\n else color.setRGB(1, 1, 1);\n }\n const normalMap = tex(bound?.normalTexture, \"linear\");\n const roughnessMap = tex(bound?.roughnessTexture, \"linear\");\n const metalnessMap = tex(bound?.metalnessTexture, \"linear\");\n const aoMap = tex(bound?.occlusionTexture, \"linear\");\n const emissiveMap = tex(bound?.emissiveTexture, \"srgb\");\n\n // A scalar map's `inputs:scale[0]` (or an authored constant) becomes three's\n // factor; three multiplies factor × map, so default to 1 to pass it through.\n const metalness =\n bound?.metalness ?? bound?.metalnessTexture?.scale?.[0] ?? (metalnessMap ? 1 : 0.1);\n const roughness =\n bound?.roughness ?? bound?.roughnessTexture?.scale?.[0] ?? (roughnessMap ? 1 : 0.8);\n\n const emissive = new THREE.Color(0x000000);\n if (bound?.emissiveColor) {\n emissive.setRGB(bound.emissiveColor[0], bound.emissiveColor[1], bound.emissiveColor[2]);\n } else if (emissiveMap) {\n emissive.setRGB(1, 1, 1); // let the map drive emission\n }\n\n // Opacity sourcing: a dedicated opacity texture → `alphaMap`; an opacity input\n // wired to the *same* image as the diffuse map → that map's own alpha channel\n // (no separate map needed). `opacityThreshold > 0` means alpha clip (a binary\n // cutout rendered in the opaque pass); otherwise sub-unit alpha blends.\n const opacityTex = bound?.opacityTexture;\n const sharesColorMap = !!(opacityTex && opacityTex.path === bound?.colorTexture?.path);\n const alphaMap = sharesColorMap ? null : tex(opacityTex, \"linear\");\n const hasAlphaSource = opacity < 1 || sharesColorMap || !!alphaMap;\n const threshold = bound?.opacityThreshold;\n const alphaTest = threshold !== undefined && threshold > 0 ? threshold : 0;\n // Alpha-clip masks render opaque (depth-written, discarded below the cutoff);\n // only true translucency uses the transparent/blended pass.\n const transparent = alphaTest === 0 && hasAlphaSource;\n\n const doubleSided = meshPrim.GetAttribute(\"doubleSided\").Get() === true;\n const material = new THREE.MeshStandardMaterial({\n color,\n metalness,\n roughness,\n emissive,\n transparent,\n opacity,\n ...(alphaTest > 0 ? { alphaTest } : {}),\n side: doubleSided ? THREE.DoubleSide : THREE.FrontSide,\n ...(map ? { map } : {}),\n ...(alphaMap ? { alphaMap } : {}),\n ...(normalMap ? { normalMap } : {}),\n ...(roughnessMap ? { roughnessMap } : {}),\n ...(metalnessMap ? { metalnessMap } : {}),\n ...(aoMap ? { aoMap } : {}),\n ...(emissiveMap ? { emissiveMap } : {}),\n });\n // Carry the USD material name so re-exports keep it (and dedupe by it).\n if (bound?.name) material.name = bound.name;\n return material;\n}\n\n/**\n * Attach visual (and optionally collision) meshes to every link of a built\n * {@link ThreeUsdRobot}. Each mesh is positioned by its transform relative to\n * the owning link prim.\n */\nexport function bindRobotMeshes(\n stage: Stage,\n robot3d: ThreeUsdRobot,\n desc: RobotDescription,\n options: BindMeshesOptions = {},\n): void {\n const loadVisuals = options.loadVisuals ?? true;\n const loadCollisions = options.loadCollisions ?? false;\n const textures = options.textureProvider;\n\n for (const [key, link] of Object.entries(desc.links)) {\n const linkObj = robot3d.getLinkObject(key);\n const linkPrim = stage.GetPrimAtPath(link.primPath);\n if (!linkObj || !linkPrim) continue;\n\n // A mesh may be both visual and collision; attach it once, as visual.\n const visualSet = new Set(link.visualPrims);\n\n if (loadVisuals) {\n for (const meshPath of link.visualPrims) {\n attachMesh(stage, linkPrim, meshPath, linkObj, \"visual\", textures);\n }\n }\n if (loadCollisions) {\n for (const meshPath of link.collisionPrims ?? []) {\n if (loadVisuals && visualSet.has(meshPath)) continue;\n attachMesh(stage, linkPrim, meshPath, linkObj, \"collision\", textures);\n }\n }\n }\n}\n\n/**\n * Attach the gprims that belong to no link — the static scenery of a cell that\n * also contains robots. They are placed by their authored stage transform\n * under the robot root, so the loader's up-axis and unit normalization applies\n * to them too. Collision-only and guide/proxy prims are skipped.\n */\nexport function bindSceneMeshes(\n stage: Stage,\n robot3d: ThreeUsdRobot,\n desc: RobotDescription,\n options: { textureProvider?: TextureProvider } = {},\n): number {\n const owned = new Set<string>();\n for (const link of Object.values(desc.links)) {\n for (const path of link.visualPrims) owned.add(path);\n for (const path of link.collisionPrims ?? []) owned.add(path);\n owned.add(link.primPath);\n }\n\n let attached = 0;\n for (const prim of stage.Traverse()) {\n if (!isRenderableGprim(prim) || owned.has(prim.GetPath())) continue;\n if (prim.HasAPI(COLLISION_API) || isNonVisualPurpose(prim)) continue;\n // Skip gprims under a link (already bound relative to their link).\n if ([...owned].some((path) => prim.GetPath().startsWith(`${path}/`))) continue;\n\n const geometry = buildGprimGeometry(prim);\n if (!geometry) continue;\n const mesh = new THREE.Mesh(geometry, buildMeshMaterial(prim, stage, options.textureProvider));\n mesh.name = prim.GetName();\n mesh.userData.kind = \"scene\";\n mesh.userData.primPath = prim.GetPath();\n mesh.matrixAutoUpdate = false;\n mesh.matrix.fromArray(computeWorldTransform(prim));\n mesh.matrixWorldNeedsUpdate = true;\n robot3d.add(mesh);\n attached++;\n }\n return attached;\n}\n\n/**\n * Materials for a mesh: one per `materialBind` face subset (matching the\n * geometry groups {@link buildMeshGeometry} adds) plus a trailing fallback for\n * faces no subset claims. A mesh without subsets gets a single material.\n */\nexport function buildMeshMaterials(\n meshPrim: Prim,\n stage?: Stage,\n textures?: TextureProvider,\n): THREE.Material | THREE.Material[] {\n const subsets = stage ? getMaterialSubsets(meshPrim) : [];\n if (subsets.length === 0) return buildMeshMaterial(meshPrim, stage, textures);\n return [\n ...subsets.map((s) => buildMeshMaterial(meshPrim, stage, textures, s.prim)),\n buildMeshMaterial(meshPrim, stage, textures),\n ];\n}\n\nfunction attachMesh(\n stage: Stage,\n linkPrim: Prim,\n meshPath: string,\n parent: THREE.Object3D,\n kind: MeshKind,\n textures: TextureProvider | undefined,\n): void {\n const meshPrim = stage.GetPrimAtPath(meshPath);\n if (!meshPrim) return;\n const geometry = buildGprimGeometry(meshPrim);\n if (!geometry) return;\n\n const mesh = new THREE.Mesh(geometry, buildMeshMaterials(meshPrim, stage, textures));\n mesh.name = meshPrim.GetName();\n mesh.userData.kind = kind;\n mesh.userData.primPath = meshPath;\n // Collision meshes are loaded hidden; reveal via `robot.showCollision = true`.\n if (kind === \"collision\") mesh.visible = false;\n mesh.matrixAutoUpdate = false;\n mesh.matrix.fromArray(relativeTransform(linkPrim, meshPrim));\n mesh.matrixWorldNeedsUpdate = true;\n parent.add(mesh);\n}\n\n/** Accumulated local transform from `linkPrim` (exclusive) down to `meshPrim` (inclusive). */\nfunction relativeTransform(linkPrim: Prim, meshPrim: Prim): Mat4 {\n const chain: Prim[] = [];\n let p: Prim | null = meshPrim;\n const stop = linkPrim.GetPath();\n while (p && p.GetPath() !== stop) {\n chain.push(p);\n p = p.GetParent();\n }\n chain.reverse(); // top-most (just under link) → mesh\n\n let m = identity4();\n for (const prim of chain) {\n m = multiply(m, computeLocalTransform(prim).matrix);\n }\n return m;\n}\n\n// --- triangulation & typed-array helpers -----------------------------------\n\n/** Fan-triangulate USD polygon faces into a flat triangle index list. */\nfunction triangulate(faceVertexCounts: number[], faceVertexIndices: number[]): number[] {\n const tris: number[] = [];\n let offset = 0;\n for (const count of faceVertexCounts) {\n for (let k = 2; k < count; k++) {\n tris.push(\n faceVertexIndices[offset]!,\n faceVertexIndices[offset + k - 1]!,\n faceVertexIndices[offset + k]!,\n );\n }\n offset += count;\n }\n return tris;\n}\n\n/**\n * Triangulate subset by subset so each subset owns a contiguous run of the\n * index buffer, and register that run as a geometry group.\n */\nfunction triangulateBySubset(\n geometry: THREE.BufferGeometry,\n faceVertexCounts: number[],\n faceVertexIndices: number[],\n subsets: MaterialSubset[],\n): number[] {\n const faceStart: number[] = [];\n let offset = 0;\n for (const count of faceVertexCounts) {\n faceStart.push(offset);\n offset += count;\n }\n\n const tris: number[] = [];\n const emit = (face: number) => {\n const start = faceStart[face]!;\n const count = faceVertexCounts[face]!;\n for (let k = 2; k < count; k++) {\n tris.push(\n faceVertexIndices[start]!,\n faceVertexIndices[start + k - 1]!,\n faceVertexIndices[start + k]!,\n );\n }\n };\n\n const claimed = new Uint8Array(faceVertexCounts.length);\n subsets.forEach((subset, index) => {\n const begin = tris.length;\n for (const face of subset.faces) {\n if (face < 0 || face >= faceVertexCounts.length || claimed[face]) continue;\n claimed[face] = 1;\n emit(face);\n }\n if (tris.length > begin) geometry.addGroup(begin, tris.length - begin, index);\n });\n\n const begin = tris.length;\n for (let face = 0; face < faceVertexCounts.length; face++) {\n if (!claimed[face]) emit(face);\n }\n if (tris.length > begin) geometry.addGroup(begin, tris.length - begin, subsets.length);\n\n return tris;\n}\n\nfunction flat3(v: Vec3[]): number[] {\n const out = new Array<number>(v.length * 3);\n for (let i = 0; i < v.length; i++) {\n out[i * 3] = v[i]![0];\n out[i * 3 + 1] = v[i]![1];\n out[i * 3 + 2] = v[i]![2];\n }\n return out;\n}\n\nfunction flat2(v: Vec2[]): number[] {\n const out = new Array<number>(v.length * 2);\n for (let i = 0; i < v.length; i++) {\n out[i * 2] = v[i]![0];\n out[i * 2 + 1] = v[i]![1];\n }\n return out;\n}\n\nfunction isNumberArray(v: unknown): v is number[] {\n return Array.isArray(v) && v.every((n) => typeof n === \"number\");\n}\n\nfunction isVec3Array(v: unknown): v is Vec3[] {\n return Array.isArray(v) && v.every((e) => Array.isArray(e) && e.length === 3);\n}\n\nfunction isVec2Array(v: unknown): v is Vec2[] {\n return Array.isArray(v) && v.every((e) => Array.isArray(e) && e.length === 2);\n}\n","/**\n * Loads texture image assets referenced by `UsdShade` materials.\n *\n * A {@link TextureProvider} maps an authored asset path (plus sampler/transform\n * options) to a `THREE.Texture`. The default provider fetches the image **bytes**\n * through the {@link AssetResolver} and decodes them via a blob URL — so it works\n * uniformly for textures served over HTTP and for images embedded inside a\n * `.usdz` package (whose resolver serves zip entries, not real URLs). Decoded\n * images are cached per resolved URL and shared across every texture that uses\n * them; each `THREE.Texture` carries its own color space / wrap / transform.\n */\n\nimport * as THREE from \"three\";\nimport type { AssetResolver } from \"../usd/AssetResolver.js\";\nimport type { TextureTransform, TextureWrap } from \"./MaterialBinding.js\";\n\n/**\n * Color space to interpret a texture in. Color/albedo and emissive maps are\n * `\"srgb\"`; data maps (normal, roughness, metalness, occlusion) are `\"linear\"`.\n */\nexport type TextureColorSpace = \"srgb\" | \"linear\";\n\n/** Per-use sampler state applied to the returned `THREE.Texture`. */\nexport type TextureOptions = {\n /** Defaults to `\"srgb\"`. */\n colorSpace?: TextureColorSpace;\n wrapS?: TextureWrap;\n wrapT?: TextureWrap;\n transform?: TextureTransform;\n};\n\n/** Resolve an authored texture asset path to a `THREE.Texture` (or `null`). */\nexport type TextureProvider = (assetPath: string, options?: TextureOptions) => THREE.Texture | null;\n\nconst DEG2RAD = Math.PI / 180;\n\n/**\n * A {@link TextureProvider} backed by the {@link AssetResolver}, resolving paths\n * against `baseUrl`. Image bytes are fetched once per URL (works for HTTP and\n * `.usdz` entries alike) and the decoded image is shared; each call returns a\n * distinct `THREE.Texture` carrying the requested color space / wrap / transform.\n */\nexport function createTextureProvider(resolver: AssetResolver, baseUrl: string): TextureProvider {\n const images = new Map<string, Promise<TexImageSource>>();\n\n const imageFor = (url: string): Promise<TexImageSource> => {\n let p = images.get(url);\n if (!p) {\n p = loadImage(resolver, url);\n images.set(url, p);\n }\n return p;\n };\n\n return (assetPath: string, options: TextureOptions = {}) => {\n let url: string;\n try {\n url = resolver.resolve(assetPath, baseUrl);\n } catch {\n return null;\n }\n\n const texture = new THREE.Texture();\n texture.colorSpace =\n options.colorSpace === \"linear\" ? THREE.NoColorSpace : THREE.SRGBColorSpace;\n texture.wrapS = toThreeWrap(options.wrapS);\n texture.wrapT = toThreeWrap(options.wrapT);\n applyTransform(texture, options.transform);\n\n imageFor(url)\n .then((image) => {\n texture.image = image;\n texture.needsUpdate = true;\n })\n .catch(() => {\n /* leave the texture blank if the image can't be decoded */\n });\n return texture;\n };\n}\n\n/**\n * Fetch image bytes through the resolver and decode them via a blob URL into an\n * `HTMLImageElement` (so three's default `flipY = true` orients USD's bottom-left\n * `st` origin correctly, matching the prior `TextureLoader` HTTP path).\n */\nasync function loadImage(resolver: AssetResolver, url: string): Promise<TexImageSource> {\n const bytes = resolver.fetchBytes\n ? await resolver.fetchBytes(url)\n : new TextEncoder().encode(await resolver.fetchText(url));\n const blob = new Blob([bytes as BlobPart], { type: mimeOf(url) });\n const objectUrl = URL.createObjectURL(blob);\n try {\n return await new Promise<HTMLImageElement>((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error(`failed to decode texture: ${url}`));\n img.src = objectUrl;\n });\n } finally {\n // The decoded image keeps its pixels; the blob URL can be released.\n URL.revokeObjectURL(objectUrl);\n }\n}\n\nfunction toThreeWrap(wrap: TextureWrap | undefined): THREE.Wrapping {\n switch (wrap) {\n case \"clamp\":\n case \"black\": // three has no border color; clamp is the closest mode\n return THREE.ClampToEdgeWrapping;\n case \"mirror\":\n return THREE.MirroredRepeatWrapping;\n default:\n return THREE.RepeatWrapping;\n }\n}\n\n/** Map a `UsdTransform2d` onto a texture's offset / repeat / rotation. */\nfunction applyTransform(texture: THREE.Texture, t: TextureTransform | undefined): void {\n if (!t) return;\n if (t.scale) texture.repeat.set(t.scale[0], t.scale[1]);\n if (t.translation) texture.offset.set(t.translation[0], t.translation[1]);\n if (t.rotation !== undefined) {\n texture.rotation = t.rotation * DEG2RAD;\n texture.center.set(0, 0); // UsdTransform2d rotates about the origin\n }\n}\n\nfunction mimeOf(url: string): string {\n if (/\\.jpe?g$/i.test(url)) return \"image/jpeg\";\n if (/\\.webp$/i.test(url)) return \"image/webp\";\n return \"image/png\";\n}\n","import type { RobotDescription } from \"../robot/RobotDescription.js\";\nimport { extractRobotDescription } from \"../robot/RobotExtractor.js\";\nimport { buildKinematicTree } from \"../robot/buildKinematicTree.js\";\nimport { type AssetResolver, DefaultAssetResolver } from \"../usd/AssetResolver.js\";\nimport { Stage } from \"../usd/Stage.js\";\nimport { type BinarySource, type UsdSource, toBytes } from \"../usd/bytes.js\";\nimport { composeFile, composeLayer } from \"../usd/composition.js\";\nimport { CrateReader } from \"../usd/crate/CrateReader.js\";\nimport { crateToUsdaFile } from \"../usd/crate/toUsdaFile.js\";\nimport { isZip, openUsdz } from \"../usd/usdz.js\";\nimport { bindRobotMeshes, bindSceneMeshes } from \"./MeshBinding.js\";\nimport { createTextureProvider } from \"./TextureBinding.js\";\nimport { ThreeUsdRobot, type ThreeUsdRobotOptions } from \"./ThreeUsdRobot.js\";\n\nexport type ThreeUsdRobotLoaderOptions = {\n /** Resolver for references / payloads / sublayers (default {@link DefaultAssetResolver}). */\n assetResolver?: AssetResolver;\n /** Render visual meshes (M6). */\n loadVisuals?: boolean;\n /** Render collision meshes (M6). */\n loadCollisions?: boolean;\n /**\n * Also render gprims that belong to no link — the static scenery of a cell\n * that contains robots (floor, guarding, racking, …). Placed by their\n * authored stage transform. Default `false`; a stage with no articulation at\n * all (a pure static scene) defaults to `true` so it renders out of the box.\n */\n loadSceneGeometry?: boolean;\n /** Load diffuse textures referenced by materials (default `true`). */\n loadTextures?: boolean;\n /** Up-axis correction strategy (M9). */\n upAxisConversion?: \"auto\" | \"Y\" | \"Z\" | \"none\";\n /** Extra uniform scale multiplied with `metersPerUnit` (M9). */\n unitScale?: number;\n /** Clamp `setJointValue` to authored limits (default `true`). */\n clampJointLimits?: boolean;\n /** Seed joints from drive targets / joint state (M9). */\n applyDriveTargetsAsInitialPose?: boolean;\n /** Override the robot name. */\n robotName?: string;\n /** Receives non-fatal load diagnostics. */\n onWarn?: (message: string) => void;\n};\n\n/** A composed stage plus the context needed to bind its meshes and textures. */\ntype OpenedStage = { stage: Stage; baseUrl: string; resolver: AssetResolver };\n\n/**\n * Loads Isaac Sim / OpenUSD robot assets into a controllable {@link ThreeUsdRobot}.\n *\n * Assets load by URL ({@link loadAsync}) or from in-memory content\n * ({@link parse} — USDA text, `ArrayBuffer`, typed array, or `Blob`/`File`).\n * Composition (references / payloads / sublayers, M8) is resolved through an\n * {@link AssetResolver}. Mesh rendering is M6; unit / up-axis / initial-pose\n * handling is M9; USDC and variants are M10.\n */\nexport class ThreeUsdRobotLoader {\n readonly options: ThreeUsdRobotLoaderOptions;\n\n constructor(options: ThreeUsdRobotLoaderOptions = {}) {\n this.options = options;\n }\n\n private get resolver(): AssetResolver {\n return this.options.assetResolver ?? new DefaultAssetResolver();\n }\n\n /**\n * Fetch an asset by URL and build the robot. `.usdz` packages are unzipped and\n * composed from their entries; everything else is sniffed for the zip / crate\n * magic and parsed as USDZ, binary USDC, or USDA text.\n */\n async loadAsync(url: string): Promise<ThreeUsdRobot> {\n const bytes = await this.fetchRootBytes(url);\n // Extension first: sniffing only sees offset 0, the extension also covers\n // zip archives with a prefix (fflate reads the central directory anyway).\n if (/\\.usdz$/i.test(url)) return this.parseUsdz(bytes);\n return this.parse(bytes, url);\n }\n\n private async fetchRootBytes(url: string): Promise<Uint8Array> {\n const resolver = this.resolver;\n if (resolver.fetchBytes) return resolver.fetchBytes(url);\n return new TextEncoder().encode(await resolver.fetchText(url));\n }\n\n /**\n * Build a robot from in-memory content — no fetch involved. Accepts USDA\n * source text, or an `ArrayBuffer` / typed array / `Blob` (e.g. a dropped\n * `File`) holding USDA text, a binary crate, or a `.usdz` package; binary\n * input is sniffed for the zip / crate magic. `baseUrl` anchors relative\n * references, payloads, and texture paths of non-package input.\n */\n async parse(data: UsdSource, baseUrl = \"\"): Promise<ThreeUsdRobot> {\n return this.buildFromStage(await this.openSource(data, baseUrl));\n }\n\n /** Build a robot from a `.usdz` package (bytes, `ArrayBuffer`, or `Blob`). */\n async parseUsdz(data: BinarySource): Promise<ThreeUsdRobot> {\n return this.buildFromStage(await this.openUsdzStage(await toBytes(data)));\n }\n\n /** Build a robot from a binary crate (`.usdc` / binary `.usd`). */\n async parseCrate(data: BinarySource, baseUrl = \"\"): Promise<ThreeUsdRobot> {\n const stage = await this.composeStageFromBytes(await toBytes(data), baseUrl, this.resolver);\n return this.buildFromStage({ stage, baseUrl, resolver: this.resolver });\n }\n\n /**\n * Parse + compose in-memory content (same formats as {@link parse}) into the\n * Three.js-independent robot IR.\n */\n async parseRobotDescription(data: UsdSource, baseUrl = \"\"): Promise<RobotDescription> {\n const { stage } = await this.openSource(data, baseUrl);\n return extractRobotDescription(stage, this.extractOptions());\n }\n\n /** Sniff in-memory content (text / zip / crate) and compose it into a stage. */\n private async openSource(data: UsdSource, baseUrl: string): Promise<OpenedStage> {\n const resolver = this.resolver;\n if (typeof data === \"string\") {\n return { stage: await this.composeStage(data, baseUrl, resolver), baseUrl, resolver };\n }\n const bytes = await toBytes(data);\n if (isZip(bytes)) return this.openUsdzStage(bytes);\n const stage = CrateReader.isCrate(bytes)\n ? await this.composeStageFromBytes(bytes, baseUrl, resolver)\n : await this.composeStage(new TextDecoder().decode(bytes), baseUrl, resolver);\n return { stage, baseUrl, resolver };\n }\n\n private async openUsdzStage(bytes: Uint8Array): Promise<OpenedStage> {\n const pkg = openUsdz(bytes);\n // The root layer of a usdz is typically binary USDC — sniff, don't assume text.\n const rootBytes = await pkg.resolver.fetchBytes(pkg.rootEntry);\n const stage = await this.composeStageFromBytes(rootBytes, pkg.rootEntry, pkg.resolver);\n return { stage, baseUrl: pkg.rootEntry, resolver: pkg.resolver };\n }\n\n private buildFromStage({ stage, baseUrl, resolver }: OpenedStage): ThreeUsdRobot {\n const robot = extractRobotDescription(stage, this.extractOptions());\n const tree = buildKinematicTree(robot);\n const robot3d = new ThreeUsdRobot(robot, tree, this.robotOptions());\n\n const loadVisuals = this.options.loadVisuals ?? true;\n const loadCollisions = this.options.loadCollisions ?? false;\n // A stage with no articulation at all is a pure static scene; default to\n // drawing its geometry — otherwise the load would be silently empty.\n const isStaticScene =\n Object.keys(robot.links).length === 0 && Object.keys(robot.joints).length === 0;\n if (isStaticScene && this.options.loadSceneGeometry === undefined) {\n this.options.onWarn?.(\n \"no articulation found (0 links / 0 joints); rendering the stage as static scene geometry\",\n );\n }\n const loadScene = this.options.loadSceneGeometry ?? isStaticScene;\n if (loadVisuals || loadCollisions || loadScene) {\n const textureProvider =\n (this.options.loadTextures ?? true) ? createTextureProvider(resolver, baseUrl) : undefined;\n if (loadVisuals || loadCollisions) {\n bindRobotMeshes(stage, robot3d, robot, {\n loadVisuals,\n loadCollisions,\n ...(textureProvider ? { textureProvider } : {}),\n });\n }\n if (loadScene) {\n bindSceneMeshes(stage, robot3d, robot, {\n ...(textureProvider ? { textureProvider } : {}),\n });\n }\n }\n return robot3d;\n }\n\n private async composeStage(\n text: string,\n baseUrl: string,\n resolver: AssetResolver,\n ): Promise<Stage> {\n const composeOptions = this.options.onWarn ? { onWarn: this.options.onWarn } : {};\n return Stage.OpenFromFile(await composeLayer(text, baseUrl, resolver, composeOptions));\n }\n\n /** Compose a layer from raw bytes, sniffing binary crate vs USDA text. */\n private async composeStageFromBytes(\n bytes: Uint8Array,\n baseUrl: string,\n resolver: AssetResolver,\n ): Promise<Stage> {\n const composeOptions = this.options.onWarn ? { onWarn: this.options.onWarn } : {};\n const composed = CrateReader.isCrate(bytes)\n ? await composeFile(\n crateToUsdaFile(new CrateReader(bytes)),\n baseUrl,\n resolver,\n composeOptions,\n )\n : await composeLayer(new TextDecoder().decode(bytes), baseUrl, resolver, composeOptions);\n return Stage.OpenFromFile(composed);\n }\n\n private robotOptions(): ThreeUsdRobotOptions {\n return {\n upAxisConversion: this.options.upAxisConversion ?? \"auto\",\n ...(this.options.clampJointLimits !== undefined\n ? { clampJointLimits: this.options.clampJointLimits }\n : {}),\n ...(this.options.unitScale !== undefined ? { unitScale: this.options.unitScale } : {}),\n ...(this.options.applyDriveTargetsAsInitialPose !== undefined\n ? { applyInitialPose: this.options.applyDriveTargetsAsInitialPose }\n : {}),\n };\n }\n\n private extractOptions(): { robotName?: string; onWarn?: (message: string) => void } {\n return {\n ...(this.options.robotName !== undefined ? { robotName: this.options.robotName } : {}),\n ...(this.options.onWarn !== undefined ? { onWarn: this.options.onWarn } : {}),\n };\n }\n}\n"]}