three-usd-robot 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +48 -7
  2. package/dist/MeshBinding-DQKXuYNr.d.ts +288 -0
  3. package/dist/{ThreeUsdRobot-BxnCluuK.d.ts → ThreeUsdRobot-C3N6-XBJ.d.ts} +1 -1
  4. package/dist/{ThreeUsdRobotLoader-C-E9uwEe.d.ts → ThreeUsdRobotLoader-D2fEo9_p.d.ts} +11 -3
  5. package/dist/{buildKinematicTree-BCySuZZn.d.ts → buildKinematicTree-iFqaw0Jl.d.ts} +1 -1
  6. package/dist/bytes-CxGRGry_.d.ts +14 -0
  7. package/dist/{chunk-AXPMXEQC.js → chunk-6W4LQVEQ.js} +13 -715
  8. package/dist/chunk-6W4LQVEQ.js.map +1 -0
  9. package/dist/{chunk-5SVRTKS4.js → chunk-7GGSIA6M.js} +18 -11
  10. package/dist/chunk-7GGSIA6M.js.map +1 -0
  11. package/dist/{chunk-BCRRXGNB.js → chunk-CK5MTMYR.js} +6 -4
  12. package/dist/chunk-CK5MTMYR.js.map +1 -0
  13. package/dist/chunk-JGIVJXBU.js +54 -0
  14. package/dist/chunk-JGIVJXBU.js.map +1 -0
  15. package/dist/{chunk-ENWFOYHU.js → chunk-KYBHWDX5.js} +3 -3
  16. package/dist/{chunk-ENWFOYHU.js.map → chunk-KYBHWDX5.js.map} +1 -1
  17. package/dist/chunk-PPPRB6KE.js +963 -0
  18. package/dist/chunk-PPPRB6KE.js.map +1 -0
  19. package/dist/{chunk-LDO5FKQS.js → chunk-YGJ23CG3.js} +4 -53
  20. package/dist/chunk-YGJ23CG3.js.map +1 -0
  21. package/dist/core.d.ts +6 -63
  22. package/dist/core.js +5 -3
  23. package/dist/extras.d.ts +2 -2
  24. package/dist/helpers.d.ts +2 -2
  25. package/dist/helpers.js +3 -2
  26. package/dist/helpers.js.map +1 -1
  27. package/dist/index.d.ts +11 -262
  28. package/dist/index.js +10 -8
  29. package/dist/index.js.map +1 -1
  30. package/dist/nodes.d.ts +49 -0
  31. package/dist/nodes.js +439 -0
  32. package/dist/nodes.js.map +1 -0
  33. package/dist/parseMdl-vfzBGoMr.d.ts +87 -0
  34. package/dist/react.d.ts +6 -4
  35. package/dist/react.js +6 -4
  36. package/dist/react.js.map +1 -1
  37. package/package.json +6 -2
  38. package/dist/bytes-MOJ2oN-u.d.ts +0 -42
  39. package/dist/chunk-5SVRTKS4.js.map +0 -1
  40. package/dist/chunk-AXPMXEQC.js.map +0 -1
  41. package/dist/chunk-BCRRXGNB.js.map +0 -1
  42. package/dist/chunk-LDO5FKQS.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/helpers/appearance.ts","../src/helpers/JointAxisHelper.ts","../src/helpers/JointLimitHelper.ts","../src/helpers/LinkFrameHelper.ts","../src/helpers/attach.ts"],"names":["THREE","THREE2","lo","hi","THREE4"],"mappings":"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","file":"helpers.js","sourcesContent":["/**\n * Per-link appearance helpers: highlight (tint), material replacement, and\n * translucent \"ghost\" clones for pose previews.\n *\n * Material overrides are reversible — the original materials are kept aside on\n * first override and put back exactly by {@link restoreLinkMaterials} /\n * {@link restoreAllLinkMaterials}. Links are addressed like everywhere else:\n * by key or by full prim path.\n */\n\nimport * as THREE from \"three\";\nimport { ThreeUsdRobot } from \"../three/ThreeUsdRobot.js\";\n\n/** Which meshes of a link an operation affects. */\nexport type LinkMeshKind = \"visual\" | \"collision\" | \"all\";\n\n/** Originals saved on first override (per mesh; first save wins until restore). */\nconst savedMaterials = new WeakMap<THREE.Mesh, THREE.Material | THREE.Material[]>();\n\n/** Marks materials created by {@link highlightLink}, so restore can dispose them. */\nconst HIGHLIGHT_FLAG = \"__threeUsdRobotHighlight\";\n\n/**\n * The meshes belonging to exactly this link — not those of child links, which\n * live under their own `LinkObject` deeper in the kinematic chain. Helpers and\n * joint-frame groups are excluded.\n */\nexport function getLinkMeshes(\n robot: ThreeUsdRobot,\n link: string,\n kind: LinkMeshKind = \"all\",\n): THREE.Mesh[] {\n const obj = robot.getLinkObject(link);\n if (!obj) return [];\n const out: THREE.Mesh[] = [];\n for (const child of obj.children) {\n const mesh = child as THREE.Mesh;\n if (!mesh.isMesh) continue;\n const k = (mesh.userData as { kind?: string }).kind;\n if (k !== \"visual\" && k !== \"collision\") continue;\n if (kind !== \"all\" && k !== kind) continue;\n out.push(mesh);\n }\n return out;\n}\n\nexport type HighlightLinkOptions = {\n /** Highlight color (default red `0xff4444`). */\n color?: THREE.ColorRepresentation;\n /** Emissive strength of the tint (default `0.8`). */\n emissiveIntensity?: number;\n /** Force translucency while highlighted (e.g. `0.5`); default keeps the material's own. */\n opacity?: number;\n /** Which meshes of the link to affect (default `\"visual\"`). */\n kind?: LinkMeshKind;\n};\n\n/**\n * Tint a link's meshes (emissive red by default) while keeping their maps and\n * base colors — e.g. to flag a colliding link. Repeated calls re-tint from the\n * *original* materials, so highlights don't stack; restore with\n * {@link restoreLinkMaterials}. Returns `false` when the link has no matching\n * meshes.\n */\nexport function highlightLink(\n robot: ThreeUsdRobot,\n link: string,\n options: HighlightLinkOptions = {},\n): boolean {\n const meshes = getLinkMeshes(robot, link, options.kind ?? \"visual\");\n if (meshes.length === 0) return false;\n\n const color = new THREE.Color(options.color ?? 0xff4444);\n for (const mesh of meshes) {\n if (!savedMaterials.has(mesh)) savedMaterials.set(mesh, mesh.material);\n const base = savedMaterials.get(mesh)!;\n disposeHighlightClones(mesh.material);\n mesh.material = Array.isArray(base)\n ? base.map((m) => tintClone(m, color, options))\n : tintClone(base, color, options);\n }\n return true;\n}\n\nfunction tintClone(\n base: THREE.Material,\n color: THREE.Color,\n options: HighlightLinkOptions,\n): THREE.Material {\n const m = base.clone();\n m.userData[HIGHLIGHT_FLAG] = true;\n const std = m as THREE.MeshStandardMaterial;\n if (std.isMeshStandardMaterial) {\n std.emissive.copy(color);\n std.emissiveIntensity = options.emissiveIntensity ?? 0.8;\n } else if (\"color\" in m) {\n (m as THREE.MeshBasicMaterial).color.copy(color);\n }\n if (options.opacity !== undefined) {\n m.transparent = options.opacity < 1;\n m.opacity = options.opacity;\n }\n return m;\n}\n\n/**\n * Replace a link's mesh materials with `material` (one shared instance). The\n * caller keeps ownership — it is never disposed here. Restore the originals\n * with {@link restoreLinkMaterials}. Returns `false` when the link has no\n * matching meshes.\n */\nexport function setLinkMaterial(\n robot: ThreeUsdRobot,\n link: string,\n material: THREE.Material,\n kind: LinkMeshKind = \"visual\",\n): boolean {\n const meshes = getLinkMeshes(robot, link, kind);\n if (meshes.length === 0) return false;\n for (const mesh of meshes) {\n if (!savedMaterials.has(mesh)) savedMaterials.set(mesh, mesh.material);\n disposeHighlightClones(mesh.material);\n mesh.material = material;\n }\n return true;\n}\n\n/** Put back a link's original materials (no-op for untouched meshes). */\nexport function restoreLinkMaterials(robot: ThreeUsdRobot, link: string): void {\n for (const mesh of getLinkMeshes(robot, link, \"all\")) {\n const original = savedMaterials.get(mesh);\n if (original === undefined) continue;\n disposeHighlightClones(mesh.material);\n mesh.material = original;\n savedMaterials.delete(mesh);\n }\n}\n\n/** Put back the original materials of every link of the robot. */\nexport function restoreAllLinkMaterials(robot: ThreeUsdRobot): void {\n for (const name of robot.getLinkNames()) restoreLinkMaterials(robot, name);\n}\n\n/** Dispose materials created by {@link highlightLink} (never user-supplied ones). */\nfunction disposeHighlightClones(current: THREE.Material | THREE.Material[]): void {\n for (const m of Array.isArray(current) ? current : [current]) {\n if (m.userData[HIGHLIGHT_FLAG]) m.dispose();\n }\n}\n\nexport type GhostRobotOptions = {\n /** Ghost tint (default `0x66aaff`). */\n color?: THREE.ColorRepresentation;\n /** Ghost opacity (default `0.35`). */\n opacity?: number;\n /** Complete material override; `color` / `opacity` are ignored when given. */\n material?: THREE.Material;\n /** Which meshes to clone (default `\"visual\"`). */\n kind?: \"visual\" | \"collision\";\n /** Joint overrides applied on top of the source robot's current pose. */\n jointValues?: Record<string, number>;\n};\n\n/**\n * Build a translucent clone of the robot for pose previews (target pose,\n * onion-skinning). Geometry is shared with the source; every mesh uses one\n * ghost material and is tagged `userData.kind = \"ghost\"`, so the source's\n * `showVisual` / `showCollision` toggles never affect it. The clone is a full\n * {@link ThreeUsdRobot} — drive it with `setJointValues` — starting from the\n * source's current joint values (plus `jointValues` overrides) and mirroring\n * its root transform. Add it to the same parent/scene as the source.\n */\nexport function createGhostRobot(\n robot: ThreeUsdRobot,\n options: GhostRobotOptions = {},\n): ThreeUsdRobot {\n const ghost = new ThreeUsdRobot(robot.robot, robot.tree, {\n clampJointLimits: robot.clampJointLimits,\n applyInitialPose: false,\n upAxisConversion: \"none\",\n });\n ghost.name = `${robot.name}_ghost`;\n // Mirror the source root exactly (stage normalization + any user transform).\n ghost.position.copy(robot.position);\n ghost.quaternion.copy(robot.quaternion);\n ghost.scale.copy(robot.scale);\n\n const material =\n options.material ??\n new THREE.MeshStandardMaterial({\n color: options.color ?? 0x66aaff,\n transparent: true,\n opacity: options.opacity ?? 0.35,\n depthWrite: false,\n metalness: 0,\n roughness: 1,\n });\n\n const kind = options.kind ?? \"visual\";\n for (const key of robot.getLinkNames()) {\n const target = ghost.getLinkObject(key);\n if (!target) continue;\n for (const src of getLinkMeshes(robot, key, kind)) {\n const mesh = new THREE.Mesh(src.geometry, material);\n mesh.name = `${src.name}_ghost`;\n mesh.userData.kind = \"ghost\";\n mesh.userData.primPath = (src.userData as { primPath?: string }).primPath;\n mesh.matrixAutoUpdate = false;\n mesh.matrix.copy(src.matrix);\n mesh.matrixWorldNeedsUpdate = true;\n target.add(mesh);\n }\n }\n\n for (const name of robot.getJointNames()) {\n const value = robot.getJointValue(name);\n if (value !== undefined) ghost.setJointValue(name, value);\n }\n if (options.jointValues) ghost.setJointValues(options.jointValues);\n return ghost;\n}\n","import * as THREE from \"three\";\nimport type { JointObject } from \"../three/JointObject.js\";\n\n/**\n * An arrow drawn along a joint's motion axis (the rotation axis for\n * revolute/continuous joints, the slide direction for prismatic). Add it to the\n * joint's motion node so it tracks the joint.\n */\nexport class JointAxisHelper extends THREE.ArrowHelper {\n readonly isJointAxisHelper = true;\n\n constructor(joint: JointObject, length = 0.2, color: THREE.ColorRepresentation = 0xffd000) {\n super(joint.axis.clone().normalize(), new THREE.Vector3(0, 0, 0), length, color);\n this.name = `${joint.jointName}:axis`;\n }\n}\n","import * as THREE from \"three\";\nimport type { JointObject } from \"../three/JointObject.js\";\n\n/**\n * Visualizes a joint's range of motion: an arc swept between the lower and\n * upper limits (revolute/continuous) or a line segment between them\n * (prismatic). A limitless revolute joint draws a full circle. Add it to the\n * joint's motion node's parent frame (or the joint node) to anchor it.\n */\nexport class JointLimitHelper extends THREE.Line {\n readonly isJointLimitHelper = true;\n\n constructor(joint: JointObject, radius = 0.15, color: THREE.ColorRepresentation = 0x00aaff) {\n super(buildLimitGeometry(joint, radius), new THREE.LineBasicMaterial({ color }));\n this.name = `${joint.jointName}:limit`;\n }\n}\n\nfunction buildLimitGeometry(joint: JointObject, radius: number): THREE.BufferGeometry {\n const axis = joint.axis.clone().normalize();\n\n if (joint.jointType === \"prismatic\") {\n const lo = joint.lower ?? -radius;\n const hi = joint.upper ?? radius;\n return new THREE.BufferGeometry().setFromPoints([\n axis.clone().multiplyScalar(lo),\n axis.clone().multiplyScalar(hi),\n ]);\n }\n\n // Revolute / continuous: sweep an arc in the plane perpendicular to the axis.\n const lo = joint.lower ?? 0;\n const hi = joint.upper ?? Math.PI * 2;\n const { u, v } = perpendicularBasis(axis);\n const segments = 48;\n const points: THREE.Vector3[] = [];\n for (let i = 0; i <= segments; i++) {\n const t = lo + ((hi - lo) * i) / segments;\n points.push(\n u\n .clone()\n .multiplyScalar(Math.cos(t) * radius)\n .addScaledVector(v, Math.sin(t) * radius),\n );\n }\n return new THREE.BufferGeometry().setFromPoints(points);\n}\n\nfunction perpendicularBasis(axis: THREE.Vector3): { u: THREE.Vector3; v: THREE.Vector3 } {\n const ref = Math.abs(axis.x) < 0.9 ? new THREE.Vector3(1, 0, 0) : new THREE.Vector3(0, 1, 0);\n const u = new THREE.Vector3().crossVectors(axis, ref).normalize();\n const v = new THREE.Vector3().crossVectors(axis, u).normalize();\n return { u, v };\n}\n","import * as THREE from \"three\";\n\n/** A small RGB axes gizmo for a link's local frame. Add it to a `LinkObject`. */\nexport class LinkFrameHelper extends THREE.AxesHelper {\n readonly isLinkFrameHelper = true;\n\n constructor(size = 0.2) {\n super(size);\n this.name = \"linkFrame\";\n }\n}\n","import type * as THREE from \"three\";\nimport type { ThreeUsdRobot } from \"../three/ThreeUsdRobot.js\";\nimport { JointAxisHelper } from \"./JointAxisHelper.js\";\nimport { JointLimitHelper } from \"./JointLimitHelper.js\";\nimport { LinkFrameHelper } from \"./LinkFrameHelper.js\";\n\n/** Attach a {@link JointAxisHelper} to every articulated joint. Returns the helpers. */\nexport function addJointAxisHelpers(\n robot: ThreeUsdRobot,\n length?: number,\n color?: THREE.ColorRepresentation,\n): JointAxisHelper[] {\n const out: JointAxisHelper[] = [];\n for (const name of robot.getJointNames()) {\n const joint = robot.getJointObject(name);\n if (!joint?.articulated) continue;\n const helper = new JointAxisHelper(joint, length, color);\n joint.add(helper);\n out.push(helper);\n }\n return out;\n}\n\n/** Attach a {@link JointLimitHelper} to every articulated joint. Returns the helpers. */\nexport function addJointLimitHelpers(\n robot: ThreeUsdRobot,\n radius?: number,\n color?: THREE.ColorRepresentation,\n): JointLimitHelper[] {\n const out: JointLimitHelper[] = [];\n for (const name of robot.getJointNames()) {\n const joint = robot.getJointObject(name);\n if (!joint?.articulated) continue;\n const helper = new JointLimitHelper(joint, radius, color);\n joint.add(helper);\n out.push(helper);\n }\n return out;\n}\n\n/** Attach a {@link LinkFrameHelper} to every link. Returns the helpers. */\nexport function addLinkFrameHelpers(robot: ThreeUsdRobot, size?: number): LinkFrameHelper[] {\n const out: LinkFrameHelper[] = [];\n for (const name of robot.getLinkNames()) {\n const link = robot.getLinkObject(name);\n if (!link) continue;\n const helper = new LinkFrameHelper(size);\n link.add(helper);\n out.push(helper);\n }\n return out;\n}\n"]}
1
+ {"version":3,"sources":["../src/helpers/appearance.ts","../src/helpers/JointAxisHelper.ts","../src/helpers/JointLimitHelper.ts","../src/helpers/LinkFrameHelper.ts","../src/helpers/attach.ts"],"names":["THREE","THREE2","lo","hi","THREE4"],"mappings":"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","file":"helpers.js","sourcesContent":["/**\n * Per-link appearance helpers: highlight (tint), material replacement, and\n * translucent \"ghost\" clones for pose previews.\n *\n * Material overrides are reversible — the original materials are kept aside on\n * first override and put back exactly by {@link restoreLinkMaterials} /\n * {@link restoreAllLinkMaterials}. Links are addressed like everywhere else:\n * by key or by full prim path.\n */\n\nimport * as THREE from \"three\";\nimport { ThreeUsdRobot } from \"../three/ThreeUsdRobot.js\";\n\n/** Which meshes of a link an operation affects. */\nexport type LinkMeshKind = \"visual\" | \"collision\" | \"all\";\n\n/** Originals saved on first override (per mesh; first save wins until restore). */\nconst savedMaterials = new WeakMap<THREE.Mesh, THREE.Material | THREE.Material[]>();\n\n/** Marks materials created by {@link highlightLink}, so restore can dispose them. */\nconst HIGHLIGHT_FLAG = \"__threeUsdRobotHighlight\";\n\n/**\n * The meshes belonging to exactly this link — not those of child links, which\n * live under their own `LinkObject` deeper in the kinematic chain. Helpers and\n * joint-frame groups are excluded.\n */\nexport function getLinkMeshes(\n robot: ThreeUsdRobot,\n link: string,\n kind: LinkMeshKind = \"all\",\n): THREE.Mesh[] {\n const obj = robot.getLinkObject(link);\n if (!obj) return [];\n const out: THREE.Mesh[] = [];\n for (const child of obj.children) {\n const mesh = child as THREE.Mesh;\n if (!mesh.isMesh) continue;\n const k = (mesh.userData as { kind?: string }).kind;\n if (k !== \"visual\" && k !== \"collision\") continue;\n if (kind !== \"all\" && k !== kind) continue;\n out.push(mesh);\n }\n return out;\n}\n\nexport type HighlightLinkOptions = {\n /** Highlight color (default red `0xff4444`). */\n color?: THREE.ColorRepresentation;\n /** Emissive strength of the tint (default `0.8`). */\n emissiveIntensity?: number;\n /** Force translucency while highlighted (e.g. `0.5`); default keeps the material's own. */\n opacity?: number;\n /** Which meshes of the link to affect (default `\"visual\"`). */\n kind?: LinkMeshKind;\n};\n\n/**\n * Tint a link's meshes (emissive red by default) while keeping their maps and\n * base colors — e.g. to flag a colliding link. Repeated calls re-tint from the\n * *original* materials, so highlights don't stack; restore with\n * {@link restoreLinkMaterials}. Returns `false` when the link has no matching\n * meshes.\n */\nexport function highlightLink(\n robot: ThreeUsdRobot,\n link: string,\n options: HighlightLinkOptions = {},\n): boolean {\n const meshes = getLinkMeshes(robot, link, options.kind ?? \"visual\");\n if (meshes.length === 0) return false;\n\n const color = new THREE.Color(options.color ?? 0xff4444);\n for (const mesh of meshes) {\n if (!savedMaterials.has(mesh)) savedMaterials.set(mesh, mesh.material);\n const base = savedMaterials.get(mesh)!;\n disposeHighlightClones(mesh.material);\n mesh.material = Array.isArray(base)\n ? base.map((m) => tintClone(m, color, options))\n : tintClone(base, color, options);\n }\n return true;\n}\n\nfunction tintClone(\n base: THREE.Material,\n color: THREE.Color,\n options: HighlightLinkOptions,\n): THREE.Material {\n const m = base.clone();\n m.userData[HIGHLIGHT_FLAG] = true;\n const std = m as THREE.MeshStandardMaterial;\n if (std.isMeshStandardMaterial) {\n std.emissive.copy(color);\n std.emissiveIntensity = options.emissiveIntensity ?? 0.8;\n } else if (\"color\" in m) {\n (m as THREE.MeshBasicMaterial).color.copy(color);\n }\n if (options.opacity !== undefined) {\n m.transparent = options.opacity < 1;\n m.opacity = options.opacity;\n }\n return m;\n}\n\n/**\n * Replace a link's mesh materials with `material` (one shared instance). The\n * caller keeps ownership — it is never disposed here. Restore the originals\n * with {@link restoreLinkMaterials}. Returns `false` when the link has no\n * matching meshes.\n */\nexport function setLinkMaterial(\n robot: ThreeUsdRobot,\n link: string,\n material: THREE.Material,\n kind: LinkMeshKind = \"visual\",\n): boolean {\n const meshes = getLinkMeshes(robot, link, kind);\n if (meshes.length === 0) return false;\n for (const mesh of meshes) {\n if (!savedMaterials.has(mesh)) savedMaterials.set(mesh, mesh.material);\n disposeHighlightClones(mesh.material);\n mesh.material = material;\n }\n return true;\n}\n\n/** Put back a link's original materials (no-op for untouched meshes). */\nexport function restoreLinkMaterials(robot: ThreeUsdRobot, link: string): void {\n for (const mesh of getLinkMeshes(robot, link, \"all\")) {\n const original = savedMaterials.get(mesh);\n if (original === undefined) continue;\n disposeHighlightClones(mesh.material);\n mesh.material = original;\n savedMaterials.delete(mesh);\n }\n}\n\n/** Put back the original materials of every link of the robot. */\nexport function restoreAllLinkMaterials(robot: ThreeUsdRobot): void {\n for (const name of robot.getLinkNames()) restoreLinkMaterials(robot, name);\n}\n\n/** Dispose materials created by {@link highlightLink} (never user-supplied ones). */\nfunction disposeHighlightClones(current: THREE.Material | THREE.Material[]): void {\n for (const m of Array.isArray(current) ? current : [current]) {\n if (m.userData[HIGHLIGHT_FLAG]) m.dispose();\n }\n}\n\nexport type GhostRobotOptions = {\n /** Ghost tint (default `0x66aaff`). */\n color?: THREE.ColorRepresentation;\n /** Ghost opacity (default `0.35`). */\n opacity?: number;\n /** Complete material override; `color` / `opacity` are ignored when given. */\n material?: THREE.Material;\n /** Which meshes to clone (default `\"visual\"`). */\n kind?: \"visual\" | \"collision\";\n /** Joint overrides applied on top of the source robot's current pose. */\n jointValues?: Record<string, number>;\n};\n\n/**\n * Build a translucent clone of the robot for pose previews (target pose,\n * onion-skinning). Geometry is shared with the source; every mesh uses one\n * ghost material and is tagged `userData.kind = \"ghost\"`, so the source's\n * `showVisual` / `showCollision` toggles never affect it. The clone is a full\n * {@link ThreeUsdRobot} — drive it with `setJointValues` — starting from the\n * source's current joint values (plus `jointValues` overrides) and mirroring\n * its root transform. Add it to the same parent/scene as the source.\n */\nexport function createGhostRobot(\n robot: ThreeUsdRobot,\n options: GhostRobotOptions = {},\n): ThreeUsdRobot {\n const ghost = new ThreeUsdRobot(robot.robot, robot.tree, {\n clampJointLimits: robot.clampJointLimits,\n applyInitialPose: false,\n upAxisConversion: \"none\",\n });\n ghost.name = `${robot.name}_ghost`;\n // Mirror the source root exactly (stage normalization + any user transform).\n ghost.position.copy(robot.position);\n ghost.quaternion.copy(robot.quaternion);\n ghost.scale.copy(robot.scale);\n\n const material =\n options.material ??\n new THREE.MeshStandardMaterial({\n color: options.color ?? 0x66aaff,\n transparent: true,\n opacity: options.opacity ?? 0.35,\n depthWrite: false,\n metalness: 0,\n roughness: 1,\n });\n\n const kind = options.kind ?? \"visual\";\n for (const key of robot.getLinkNames()) {\n const target = ghost.getLinkObject(key);\n if (!target) continue;\n for (const src of getLinkMeshes(robot, key, kind)) {\n const mesh = new THREE.Mesh(src.geometry, material);\n mesh.name = `${src.name}_ghost`;\n mesh.userData.kind = \"ghost\";\n mesh.userData.primPath = (src.userData as { primPath?: string }).primPath;\n mesh.matrixAutoUpdate = false;\n mesh.matrix.copy(src.matrix);\n mesh.matrixWorldNeedsUpdate = true;\n target.add(mesh);\n }\n }\n\n for (const name of robot.getJointNames()) {\n const value = robot.getJointValue(name);\n if (value !== undefined) ghost.setJointValue(name, value);\n }\n if (options.jointValues) ghost.setJointValues(options.jointValues);\n return ghost;\n}\n","import * as THREE from \"three\";\nimport type { JointObject } from \"../three/JointObject.js\";\n\n/**\n * An arrow drawn along a joint's motion axis (the rotation axis for\n * revolute/continuous joints, the slide direction for prismatic). Add it to the\n * joint's motion node so it tracks the joint.\n */\nexport class JointAxisHelper extends THREE.ArrowHelper {\n readonly isJointAxisHelper = true;\n\n constructor(joint: JointObject, length = 0.2, color: THREE.ColorRepresentation = 0xffd000) {\n super(joint.axis.clone().normalize(), new THREE.Vector3(0, 0, 0), length, color);\n this.name = `${joint.jointName}:axis`;\n }\n}\n","import * as THREE from \"three\";\nimport type { JointObject } from \"../three/JointObject.js\";\n\n/**\n * Visualizes a joint's range of motion: an arc swept between the lower and\n * upper limits (revolute/continuous) or a line segment between them\n * (prismatic). A limitless revolute joint draws a full circle. Add it to the\n * joint's motion node's parent frame (or the joint node) to anchor it.\n */\nexport class JointLimitHelper extends THREE.Line {\n readonly isJointLimitHelper = true;\n\n constructor(joint: JointObject, radius = 0.15, color: THREE.ColorRepresentation = 0x00aaff) {\n super(buildLimitGeometry(joint, radius), new THREE.LineBasicMaterial({ color }));\n this.name = `${joint.jointName}:limit`;\n }\n}\n\nfunction buildLimitGeometry(joint: JointObject, radius: number): THREE.BufferGeometry {\n const axis = joint.axis.clone().normalize();\n\n if (joint.jointType === \"prismatic\") {\n const lo = joint.lower ?? -radius;\n const hi = joint.upper ?? radius;\n return new THREE.BufferGeometry().setFromPoints([\n axis.clone().multiplyScalar(lo),\n axis.clone().multiplyScalar(hi),\n ]);\n }\n\n // Revolute / continuous: sweep an arc in the plane perpendicular to the axis.\n const lo = joint.lower ?? 0;\n const hi = joint.upper ?? Math.PI * 2;\n const { u, v } = perpendicularBasis(axis);\n const segments = 48;\n const points: THREE.Vector3[] = [];\n for (let i = 0; i <= segments; i++) {\n const t = lo + ((hi - lo) * i) / segments;\n points.push(\n u\n .clone()\n .multiplyScalar(Math.cos(t) * radius)\n .addScaledVector(v, Math.sin(t) * radius),\n );\n }\n return new THREE.BufferGeometry().setFromPoints(points);\n}\n\nfunction perpendicularBasis(axis: THREE.Vector3): { u: THREE.Vector3; v: THREE.Vector3 } {\n const ref = Math.abs(axis.x) < 0.9 ? new THREE.Vector3(1, 0, 0) : new THREE.Vector3(0, 1, 0);\n const u = new THREE.Vector3().crossVectors(axis, ref).normalize();\n const v = new THREE.Vector3().crossVectors(axis, u).normalize();\n return { u, v };\n}\n","import * as THREE from \"three\";\n\n/** A small RGB axes gizmo for a link's local frame. Add it to a `LinkObject`. */\nexport class LinkFrameHelper extends THREE.AxesHelper {\n readonly isLinkFrameHelper = true;\n\n constructor(size = 0.2) {\n super(size);\n this.name = \"linkFrame\";\n }\n}\n","import type * as THREE from \"three\";\nimport type { ThreeUsdRobot } from \"../three/ThreeUsdRobot.js\";\nimport { JointAxisHelper } from \"./JointAxisHelper.js\";\nimport { JointLimitHelper } from \"./JointLimitHelper.js\";\nimport { LinkFrameHelper } from \"./LinkFrameHelper.js\";\n\n/** Attach a {@link JointAxisHelper} to every articulated joint. Returns the helpers. */\nexport function addJointAxisHelpers(\n robot: ThreeUsdRobot,\n length?: number,\n color?: THREE.ColorRepresentation,\n): JointAxisHelper[] {\n const out: JointAxisHelper[] = [];\n for (const name of robot.getJointNames()) {\n const joint = robot.getJointObject(name);\n if (!joint?.articulated) continue;\n const helper = new JointAxisHelper(joint, length, color);\n joint.add(helper);\n out.push(helper);\n }\n return out;\n}\n\n/** Attach a {@link JointLimitHelper} to every articulated joint. Returns the helpers. */\nexport function addJointLimitHelpers(\n robot: ThreeUsdRobot,\n radius?: number,\n color?: THREE.ColorRepresentation,\n): JointLimitHelper[] {\n const out: JointLimitHelper[] = [];\n for (const name of robot.getJointNames()) {\n const joint = robot.getJointObject(name);\n if (!joint?.articulated) continue;\n const helper = new JointLimitHelper(joint, radius, color);\n joint.add(helper);\n out.push(helper);\n }\n return out;\n}\n\n/** Attach a {@link LinkFrameHelper} to every link. Returns the helpers. */\nexport function addLinkFrameHelpers(robot: ThreeUsdRobot, size?: number): LinkFrameHelper[] {\n const out: LinkFrameHelper[] = [];\n for (const name of robot.getLinkNames()) {\n const link = robot.getLinkObject(name);\n if (!link) continue;\n const helper = new LinkFrameHelper(size);\n link.add(helper);\n out.push(helper);\n }\n return out;\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,269 +1,18 @@
1
- import { MdlModuleProvider, CollisionApproximation, ExportPhysicsMaterial, RobotGeometryProvider, ExportRobotOptions, ExportMaterial, ExportMesh } from './core.js';
2
- export { ARTICULATION_ROOT_API, COLLISION_API, ComposeOptions, CrateReader, ExtractOptions, JointDofInput, JointRelativeDecomposition, MASS_API, MESH_COLLISION_API, MdlMaterialDecl, MdlModule, MdlTextureValue, MdlValue, PACKAGE_NAME, PHYSICS_MATERIAL_API, ParseError, RIGID_BODY_API, ResolvedXform, TextureChannel, TokenizeError, UsdzPackage, VERSION, ValidateRobotOptions, ValidationIssue, ValidationSeverity, collectMdlAssetPaths, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, decomposeJointRelative, driveKindFor, exportRobotUsda, extractRobotDescription, gatherGprimDescendants, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, isBasisCurves, isMdlTexture, isMesh, isPoints, isRenderableGprim, isScope, isSolidGprim, isUnsupportedGprim, isXform, isZip, iterDescendants, jointValueFromSI, jointValueToSI, loadMdlModules, nearestAngleBranch, normalizeJointLimits, openUsdz, parseMdl, parseMdlLiteral, parseOpType, parseUsda, refineJointType, serializeUsda, stageGeometryProvider, tokenize, validateRobotDescription, writeUsdz } from './core.js';
1
+ import { CollisionApproximation, ExportPhysicsMaterial, RobotGeometryProvider, ExportRobotOptions, ExportMaterial, ExportMesh } from './core.js';
2
+ export { ARTICULATION_ROOT_API, COLLISION_API, ComposeOptions, CrateReader, ExtractOptions, JointDofInput, JointRelativeDecomposition, MASS_API, MESH_COLLISION_API, PACKAGE_NAME, PHYSICS_MATERIAL_API, ParseError, RIGID_BODY_API, ResolvedXform, TextureChannel, TokenizeError, UsdzPackage, VERSION, ValidateRobotOptions, ValidationIssue, ValidationSeverity, collectMdlAssetPaths, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, decomposeJointRelative, driveKindFor, exportRobotUsda, extractRobotDescription, gatherGprimDescendants, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, isBasisCurves, isMesh, isPoints, isRenderableGprim, isScope, isSolidGprim, isUnsupportedGprim, isXform, isZip, iterDescendants, jointValueFromSI, jointValueToSI, loadMdlModules, nearestAngleBranch, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, serializeUsda, stageGeometryProvider, tokenize, validateRobotDescription, writeUsdz } from './core.js';
3
3
  import * as THREE from 'three';
4
- import { A as Axis, V as Vec2, b as Vec3, S as Stage, P as Prim, R as RobotDescription, c as JointDriveDescription, d as LinkInertialDescription, K as KinematicTree, U as UsdaFile, M as Mat4 } from './buildKinematicTree-BCySuZZn.js';
5
- export { e as AssetPath, f as Attribute, g as AttributeSpec, B as BuildTreeOptions, C as CompositionArc, D as DEFAULT_METERS_PER_UNIT, h as DEG2RAD, a as JointDescription, J as JointType, i as KinematicNode, j as Layer, L as LinkDescription, k as ListOp, l as MetadataMap, m as PrimSpec, n as PropertySpec, Q as Quat, o as RAD2DEG, p as Relationship, q as RelationshipSpec, r as SampleChannel, s as SdfPath, t as Specifier, T as TreeEdge, u as UpAxis, v as UsdDictionary, w as UsdMatrix, x as UsdValue, y as Variability, z as Vec4, E as buildKinematicTree, F as channelFromSamples, G as decomposeRigid, H as fromUsdMatrix, I as getTranslation, N as identity4, O as interpolate, W as invert, X as makeEuler, Y as makeRotationFromQuat, Z as makeRotationX, _ as makeRotationY, $ as makeRotationZ, a0 as makeScale, a1 as makeTranslation, a2 as multiply, a3 as multiplyAll, a4 as toUsdMatrix } from './buildKinematicTree-BCySuZZn.js';
6
- import { T as ThreeUsdRobot } from './ThreeUsdRobot-BxnCluuK.js';
7
- export { J as JointObject, b as JointResidual, c as JointValuesFromLinkTransformsOptions, L as LinkObject, d as LinkPose, e as LinkPoseSpace, f as LinkPosesOptions, a as ThreeUsdRobotOptions, W as WorldUpAxis } from './ThreeUsdRobot-BxnCluuK.js';
8
- import { A as AssetResolver } from './bytes-MOJ2oN-u.js';
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-C-E9uwEe.js';
4
+ import { A as Axis, J as JointDriveDescription, L as LinkInertialDescription, R as RobotDescription, K as KinematicTree, U as UsdaFile, S as Stage, M as Mat4 } from './buildKinematicTree-iFqaw0Jl.js';
5
+ export { a as AssetPath, b as Attribute, c as AttributeSpec, B as BuildTreeOptions, C as CompositionArc, D as DEFAULT_METERS_PER_UNIT, d as DEG2RAD, e as JointDescription, f as JointType, g as KinematicNode, h as Layer, i as LinkDescription, j as ListOp, k as MetadataMap, P as Prim, l as PrimSpec, m as PropertySpec, Q as Quat, n as RAD2DEG, o as Relationship, p as RelationshipSpec, q as SampleChannel, r as SdfPath, s as Specifier, T as TreeEdge, t as UpAxis, u as UsdDictionary, v as UsdMatrix, w as UsdValue, V as Variability, x as Vec2, y as Vec3, z as Vec4, E as buildKinematicTree, F as channelFromSamples, G as decomposeRigid, H as fromUsdMatrix, I as getTranslation, N as identity4, O as interpolate, W as invert, X as makeEuler, Y as makeRotationFromQuat, Z as makeRotationX, _ as makeRotationY, $ as makeRotationZ, a0 as makeScale, a1 as makeTranslation, a2 as multiply, a3 as multiplyAll, a4 as toUsdMatrix } from './buildKinematicTree-iFqaw0Jl.js';
6
+ import { T as ThreeUsdRobot } from './ThreeUsdRobot-C3N6-XBJ.js';
7
+ export { J as JointObject, b as JointResidual, c as JointValuesFromLinkTransformsOptions, L as LinkObject, d as LinkPose, e as LinkPoseSpace, f as LinkPosesOptions, a as ThreeUsdRobotOptions, W as WorldUpAxis } from './ThreeUsdRobot-C3N6-XBJ.js';
8
+ export { B as BindMeshesOptions, a as BuildGprimOptions, M as MaterialFactory, b as MeshKind, R as ResolveMaterialOptions, c as ResolvedMaterial, d as ResolvedTexture, e as TextureColorSpace, f as TextureOptions, T as TextureProvider, g as TextureTransform, h as TextureWrap, i as bindRobotMeshes, j as bindSceneMeshes, k as buildGprimGeometry, l as buildGprimObject, m as buildMeshGeometry, n as buildMeshMaterial, o as createTextureProvider, p as findBoundSurfaceShader, r as resolveBoundMaterial } from './MeshBinding-DQKXuYNr.js';
9
+ export { a as ThreeUsdRobotLoader, T as ThreeUsdRobotLoaderOptions } from './ThreeUsdRobotLoader-D2fEo9_p.js';
10
+ export { A as AssetResolver, D as DefaultAssetResolver, M as MdlMaterialDecl, a as MdlModule, b as MdlModuleProvider, c as MdlTextureValue, d as MdlValue, e as createMemoryResolver, i as isMdlTexture, j as joinPosix, p as parseMdl, f as parseMdlLiteral } from './parseMdl-vfzBGoMr.js';
11
+ export { B as BinarySource, U as UsdSource, t as toBytes } from './bytes-CxGRGry_.js';
11
12
 
12
13
  /** Unit vector for a USD joint axis token. Returns a fresh vector each call. */
13
14
  declare function axisVector(axis: Axis): THREE.Vector3;
14
15
 
15
- /**
16
- * Resolves `UsdShade` material bindings to flat PBR parameters.
17
- *
18
- * Follows a prim's (or an ancestor's) `material:binding` to a `Material`, finds
19
- * its surface `Shader`, and reads constant color/metalness/roughness/opacity/
20
- * emissive inputs plus the **texture** asset paths for the diffuse, normal,
21
- * roughness, metallic, occlusion and emissive channels. Handles both
22
- * `UsdPreviewSurface` (constant inputs or a connected `UsdUVTexture` network)
23
- * and the Omniverse MDL material families (M20): `OmniPBR` (and derivatives
24
- * such as `OmniPBR_Opacity`), `OmniPBR_ClearCoat`, `OmniGlass`, and an
25
- * `OmniSurface(Lite)` constants subset. MDL shaders are identified by
26
- * `info:mdl:sourceAsset` / `:subIdentifier`; when the referenced `.mdl` module
27
- * text is available (see `loadMdlModules`), parameter values fall back from
28
- * authored USD inputs to the module's wrapper arguments and declaration
29
- * defaults. Executing MDL remains out of scope.
30
- */
31
-
32
- /** `UsdUVTexture` wrap mode for one axis (`black` ≈ clamp; three has no border). */
33
- type TextureWrap = "repeat" | "clamp" | "mirror" | "black";
34
- /** `UsdTransform2d` applied to the `st` coords feeding a texture. */
35
- type TextureTransform = {
36
- /** `inputs:translation` (UV offset). */
37
- translation?: Vec2;
38
- /** `inputs:rotation` in degrees (CCW about the origin). */
39
- rotation?: number;
40
- /** `inputs:scale` (UV tiling). */
41
- scale?: Vec2;
42
- };
43
- /** A resolved texture reference plus its `UsdUVTexture` sampler/transform state. */
44
- type ResolvedTexture = {
45
- /** Authored asset path of the image. */
46
- path: string;
47
- wrapS?: TextureWrap;
48
- wrapT?: TextureWrap;
49
- /** `UsdTransform2d` on the `st` input, if any. */
50
- transform?: TextureTransform;
51
- /** `inputs:scale` — multiplies the sampled value (folded into material factors). */
52
- scale?: [number, number, number, number];
53
- /** `inputs:bias` — added to the sampled value. */
54
- bias?: [number, number, number, number];
55
- /**
56
- * UV-set (primvar) name the texture reads, resolved through the `inputs:st`
57
- * connection to a `UsdPrimvarReader_float2.inputs:varname`. Absent ⇒ `"st"`.
58
- */
59
- uvSet?: string;
60
- /** `inputs:sourceColorSpace` — overrides the per-channel colorspace default. */
61
- sourceColorSpace?: "raw" | "sRGB" | "auto";
62
- /**
63
- * Which output the consuming input connects to (`outputs:r` → `"r"`, …).
64
- * three.js samples fixed channels (roughness = G, metalness = B, ao = R);
65
- * a mismatch is surfaced as a load warning.
66
- */
67
- outputChannel?: "r" | "g" | "b" | "a" | "rgb";
68
- };
69
- type ResolvedMaterial = {
70
- /** Name of the bound `Material` prim, for round-tripping and debugging. */
71
- name?: string;
72
- color?: Vec3;
73
- opacity?: number;
74
- metalness?: number;
75
- roughness?: number;
76
- emissiveColor?: Vec3;
77
- /**
78
- * `inputs:opacityThreshold`. When `> 0`, opacity is a binary mask (alpha
79
- * clip / cutout); when `0`/absent, sub-unit opacity blends translucently.
80
- */
81
- opacityThreshold?: number;
82
- /** `inputs:ior` — promotes the three material to `MeshPhysicalMaterial`. */
83
- ior?: number;
84
- /** `inputs:clearcoat` (physical promotion). */
85
- clearcoat?: number;
86
- /** `inputs:clearcoatRoughness` (physical promotion). */
87
- clearcoatRoughness?: number;
88
- /** `inputs:specularColor`, only when `inputs:useSpecularWorkflow = 1`. */
89
- specularColor?: Vec3;
90
- /** OmniPBR `inputs:emissive_intensity` — multiplies the emissive color. */
91
- emissiveIntensity?: number;
92
- /** OmniGlass — `1` marks a transmissive dielectric (physical promotion, M20). */
93
- transmission?: number;
94
- /** OmniGlass `inputs:depth` — refraction volume thickness (scene units, M20). */
95
- thickness?: number;
96
- /** Diffuse/albedo texture, if any. */
97
- colorTexture?: ResolvedTexture;
98
- /** Opacity / alpha texture (may be the same image as `colorTexture`). */
99
- opacityTexture?: ResolvedTexture;
100
- /** Tangent-space normal map, if any. */
101
- normalTexture?: ResolvedTexture;
102
- /** Roughness map, if any. */
103
- roughnessTexture?: ResolvedTexture;
104
- /** Metallic map, if any. */
105
- metalnessTexture?: ResolvedTexture;
106
- /** Ambient-occlusion map, if any. */
107
- occlusionTexture?: ResolvedTexture;
108
- /** Emissive map, if any. */
109
- emissiveTexture?: ResolvedTexture;
110
- /** OmniPBR_ClearCoat `clearcoat_normalmap_texture` (physical promotion, M20). */
111
- clearcoatNormalTexture?: ResolvedTexture;
112
- };
113
- type ResolveMaterialOptions = {
114
- /** Parsed `.mdl` modules for MDL family detection and value fallback (M20). */
115
- mdl?: MdlModuleProvider;
116
- /** Receives diagnostics (unknown MDL material families). */
117
- onWarn?: (message: string) => void;
118
- };
119
- /** Resolve the bound material's flat parameters for `prim`, or `undefined`. */
120
- declare function resolveBoundMaterial(stage: Stage, prim: Prim, options?: ResolveMaterialOptions): ResolvedMaterial | undefined;
121
-
122
- /**
123
- * Loads texture image assets referenced by `UsdShade` materials.
124
- *
125
- * A {@link TextureProvider} maps an authored asset path (plus sampler/transform
126
- * options) to a `THREE.Texture`. The default provider fetches the image **bytes**
127
- * through the {@link AssetResolver} and decodes them via a blob URL — so it works
128
- * uniformly for textures served over HTTP and for images embedded inside a
129
- * `.usdz` package (whose resolver serves zip entries, not real URLs). Decoded
130
- * images are cached per resolved URL and shared across every texture that uses
131
- * them; each `THREE.Texture` carries its own color space / wrap / transform.
132
- */
133
-
134
- /**
135
- * Color space to interpret a texture in. Color/albedo and emissive maps are
136
- * `"srgb"`; data maps (normal, roughness, metalness, occlusion) are `"linear"`.
137
- */
138
- type TextureColorSpace = "srgb" | "linear";
139
- /** Per-use sampler state applied to the returned `THREE.Texture`. */
140
- type TextureOptions = {
141
- /** Defaults to `"srgb"`. */
142
- colorSpace?: TextureColorSpace;
143
- wrapS?: TextureWrap;
144
- wrapT?: TextureWrap;
145
- transform?: TextureTransform;
146
- /** UV channel index (0 = `uv`, 1 = `uv1`, …) for multi-UV-set meshes. */
147
- channel?: number;
148
- };
149
- /** Resolve an authored texture asset path to a `THREE.Texture` (or `null`). */
150
- type TextureProvider = (assetPath: string, options?: TextureOptions) => THREE.Texture | null;
151
- /**
152
- * A {@link TextureProvider} backed by the {@link AssetResolver}, resolving paths
153
- * against `baseUrl`. Image bytes are fetched once per URL (works for HTTP and
154
- * `.usdz` entries alike) and the decoded image is shared; each call returns a
155
- * distinct `THREE.Texture` carrying the requested color space / wrap / transform.
156
- */
157
- declare function createTextureProvider(resolver: AssetResolver, baseUrl: string): TextureProvider;
158
-
159
- /**
160
- * Binds renderable gprims — `UsdGeom.Mesh` plus the parametric solids (`Cube` /
161
- * `Sphere` / `Cylinder` / `Capsule` / `Cone`) — to Three.js geometry and
162
- * attaches them under the robot's link objects.
163
- *
164
- * Meshes are triangulated with a simple fan. Primvars (`st` UV sets, `normals`,
165
- * `displayColor`) resolve with USD interpolation semantics — `:indices`
166
- * de-referencing, vertex vs faceVarying (de-indexed) layouts, multiple UV
167
- * channels. Solids tessellate from their schema attributes. Geometry is left
168
- * in stage units; the global `metersPerUnit` scale is applied at the root in M9.
169
- */
170
-
171
- type MeshKind = "visual" | "collision";
172
- type BindMeshesOptions = {
173
- loadVisuals?: boolean;
174
- loadCollisions?: boolean;
175
- /** Resolves diffuse texture asset paths to `THREE.Texture` (M-tex). */
176
- textureProvider?: TextureProvider;
177
- /** Render `BasisCurves` with authored `widths` as tube meshes (M18). */
178
- curveTubes?: boolean;
179
- /** Receives fidelity diagnostics (channel-packing mismatches, M19). */
180
- onWarn?: (message: string) => void;
181
- /** Parsed `.mdl` modules for MDL material family/value resolution (M20). */
182
- mdl?: MdlModuleProvider;
183
- };
184
- /**
185
- * Build a `BufferGeometry` from a Mesh prim, or `null` if it has no points.
186
- *
187
- * Primvars resolve with full interpolation semantics (M19): `:indices` arrays
188
- * are de-referenced, vertex-interpolated `st` sets / `normals` /
189
- * `displayColor` bind onto the shared vertices, and any faceVarying primvar
190
- * (or per-face color) switches the mesh to a de-indexed layout where every
191
- * face corner owns its vertex. Extra UV sets become `uv1`, `uv2`, … in
192
- * {@link meshUvSetNames} order.
193
- *
194
- * When the mesh carries `materialBind` face subsets, the triangles are ordered
195
- * subset by subset and a geometry group is added for each — so the mesh can be
196
- * drawn with one material per subset (see {@link buildMeshMaterials}). Group
197
- * order matches {@link getMaterialSubsets}, with any unassigned faces last.
198
- */
199
- declare function buildMeshGeometry(meshPrim: Prim): THREE.BufferGeometry | null;
200
- /**
201
- * Build geometry for any renderable gprim: `Mesh` via {@link buildMeshGeometry},
202
- * parametric solids from their schema attributes. Solids follow UsdGeom
203
- * semantics — sizes in stage units, centered at the origin, `axis` (default
204
- * `"Z"`) along the spine, and a capsule's `height` spans only its cylindrical
205
- * section. Returns `null` for unsupported prim types.
206
- */
207
- declare function buildGprimGeometry(prim: Prim): THREE.BufferGeometry | null;
208
- type BuildGprimOptions = {
209
- /** Resolves texture asset paths for mesh materials. */
210
- textureProvider?: TextureProvider;
211
- /**
212
- * Render `BasisCurves` that author `widths` as tube meshes instead of
213
- * 1-px lines (default `false`).
214
- */
215
- curveTubes?: boolean;
216
- /** Receives fidelity diagnostics (channel-packing mismatches, M19). */
217
- onWarn?: (message: string) => void;
218
- /** Parsed `.mdl` modules for MDL material family/value resolution (M20). */
219
- mdl?: MdlModuleProvider;
220
- };
221
- /**
222
- * Build a renderable `THREE.Object3D` for any supported gprim (M18):
223
- * `Mesh` and the parametric solids become a `THREE.Mesh` (via
224
- * {@link buildGprimGeometry} + {@link buildMeshMaterials}), `Points` a
225
- * `THREE.Points`, and `BasisCurves` a `THREE.Group` holding one line — or,
226
- * with {@link BuildGprimOptions.curveTubes}, one tube mesh — per curve.
227
- * Returns `null` for unsupported prim types and degenerate geometry.
228
- */
229
- declare function buildGprimObject(prim: Prim, stage?: Stage, options?: BuildGprimOptions): THREE.Object3D | null;
230
- /**
231
- * Build a material for a gprim. Color priority: bound `UsdShade` material
232
- * (when `stage` is given) → `primvars:displayColor` → default gray. Textures
233
- * (via `textures`) become the matching `MeshStandardMaterial` maps — diffuse →
234
- * `map` (sRGB), plus `normalMap` / `roughnessMap` / `metalnessMap` / `aoMap`
235
- * (linear data) and emissive `emissiveMap`. Metalness / roughness / opacity /
236
- * emissive constants come from the bound material when present.
237
- */
238
- declare function buildMeshMaterial(meshPrim: Prim, stage?: Stage, textures?: TextureProvider,
239
- /** Resolve the material binding from here instead (a `GeomSubset`). */
240
- bindingPrim?: Prim,
241
- /** Receives fidelity diagnostics (channel-packing mismatches, M19). */
242
- onWarn?: (message: string) => void,
243
- /** Parsed `.mdl` modules for MDL material family/value resolution (M20). */
244
- mdl?: MdlModuleProvider): THREE.Material;
245
- /**
246
- * Attach visual (and optionally collision) meshes to every link of a built
247
- * {@link ThreeUsdRobot}. Each mesh is positioned by its transform relative to
248
- * the owning link prim.
249
- */
250
- declare function bindRobotMeshes(stage: Stage, robot3d: ThreeUsdRobot, desc: RobotDescription, options?: BindMeshesOptions): void;
251
- /**
252
- * Attach the gprims that belong to no link — the static scenery of a cell that
253
- * also contains robots. The authored prim hierarchy is mirrored with
254
- * `THREE.Group` nodes (each carrying `userData.primPath` and its prim's local
255
- * transform), so grouped scenery — a pallet and its cartons, a fence and its
256
- * wires — stays one movable subtree. World placements are unchanged, and the
257
- * loader's up-axis and unit normalization still applies at the robot root.
258
- * Collision-only and guide/proxy prims are skipped.
259
- */
260
- declare function bindSceneMeshes(stage: Stage, robot3d: ThreeUsdRobot, desc: RobotDescription, options?: {
261
- textureProvider?: TextureProvider;
262
- curveTubes?: boolean;
263
- onWarn?: (message: string) => void;
264
- mdl?: MdlModuleProvider;
265
- }): number;
266
-
267
16
  /**
268
17
  * Authoring API (M14): assemble a robot from Three.js objects and export it.
269
18
  *
@@ -397,4 +146,4 @@ type ExportThreeUsdRobotOptions = Omit<ExportRobotOptions, "geometry"> & {
397
146
  /** Export a loaded robot back to a USDA AST (pass the result to `serializeUsda`). */
398
147
  declare function exportThreeUsdRobot(robot: ThreeUsdRobot, options?: ExportThreeUsdRobotOptions): UsdaFile;
399
148
 
400
- export { type AddJointOptions, type AddLinkOptions, AssetResolver, Axis, type BindMeshesOptions, type BuildGprimOptions, CollisionApproximation, ExportMaterial, ExportMesh, ExportPhysicsMaterial, ExportRobotOptions, type ExportThreeUsdRobotOptions, type GeometryToExportMeshOptions, JointDriveDescription, KinematicTree, LinkInertialDescription, Mat4, MdlModuleProvider, type MeshKind, Prim, type ResolveMaterialOptions, type ResolvedMaterial, type ResolvedTexture, RobotBuilder, type RobotBuilderOptions, RobotDescription, RobotGeometryProvider, Stage, type TextureColorSpace, type TextureOptions, type TextureProvider, type TextureTransform, type TextureWrap, ThreeUsdRobot, UsdaFile, Vec2, Vec3, type WorldFrame, axisVector, bindRobotMeshes, bindSceneMeshes, buildGprimGeometry, buildGprimObject, buildMeshGeometry, buildMeshMaterial, createTextureProvider, exportThreeUsdRobot, geometryToExportMesh, materialToExportMaterial, resolveBoundMaterial, threeGeometryProvider };
149
+ export { type AddJointOptions, type AddLinkOptions, Axis, CollisionApproximation, ExportMaterial, ExportMesh, ExportPhysicsMaterial, ExportRobotOptions, type ExportThreeUsdRobotOptions, type GeometryToExportMeshOptions, JointDriveDescription, KinematicTree, LinkInertialDescription, Mat4, RobotBuilder, type RobotBuilderOptions, RobotDescription, RobotGeometryProvider, Stage, ThreeUsdRobot, UsdaFile, type WorldFrame, axisVector, exportThreeUsdRobot, geometryToExportMesh, materialToExportMaterial, threeGeometryProvider };
package/dist/index.js CHANGED
@@ -1,11 +1,13 @@
1
- import { stageGeometryProvider, exportRobotUsda } from './chunk-BCRRXGNB.js';
2
- export { PACKAGE_NAME, VERSION, exportRobotUsda, stageGeometryProvider, validateRobotDescription, writeUsdz } from './chunk-BCRRXGNB.js';
3
- export { ThreeUsdRobotLoader, bindRobotMeshes, bindSceneMeshes, buildGprimGeometry, buildGprimObject, buildMeshGeometry, buildMeshMaterial, createTextureProvider } from './chunk-5SVRTKS4.js';
4
- import { refineJointType, buildKinematicTree } from './chunk-AXPMXEQC.js';
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, collectMdlAssetPaths, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, createMemoryResolver, driveKindFor, extractRobotDescription, gatherGprimDescendants, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, isBasisCurves, isMdlTexture, isMesh, isPoints, isRenderableGprim, isScope, isSolidGprim, isUnsupportedGprim, isXform, isZip, iterDescendants, joinPosix, jointValueFromSI, jointValueToSI, loadMdlModules, normalizeJointLimits, openUsdz, parseMdl, parseMdlLiteral, parseOpType, parseUsda, refineJointType, resolveBoundMaterial, serializeUsda, toBytes, tokenize } from './chunk-AXPMXEQC.js';
6
- export { JointObject, LinkObject, ThreeUsdRobot, axisVector } from './chunk-ENWFOYHU.js';
7
- import { identity4, multiply, invert } from './chunk-LDO5FKQS.js';
8
- export { AssetPath, DEG2RAD, Quat, RAD2DEG, UsdMatrix, channelFromSamples, decomposeJointRelative, decomposeRigid, fromUsdMatrix, getTranslation, identity4, interpolate, invert, makeEuler, makeRotationFromQuat, makeRotationX, makeRotationY, makeRotationZ, makeScale, makeTranslation, multiply, multiplyAll, nearestAngleBranch, toUsdMatrix } from './chunk-LDO5FKQS.js';
1
+ import { stageGeometryProvider, exportRobotUsda } from './chunk-CK5MTMYR.js';
2
+ export { PACKAGE_NAME, VERSION, exportRobotUsda, stageGeometryProvider, validateRobotDescription, writeUsdz } from './chunk-CK5MTMYR.js';
3
+ export { ThreeUsdRobotLoader, bindRobotMeshes, bindSceneMeshes, buildGprimGeometry, buildGprimObject, buildMeshGeometry, buildMeshMaterial, createTextureProvider } from './chunk-7GGSIA6M.js';
4
+ import { refineJointType, buildKinematicTree } from './chunk-6W4LQVEQ.js';
5
+ export { ARTICULATION_ROOT_API, Attribute, COLLISION_API, CrateReader, DEFAULT_METERS_PER_UNIT, Layer, MASS_API, MESH_COLLISION_API, PHYSICS_MATERIAL_API, ParseError, Prim, RIGID_BODY_API, Relationship, Stage, TokenizeError, buildKinematicTree, collectMdlAssetPaths, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, driveKindFor, extractRobotDescription, gatherGprimDescendants, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, isBasisCurves, isMesh, isPoints, isRenderableGprim, isScope, isSolidGprim, isUnsupportedGprim, isXform, isZip, iterDescendants, jointValueFromSI, jointValueToSI, loadMdlModules, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, serializeUsda, toBytes, tokenize } from './chunk-6W4LQVEQ.js';
6
+ export { JointObject, LinkObject, ThreeUsdRobot, axisVector } from './chunk-KYBHWDX5.js';
7
+ import { identity4, multiply, invert } from './chunk-YGJ23CG3.js';
8
+ export { DEG2RAD, RAD2DEG, channelFromSamples, decomposeJointRelative, decomposeRigid, fromUsdMatrix, getTranslation, identity4, interpolate, invert, makeEuler, makeRotationFromQuat, makeRotationX, makeRotationY, makeRotationZ, makeScale, makeTranslation, multiply, multiplyAll, nearestAngleBranch, toUsdMatrix } from './chunk-YGJ23CG3.js';
9
+ export { DefaultAssetResolver, createMemoryResolver, findBoundSurfaceShader, isMdlTexture, joinPosix, parseMdl, parseMdlLiteral, resolveBoundMaterial } from './chunk-PPPRB6KE.js';
10
+ export { AssetPath, Quat, UsdMatrix } from './chunk-JGIVJXBU.js';
9
11
  import * as THREE from 'three';
10
12
 
11
13
  function geometryToExportMesh(geometry, options) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/three/exportThreeUsdRobot.ts","../src/three/RobotBuilder.ts"],"names":["material","exportMaterial","mesh","isIdentityMat4","THREE2"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Three.js-side export (M14).\n *\n * Converts `BufferGeometry` / `MeshStandardMaterial` into the plain\n * {@link ExportMesh} data the exporter consumes, harvests the meshes attached\n * under a loaded robot's links, and re-exports a {@link ThreeUsdRobot} as a\n * USDA AST. Texture maps are not carried yet (M15) — constants only.\n */\n\nimport * as THREE from \"three\";\nimport type {\n ExportMaterial,\n ExportMesh,\n RobotGeometryProvider,\n} from \"../export/GeometryProvider.js\";\nimport { stageGeometryProvider } from \"../export/GeometryProvider.js\";\nimport { type ExportRobotOptions, exportRobotUsda } from \"../export/exportRobot.js\";\nimport type { Mat4 } from \"../kinematics/transforms.js\";\nimport type { UsdaFile, Vec2, Vec3 } from \"../parser/ast.js\";\nimport type { Stage } from \"../usd/Stage.js\";\nimport type { ThreeUsdRobot } from \"./ThreeUsdRobot.js\";\n\nexport type GeometryToExportMeshOptions = {\n name: string;\n kind?: \"visual\" | \"collision\";\n /** Transform relative to the link frame (column-major); identity when omitted. */\n transform?: Mat4;\n material?: ExportMaterial;\n doubleSided?: boolean;\n /**\n * Export only this slice of the index buffer — a `BufferGeometry` group, as\n * used by multi-material meshes. Vertices are re-indexed onto the slice.\n */\n group?: { start: number; count: number };\n};\n\n/**\n * Convert a triangle `BufferGeometry` into exportable mesh data. Non-indexed\n * geometry becomes sequential triangles; a trailing partial triangle (or the\n * absence of a position attribute) returns `null`.\n */\nexport function geometryToExportMesh(\n geometry: THREE.BufferGeometry,\n options: GeometryToExportMeshOptions,\n): ExportMesh | null {\n const position = geometry.getAttribute(\"position\");\n if (!position || position.count === 0) return null;\n\n const index = geometry.getIndex();\n const all = index\n ? Array.from(index.array as ArrayLike<number>)\n : Array.from({ length: position.count }, (_, i) => i);\n const slice = options.group\n ? all.slice(options.group.start, options.group.start + options.group.count)\n : all;\n const triangles = Math.floor(slice.length / 3);\n if (triangles === 0) return null;\n\n const normal = geometry.getAttribute(\"normal\");\n const uv = geometry.getAttribute(\"uv\");\n const hasNormals = !!normal && normal.count === position.count;\n const hasUv = !!uv && uv.count === position.count;\n\n const points: Vec3[] = [];\n const normals: Vec3[] = [];\n const st: Vec2[] = [];\n let faceVertexIndices: number[];\n\n if (options.group) {\n // Re-index onto just the vertices this group touches.\n const remap = new Map<number, number>();\n faceVertexIndices = [];\n for (const vertex of slice.slice(0, triangles * 3)) {\n let mapped = remap.get(vertex);\n if (mapped === undefined) {\n mapped = points.length;\n remap.set(vertex, mapped);\n points.push([position.getX(vertex), position.getY(vertex), position.getZ(vertex)]);\n if (hasNormals)\n normals.push([normal.getX(vertex), normal.getY(vertex), normal.getZ(vertex)]);\n if (hasUv) st.push([uv.getX(vertex), uv.getY(vertex)]);\n }\n faceVertexIndices.push(mapped);\n }\n } else {\n for (let i = 0; i < position.count; i++) {\n points.push([position.getX(i), position.getY(i), position.getZ(i)]);\n if (hasNormals) normals.push([normal.getX(i), normal.getY(i), normal.getZ(i)]);\n if (hasUv) st.push([uv.getX(i), uv.getY(i)]);\n }\n faceVertexIndices = slice.slice(0, triangles * 3);\n }\n\n const mesh: ExportMesh = {\n name: options.name,\n kind: options.kind ?? \"visual\",\n points,\n faceVertexCounts: new Array(triangles).fill(3),\n faceVertexIndices,\n };\n if (hasNormals) mesh.normals = normals;\n if (hasUv) mesh.st = st;\n\n if (options.transform && !isIdentityMat4(options.transform)) mesh.transform = options.transform;\n if (options.material) mesh.material = options.material;\n if (options.doubleSided) mesh.doubleSided = true;\n return mesh;\n}\n\n/**\n * Extract constant PBR parameters from a Three.js material. Only\n * `MeshStandardMaterial` maps onto `UsdPreviewSurface`; anything else returns\n * `undefined` (with a warning). Texture maps are reported but not carried.\n */\nexport function materialToExportMaterial(\n material: THREE.Material,\n name: string,\n onWarn?: (message: string) => void,\n): ExportMaterial | undefined {\n const std = material as THREE.MeshStandardMaterial;\n if (!std.isMeshStandardMaterial) {\n onWarn?.(`material \"${name}\": only MeshStandardMaterial exports to UsdPreviewSurface; skipped`);\n return undefined;\n }\n if (\n std.map ||\n std.normalMap ||\n std.roughnessMap ||\n std.metalnessMap ||\n std.aoMap ||\n std.emissiveMap ||\n std.alphaMap\n ) {\n onWarn?.(\n `material \"${name}\": texture maps are not carried from Three.js materials (image extraction is app-side); constants only`,\n );\n }\n\n const out: ExportMaterial = {\n name,\n diffuseColor: [std.color.r, std.color.g, std.color.b],\n metallic: std.metalness,\n roughness: std.roughness,\n };\n if (std.transparent && std.opacity < 1) out.opacity = std.opacity;\n if (std.emissive.r > 0 || std.emissive.g > 0 || std.emissive.b > 0) {\n out.emissiveColor = [std.emissive.r, std.emissive.g, std.emissive.b];\n }\n return out;\n}\n\n/**\n * Provider over the meshes `bindRobotMeshes` attached under each link of a\n * loaded robot (direct children tagged `userData.kind`), with their link-local\n * transforms and materials.\n */\nexport function threeGeometryProvider(\n robot: ThreeUsdRobot,\n onWarn?: (message: string) => void,\n): RobotGeometryProvider {\n const materialNames = new Map<THREE.Material, ExportMaterial | undefined>();\n let autoId = 0;\n const convertMaterial = (material: THREE.Material): ExportMaterial | undefined => {\n if (!materialNames.has(material)) {\n const name = material.name || `Material_${autoId++}`;\n materialNames.set(material, materialToExportMaterial(material, name, onWarn));\n }\n return materialNames.get(material);\n };\n\n return (linkKey) => {\n const linkObj = robot.getLinkObject(linkKey);\n if (!linkObj) return [];\n\n const out: ExportMesh[] = [];\n for (const childObj of linkObj.children) {\n const meshObj = childObj as THREE.Mesh;\n if (!meshObj.isMesh) continue;\n const kind = meshObj.userData.kind === \"collision\" ? \"collision\" : \"visual\";\n const transform = [...meshObj.matrix.elements];\n const baseName = meshObj.name || \"mesh\";\n const materials = Array.isArray(meshObj.material) ? meshObj.material : [meshObj.material];\n const groups = meshObj.geometry.groups;\n\n // A multi-material mesh exports one USD Mesh per geometry group, so each\n // group keeps its own material instead of collapsing to the first.\n if (materials.length > 1 && groups.length > 0) {\n for (const [i, group] of groups.entries()) {\n const material = materials[group.materialIndex ?? 0];\n const exportMaterial = material ? convertMaterial(material) : undefined;\n const mesh = geometryToExportMesh(meshObj.geometry, {\n name: `${baseName}_${material?.name || i}`,\n kind,\n transform,\n group: { start: group.start, count: group.count },\n ...(exportMaterial ? { material: exportMaterial } : {}),\n doubleSided: material?.side === THREE.DoubleSide,\n });\n if (mesh) out.push(mesh);\n }\n continue;\n }\n\n const material = materials[0];\n const exportMaterial = material ? convertMaterial(material) : undefined;\n const mesh = geometryToExportMesh(meshObj.geometry, {\n name: baseName,\n kind,\n transform,\n ...(exportMaterial ? { material: exportMaterial } : {}),\n doubleSided: material?.side === THREE.DoubleSide,\n });\n if (mesh) out.push(mesh);\n }\n return out;\n };\n}\n\nexport type ExportThreeUsdRobotOptions = Omit<ExportRobotOptions, \"geometry\"> & {\n /** Re-read mesh data from the source stage instead of the Three.js scene. */\n stage?: Stage;\n};\n\n/** Export a loaded robot back to a USDA AST (pass the result to `serializeUsda`). */\nexport function exportThreeUsdRobot(\n robot: ThreeUsdRobot,\n options: ExportThreeUsdRobotOptions = {},\n): UsdaFile {\n const { stage, ...rest } = options;\n const geometry = stage\n ? stageGeometryProvider(stage)\n : threeGeometryProvider(robot, options.onWarn);\n return exportRobotUsda(robot.robot, { ...rest, geometry });\n}\n\nfunction isIdentityMat4(m: Mat4): boolean {\n for (let i = 0; i < 16; i++) {\n if (m[i] !== (i % 5 === 0 ? 1 : 0)) return false;\n }\n return true;\n}\n","/**\n * Authoring API (M14): assemble a robot from Three.js objects and export it.\n *\n * Links and joints are declared by name. Every joint takes **one** world-space\n * frame; both body-local joint frames derive from it —\n * `frame0 = linkWorld(parent)⁻¹ · frame`, `frame1 = linkWorld(child)⁻¹ · frame`\n * — so the arrangement at build time is the robot's zero pose. Values are SI\n * (radians / stage linear units); the exporter converts to authored units on\n * write. World matrices are captured at `addLink`/`add*Joint` time.\n */\n\nimport * as THREE from \"three\";\nimport type {\n CollisionApproximation,\n ExportMaterial,\n ExportMesh,\n ExportPhysicsMaterial,\n RobotGeometryProvider,\n} from \"../export/GeometryProvider.js\";\nimport { type ExportRobotOptions, exportRobotUsda } from \"../export/exportRobot.js\";\nimport { type Mat4, identity4, invert, multiply } from \"../kinematics/transforms.js\";\nimport type { UsdaFile } from \"../parser/ast.js\";\nimport type {\n Axis,\n JointDescription,\n JointDriveDescription,\n JointType,\n LinkDescription,\n LinkInertialDescription,\n RobotDescription,\n} from \"../robot/RobotDescription.js\";\nimport { type KinematicTree, buildKinematicTree } from \"../robot/buildKinematicTree.js\";\nimport { refineJointType } from \"../robot/normalize.js\";\nimport { geometryToExportMesh, materialToExportMaterial } from \"./exportThreeUsdRobot.js\";\n\n/** A world-space frame: a matrix, or an object whose `matrixWorld` is used. */\nexport type WorldFrame = THREE.Matrix4 | THREE.Object3D;\n\nexport type RobotBuilderOptions = {\n name: string;\n /** Stage up axis; defaults to `\"Z\"` (Isaac Sim convention). */\n upAxis?: \"Y\" | \"Z\";\n /** Stage linear unit; defaults to `1` (meters). */\n metersPerUnit?: number;\n /** Link to flag with `PhysicsArticulationRootAPI` (default: the container prim). */\n articulationRoot?: string;\n onWarn?: (message: string) => void;\n};\n\nexport type AddLinkOptions = {\n name: string;\n /** Link frame in world space at build pose (default identity). */\n frame?: WorldFrame;\n /** Objects whose `THREE.Mesh` descendants become the link's visual meshes. */\n visuals?: THREE.Object3D[];\n /** Objects whose `THREE.Mesh` descendants become collision meshes. */\n collisions?: THREE.Object3D[];\n /** Mass properties, exported as `PhysicsMassAPI` (M16). */\n inertial?: LinkInertialDescription;\n /** `physics:approximation` applied to this link's collision meshes (M16). */\n collisionApproximation?: CollisionApproximation;\n /** Physics material bound to this link's collision meshes (M16). */\n physicsMaterial?: ExportPhysicsMaterial;\n};\n\nexport type AddJointOptions = {\n name: string;\n /** Parent link name; omit to fix the child to the world. */\n parent?: string;\n child: string;\n /** Joint frame in world space (default: the child link's frame). */\n frame?: WorldFrame;\n /** Rotation / sliding axis token in the joint frame (default `\"X\"`). */\n axis?: Axis;\n /** Limits in SI: radians (revolute) or stage linear units (prismatic). */\n lower?: number;\n upper?: number;\n /** Initial joint value in SI, exported as `PhysicsJointStateAPI`. */\n initialValue?: number;\n drive?: JointDriveDescription;\n};\n\ntype PendingJoint = {\n type: JointType;\n options: AddJointOptions;\n /** Joint frame world matrix captured at add time (undefined → child frame). */\n world?: Mat4;\n};\n\nexport class RobotBuilder {\n private readonly robotName: string;\n private readonly upAxis: \"Y\" | \"Z\";\n private readonly metersPerUnit: number;\n private readonly articulationRoot?: string;\n private readonly warn: (message: string) => void;\n\n private readonly links = new Map<\n string,\n { world: Mat4; meshes: ExportMesh[]; inertial?: LinkInertialDescription }\n >();\n private readonly joints = new Map<string, PendingJoint>();\n private readonly materialCache = new Map<THREE.Material, ExportMaterial | undefined>();\n private materialAutoId = 0;\n\n constructor(options: RobotBuilderOptions) {\n this.robotName = options.name;\n this.upAxis = options.upAxis ?? \"Z\";\n this.metersPerUnit = options.metersPerUnit ?? 1;\n if (options.articulationRoot !== undefined) this.articulationRoot = options.articulationRoot;\n this.warn = options.onWarn ?? (() => {});\n }\n\n addLink(options: AddLinkOptions): this {\n if (this.links.has(options.name)) {\n throw new Error(`RobotBuilder: link \"${options.name}\" is already defined`);\n }\n const world = resolveFrame(options.frame) ?? identity4();\n const collisionExtras = {\n ...(options.collisionApproximation !== undefined\n ? { approximation: options.collisionApproximation }\n : {}),\n ...(options.physicsMaterial ? { material: options.physicsMaterial } : {}),\n };\n const meshes = [\n ...this.gatherMeshes(options.visuals ?? [], world, \"visual\"),\n ...this.gatherMeshes(options.collisions ?? [], world, \"collision\", collisionExtras),\n ];\n this.links.set(options.name, {\n world,\n meshes,\n ...(options.inertial ? { inertial: options.inertial } : {}),\n });\n return this;\n }\n\n addFixedJoint(options: Omit<AddJointOptions, \"axis\" | \"lower\" | \"upper\">): this {\n return this.addJoint(\"fixed\", options);\n }\n\n addRevoluteJoint(options: AddJointOptions): this {\n return this.addJoint(\"revolute\", options);\n }\n\n addPrismaticJoint(options: AddJointOptions): this {\n return this.addJoint(\"prismatic\", options);\n }\n\n private addJoint(type: JointType, options: AddJointOptions): this {\n if (this.joints.has(options.name)) {\n throw new Error(`RobotBuilder: joint \"${options.name}\" is already defined`);\n }\n const world = resolveFrame(options.frame);\n this.joints.set(options.name, { type, options, ...(world ? { world } : {}) });\n return this;\n }\n\n /** Assemble the IR + geometry provider (validates the kinematic graph). */\n build(): { desc: RobotDescription; geometry: RobotGeometryProvider; tree: KinematicTree } {\n const links: Record<string, LinkDescription> = {};\n for (const [name, link] of this.links) {\n links[name] = {\n name,\n primPath: `/${this.robotName}/${name}`,\n visualPrims: [],\n ...(link.inertial ? { inertial: link.inertial } : {}),\n // Authored placement, so links no joint reaches keep their build pose.\n ...(isIdentityMat4(link.world) ? {} : { worldTransform: link.world }),\n };\n }\n\n const joints: Record<string, JointDescription> = {};\n for (const [name, pending] of this.joints) {\n const { options } = pending;\n const parent = options.parent ?? \"\";\n if (parent !== \"\" && !this.links.has(parent)) {\n throw new Error(`RobotBuilder: joint \"${name}\" references unknown parent \"${parent}\"`);\n }\n const childLink = this.links.get(options.child);\n if (!childLink) {\n throw new Error(\n `RobotBuilder: joint \"${name}\" references unknown child \"${options.child}\"`,\n );\n }\n\n const jointWorld = pending.world ?? childLink.world;\n const parentWorld = parent === \"\" ? identity4() : this.links.get(parent)!.world;\n const type = refineJointType(pending.type, options.lower, options.upper);\n\n joints[name] = {\n name,\n primPath: `/${this.robotName}/${name}`,\n type,\n parent,\n child: options.child,\n axis: options.axis ?? \"X\",\n jointFrame0: multiply(invert(parentWorld), jointWorld),\n jointFrame1: multiply(invert(childLink.world), jointWorld),\n ...(options.lower !== undefined ? { lower: options.lower } : {}),\n ...(options.upper !== undefined ? { upper: options.upper } : {}),\n ...(options.initialValue !== undefined ? { initialValue: options.initialValue } : {}),\n ...(options.drive ? { drive: options.drive } : {}),\n };\n }\n\n if (this.articulationRoot !== undefined && !this.links.has(this.articulationRoot)) {\n throw new Error(`RobotBuilder: articulationRoot \"${this.articulationRoot}\" is not a link`);\n }\n\n const desc: RobotDescription = {\n name: this.robotName,\n rootLink: \"\",\n links,\n joints,\n upAxis: this.upAxis,\n metersPerUnit: this.metersPerUnit,\n ...(this.articulationRoot !== undefined\n ? { articulationRoots: [this.articulationRoot] }\n : {}),\n };\n\n const tree = buildKinematicTree(desc, { onWarn: this.warn });\n desc.rootLink = tree.root;\n if (tree.loopJoints.length > 0) desc.loopJoints = tree.loopJoints;\n if (tree.warnings.length > 0) desc.warnings = tree.warnings;\n\n const byLink = this.links;\n const geometry: RobotGeometryProvider = (linkKey) => byLink.get(linkKey)?.meshes ?? [];\n return { desc, geometry, tree };\n }\n\n /** Build and export in one step (pass the result to `serializeUsda`). */\n toUsda(options: Omit<ExportRobotOptions, \"geometry\"> = {}): UsdaFile {\n const { desc, geometry } = this.build();\n return exportRobotUsda(desc, { onWarn: this.warn, ...options, geometry });\n }\n\n /** Collect `THREE.Mesh` descendants of `roots` as link-relative export meshes. */\n private gatherMeshes(\n roots: THREE.Object3D[],\n linkWorld: Mat4,\n kind: \"visual\" | \"collision\",\n collisionExtras: {\n approximation?: CollisionApproximation;\n material?: ExportPhysicsMaterial;\n } = {},\n ): ExportMesh[] {\n const linkInverse = invert(linkWorld);\n const out: ExportMesh[] = [];\n for (const root of roots) {\n root.updateWorldMatrix(true, true);\n root.traverse((obj) => {\n const meshObj = obj as THREE.Mesh;\n if (!meshObj.isMesh) return;\n const material = Array.isArray(meshObj.material) ? meshObj.material[0] : meshObj.material;\n if (Array.isArray(meshObj.material) && meshObj.material.length > 1) {\n this.warn(\n `mesh \"${meshObj.name}\": multi-material meshes export their first material only`,\n );\n }\n const exportMaterial = material ? this.convertMaterial(material) : undefined;\n const mesh = geometryToExportMesh(meshObj.geometry, {\n name: meshObj.name || \"mesh\",\n kind,\n transform: multiply(linkInverse, [...meshObj.matrixWorld.elements]),\n ...(exportMaterial ? { material: exportMaterial } : {}),\n doubleSided: material?.side === THREE.DoubleSide,\n });\n if (mesh) {\n if (kind === \"collision\") {\n if (collisionExtras.approximation !== undefined) {\n mesh.collisionApproximation = collisionExtras.approximation;\n }\n if (collisionExtras.material) mesh.physicsMaterial = collisionExtras.material;\n }\n out.push(mesh);\n } else {\n this.warn(`mesh \"${meshObj.name}\": no triangle geometry; skipped`);\n }\n });\n }\n return out;\n }\n\n private convertMaterial(material: THREE.Material): ExportMaterial | undefined {\n if (!this.materialCache.has(material)) {\n const name = material.name || `Material_${this.materialAutoId++}`;\n this.materialCache.set(material, materialToExportMaterial(material, name, this.warn));\n }\n return this.materialCache.get(material);\n }\n}\n\nfunction isIdentityMat4(m: Mat4): boolean {\n for (let i = 0; i < 16; i++) {\n if (m[i] !== (i % 5 === 0 ? 1 : 0)) return false;\n }\n return true;\n}\n\n/** World matrix of a frame argument (`matrixWorld` refreshed for objects). */\nfunction resolveFrame(frame: WorldFrame | undefined): Mat4 | undefined {\n if (!frame) return undefined;\n if ((frame as THREE.Object3D).isObject3D) {\n const obj = frame as THREE.Object3D;\n obj.updateWorldMatrix(true, false);\n return [...obj.matrixWorld.elements];\n }\n return [...(frame as THREE.Matrix4).elements];\n}\n"]}
1
+ {"version":3,"sources":["../src/three/exportThreeUsdRobot.ts","../src/three/RobotBuilder.ts"],"names":["material","exportMaterial","mesh","isIdentityMat4","THREE2"],"mappings":";;;;;;;;;;;;AAyCO,SAAS,oBAAA,CACd,UACA,OAAA,EACmB;AACnB,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,YAAA,CAAa,UAAU,CAAA;AACjD,EAAA,IAAI,CAAC,QAAA,IAAY,QAAA,CAAS,KAAA,KAAU,GAAG,OAAO,IAAA;AAE9C,EAAA,MAAM,KAAA,GAAQ,SAAS,QAAA,EAAS;AAChC,EAAA,MAAM,MAAM,KAAA,GACR,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,KAA0B,CAAA,GAC3C,KAAA,CAAM,IAAA,CAAK,EAAE,QAAQ,QAAA,CAAS,KAAA,IAAS,CAAC,CAAA,EAAG,MAAM,CAAC,CAAA;AACtD,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,GAClB,GAAA,CAAI,MAAM,OAAA,CAAQ,KAAA,CAAM,KAAA,EAAO,OAAA,CAAQ,KAAA,CAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA,GACxE,GAAA;AACJ,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,SAAS,CAAC,CAAA;AAC7C,EAAA,IAAI,SAAA,KAAc,GAAG,OAAO,IAAA;AAE5B,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,YAAA,CAAa,QAAQ,CAAA;AAC7C,EAAA,MAAM,EAAA,GAAK,QAAA,CAAS,YAAA,CAAa,IAAI,CAAA;AACrC,EAAA,MAAM,aAAa,CAAC,CAAC,MAAA,IAAU,MAAA,CAAO,UAAU,QAAA,CAAS,KAAA;AACzD,EAAA,MAAM,QAAQ,CAAC,CAAC,EAAA,IAAM,EAAA,CAAG,UAAU,QAAA,CAAS,KAAA;AAE5C,EAAA,MAAM,SAAiB,EAAC;AACxB,EAAA,MAAM,UAAkB,EAAC;AACzB,EAAA,MAAM,KAAa,EAAC;AACpB,EAAA,IAAI,iBAAA;AAEJ,EAAA,IAAI,QAAQ,KAAA,EAAO;AAEjB,IAAA,MAAM,KAAA,uBAAY,GAAA,EAAoB;AACtC,IAAA,iBAAA,GAAoB,EAAC;AACrB,IAAA,KAAA,MAAW,UAAU,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,SAAA,GAAY,CAAC,CAAA,EAAG;AAClD,MAAA,IAAI,MAAA,GAAS,KAAA,CAAM,GAAA,CAAI,MAAM,CAAA;AAC7B,MAAA,IAAI,WAAW,MAAA,EAAW;AACxB,QAAA,MAAA,GAAS,MAAA,CAAO,MAAA;AAChB,QAAA,KAAA,CAAM,GAAA,CAAI,QAAQ,MAAM,CAAA;AACxB,QAAA,MAAA,CAAO,IAAA,CAAK,CAAC,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA,EAAG,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA,EAAG,QAAA,CAAS,IAAA,CAAK,MAAM,CAAC,CAAC,CAAA;AACjF,QAAA,IAAI,UAAA;AACF,UAAA,OAAA,CAAQ,IAAA,CAAK,CAAC,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,EAAG,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,EAAG,MAAA,CAAO,IAAA,CAAK,MAAM,CAAC,CAAC,CAAA;AAC9E,QAAA,IAAI,KAAA,EAAO,EAAA,CAAG,IAAA,CAAK,CAAC,EAAA,CAAG,IAAA,CAAK,MAAM,CAAA,EAAG,EAAA,CAAG,IAAA,CAAK,MAAM,CAAC,CAAC,CAAA;AAAA,MACvD;AACA,MAAA,iBAAA,CAAkB,KAAK,MAAM,CAAA;AAAA,IAC/B;AAAA,EACF,CAAA,MAAO;AACL,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,CAAS,OAAO,CAAA,EAAA,EAAK;AACvC,MAAA,MAAA,CAAO,IAAA,CAAK,CAAC,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,EAAG,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,EAAG,QAAA,CAAS,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA;AAClE,MAAA,IAAI,YAAY,OAAA,CAAQ,IAAA,CAAK,CAAC,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,MAAA,CAAO,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA;AAC7E,MAAA,IAAI,KAAA,EAAO,EAAA,CAAG,IAAA,CAAK,CAAC,EAAA,CAAG,IAAA,CAAK,CAAC,CAAA,EAAG,EAAA,CAAG,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA;AAAA,IAC7C;AACA,IAAA,iBAAA,GAAoB,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,SAAA,GAAY,CAAC,CAAA;AAAA,EAClD;AAEA,EAAA,MAAM,IAAA,GAAmB;AAAA,IACvB,MAAM,OAAA,CAAQ,IAAA;AAAA,IACd,IAAA,EAAM,QAAQ,IAAA,IAAQ,QAAA;AAAA,IACtB,MAAA;AAAA,IACA,kBAAkB,IAAI,KAAA,CAAM,SAAS,CAAA,CAAE,KAAK,CAAC,CAAA;AAAA,IAC7C;AAAA,GACF;AACA,EAAA,IAAI,UAAA,OAAiB,OAAA,GAAU,OAAA;AAC/B,EAAA,IAAI,KAAA,OAAY,EAAA,GAAK,EAAA;AAErB,EAAA,IAAI,OAAA,CAAQ,aAAa,CAAC,cAAA,CAAe,QAAQ,SAAS,CAAA,EAAG,IAAA,CAAK,SAAA,GAAY,OAAA,CAAQ,SAAA;AACtF,EAAA,IAAI,OAAA,CAAQ,QAAA,EAAU,IAAA,CAAK,QAAA,GAAW,OAAA,CAAQ,QAAA;AAC9C,EAAA,IAAI,OAAA,CAAQ,WAAA,EAAa,IAAA,CAAK,WAAA,GAAc,IAAA;AAC5C,EAAA,OAAO,IAAA;AACT;AAOO,SAAS,wBAAA,CACd,QAAA,EACA,IAAA,EACA,MAAA,EAC4B;AAC5B,EAAA,MAAM,GAAA,GAAM,QAAA;AACZ,EAAA,IAAI,CAAC,IAAI,sBAAA,EAAwB;AAC/B,IAAA,MAAA,GAAS,CAAA,UAAA,EAAa,IAAI,CAAA,kEAAA,CAAoE,CAAA;AAC9F,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IACE,GAAA,CAAI,GAAA,IACJ,GAAA,CAAI,SAAA,IACJ,GAAA,CAAI,YAAA,IACJ,GAAA,CAAI,YAAA,IACJ,GAAA,CAAI,KAAA,IACJ,GAAA,CAAI,WAAA,IACJ,IAAI,QAAA,EACJ;AACA,IAAA,MAAA;AAAA,MACE,aAAa,IAAI,CAAA,sGAAA;AAAA,KACnB;AAAA,EACF;AAEA,EAAA,MAAM,GAAA,GAAsB;AAAA,IAC1B,IAAA;AAAA,IACA,YAAA,EAAc,CAAC,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,IAAI,KAAA,CAAM,CAAA,EAAG,GAAA,CAAI,KAAA,CAAM,CAAC,CAAA;AAAA,IACpD,UAAU,GAAA,CAAI,SAAA;AAAA,IACd,WAAW,GAAA,CAAI;AAAA,GACjB;AACA,EAAA,IAAI,IAAI,WAAA,IAAe,GAAA,CAAI,UAAU,CAAA,EAAG,GAAA,CAAI,UAAU,GAAA,CAAI,OAAA;AAC1D,EAAA,IAAI,GAAA,CAAI,QAAA,CAAS,CAAA,GAAI,CAAA,IAAK,GAAA,CAAI,QAAA,CAAS,CAAA,GAAI,CAAA,IAAK,GAAA,CAAI,QAAA,CAAS,CAAA,GAAI,CAAA,EAAG;AAClE,IAAA,GAAA,CAAI,aAAA,GAAgB,CAAC,GAAA,CAAI,QAAA,CAAS,CAAA,EAAG,IAAI,QAAA,CAAS,CAAA,EAAG,GAAA,CAAI,QAAA,CAAS,CAAC,CAAA;AAAA,EACrE;AACA,EAAA,OAAO,GAAA;AACT;AAOO,SAAS,qBAAA,CACd,OACA,MAAA,EACuB;AACvB,EAAA,MAAM,aAAA,uBAAoB,GAAA,EAAgD;AAC1E,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,MAAM,eAAA,GAAkB,CAAC,QAAA,KAAyD;AAChF,IAAA,IAAI,CAAC,aAAA,CAAc,GAAA,CAAI,QAAQ,CAAA,EAAG;AAChC,MAAA,MAAM,IAAA,GAAO,QAAA,CAAS,IAAA,IAAQ,CAAA,SAAA,EAAY,MAAA,EAAQ,CAAA,CAAA;AAClD,MAAA,aAAA,CAAc,IAAI,QAAA,EAAU,wBAAA,CAAyB,QAAA,EAAU,IAAA,EAAM,MAAM,CAAC,CAAA;AAAA,IAC9E;AACA,IAAA,OAAO,aAAA,CAAc,IAAI,QAAQ,CAAA;AAAA,EACnC,CAAA;AAEA,EAAA,OAAO,CAAC,OAAA,KAAY;AAClB,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,aAAA,CAAc,OAAO,CAAA;AAC3C,IAAA,IAAI,CAAC,OAAA,EAAS,OAAO,EAAC;AAEtB,IAAA,MAAM,MAAoB,EAAC;AAC3B,IAAA,KAAA,MAAW,QAAA,IAAY,QAAQ,QAAA,EAAU;AACvC,MAAA,MAAM,OAAA,GAAU,QAAA;AAChB,MAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACrB,MAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,QAAA,CAAS,IAAA,KAAS,cAAc,WAAA,GAAc,QAAA;AACnE,MAAA,MAAM,SAAA,GAAY,CAAC,GAAG,OAAA,CAAQ,OAAO,QAAQ,CAAA;AAC7C,MAAA,MAAM,QAAA,GAAW,QAAQ,IAAA,IAAQ,MAAA;AACjC,MAAA,MAAM,SAAA,GAAY,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,QAAQ,IAAI,OAAA,CAAQ,QAAA,GAAW,CAAC,OAAA,CAAQ,QAAQ,CAAA;AACxF,MAAA,MAAM,MAAA,GAAS,QAAQ,QAAA,CAAS,MAAA;AAIhC,MAAA,IAAI,SAAA,CAAU,MAAA,GAAS,CAAA,IAAK,MAAA,CAAO,SAAS,CAAA,EAAG;AAC7C,QAAA,KAAA,MAAW,CAAC,CAAA,EAAG,KAAK,CAAA,IAAK,MAAA,CAAO,SAAQ,EAAG;AACzC,UAAA,MAAMA,SAAAA,GAAW,SAAA,CAAU,KAAA,CAAM,aAAA,IAAiB,CAAC,CAAA;AACnD,UAAA,MAAMC,eAAAA,GAAiBD,SAAAA,GAAW,eAAA,CAAgBA,SAAQ,CAAA,GAAI,MAAA;AAC9D,UAAA,MAAME,KAAAA,GAAO,oBAAA,CAAqB,OAAA,CAAQ,QAAA,EAAU;AAAA,YAClD,MAAM,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAIF,SAAAA,EAAU,QAAQ,CAAC,CAAA,CAAA;AAAA,YACxC,IAAA;AAAA,YACA,SAAA;AAAA,YACA,OAAO,EAAE,KAAA,EAAO,MAAM,KAAA,EAAO,KAAA,EAAO,MAAM,KAAA,EAAM;AAAA,YAChD,GAAIC,eAAAA,GAAiB,EAAE,QAAA,EAAUA,eAAAA,KAAmB,EAAC;AAAA,YACrD,WAAA,EAAaD,WAAU,IAAA,KAAe,KAAA,CAAA;AAAA,WACvC,CAAA;AACD,UAAA,IAAIE,KAAAA,EAAM,GAAA,CAAI,IAAA,CAAKA,KAAI,CAAA;AAAA,QACzB;AACA,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,QAAA,GAAW,UAAU,CAAC,CAAA;AAC5B,MAAA,MAAM,cAAA,GAAiB,QAAA,GAAW,eAAA,CAAgB,QAAQ,CAAA,GAAI,MAAA;AAC9D,MAAA,MAAM,IAAA,GAAO,oBAAA,CAAqB,OAAA,CAAQ,QAAA,EAAU;AAAA,QAClD,IAAA,EAAM,QAAA;AAAA,QACN,IAAA;AAAA,QACA,SAAA;AAAA,QACA,GAAI,cAAA,GAAiB,EAAE,QAAA,EAAU,cAAA,KAAmB,EAAC;AAAA,QACrD,WAAA,EAAa,UAAU,IAAA,KAAe,KAAA,CAAA;AAAA,OACvC,CAAA;AACD,MAAA,IAAI,IAAA,EAAM,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA;AAAA,IACzB;AACA,IAAA,OAAO,GAAA;AAAA,EACT,CAAA;AACF;AAQO,SAAS,mBAAA,CACd,KAAA,EACA,OAAA,GAAsC,EAAC,EAC7B;AACV,EAAA,MAAM,EAAE,KAAA,EAAO,GAAG,IAAA,EAAK,GAAI,OAAA;AAC3B,EAAA,MAAM,QAAA,GAAW,QACb,qBAAA,CAAsB,KAAK,IAC3B,qBAAA,CAAsB,KAAA,EAAO,QAAQ,MAAM,CAAA;AAC/C,EAAA,OAAO,gBAAgB,KAAA,CAAM,KAAA,EAAO,EAAE,GAAG,IAAA,EAAM,UAAU,CAAA;AAC3D;AAEA,SAAS,eAAe,CAAA,EAAkB;AACxC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,IAAI,CAAA,CAAE,CAAC,CAAA,MAAO,CAAA,GAAI,MAAM,CAAA,GAAI,CAAA,GAAI,IAAI,OAAO,KAAA;AAAA,EAC7C;AACA,EAAA,OAAO,IAAA;AACT;;;ACvJO,IAAM,eAAN,MAAmB;AAAA,EACP,SAAA;AAAA,EACA,MAAA;AAAA,EACA,aAAA;AAAA,EACA,gBAAA;AAAA,EACA,IAAA;AAAA,EAEA,KAAA,uBAAY,GAAA,EAG3B;AAAA,EACe,MAAA,uBAAa,GAAA,EAA0B;AAAA,EACvC,aAAA,uBAAoB,GAAA,EAAgD;AAAA,EAC7E,cAAA,GAAiB,CAAA;AAAA,EAEzB,YAAY,OAAA,EAA8B;AACxC,IAAA,IAAA,CAAK,YAAY,OAAA,CAAQ,IAAA;AACzB,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,GAAA;AAChC,IAAA,IAAA,CAAK,aAAA,GAAgB,QAAQ,aAAA,IAAiB,CAAA;AAC9C,IAAA,IAAI,OAAA,CAAQ,gBAAA,KAAqB,MAAA,EAAW,IAAA,CAAK,mBAAmB,OAAA,CAAQ,gBAAA;AAC5E,IAAA,IAAA,CAAK,IAAA,GAAO,OAAA,CAAQ,MAAA,KAAW,MAAM;AAAA,IAAC,CAAA,CAAA;AAAA,EACxC;AAAA,EAEA,QAAQ,OAAA,EAA+B;AACrC,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA,EAAG;AAChC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,oBAAA,EAAuB,OAAA,CAAQ,IAAI,CAAA,oBAAA,CAAsB,CAAA;AAAA,IAC3E;AACA,IAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,OAAA,CAAQ,KAAK,KAAK,SAAA,EAAU;AACvD,IAAA,MAAM,eAAA,GAAkB;AAAA,MACtB,GAAI,QAAQ,sBAAA,KAA2B,MAAA,GACnC,EAAE,aAAA,EAAe,OAAA,CAAQ,sBAAA,EAAuB,GAChD,EAAC;AAAA,MACL,GAAI,QAAQ,eAAA,GAAkB,EAAE,UAAU,OAAA,CAAQ,eAAA,KAAoB;AAAC,KACzE;AACA,IAAA,MAAM,MAAA,GAAS;AAAA,MACb,GAAG,KAAK,YAAA,CAAa,OAAA,CAAQ,WAAW,EAAC,EAAG,OAAO,QAAQ,CAAA;AAAA,MAC3D,GAAG,KAAK,YAAA,CAAa,OAAA,CAAQ,cAAc,EAAC,EAAG,KAAA,EAAO,WAAA,EAAa,eAAe;AAAA,KACpF;AACA,IAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,OAAA,CAAQ,IAAA,EAAM;AAAA,MAC3B,KAAA;AAAA,MACA,MAAA;AAAA,MACA,GAAI,QAAQ,QAAA,GAAW,EAAE,UAAU,OAAA,CAAQ,QAAA,KAAa;AAAC,KAC1D,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,cAAc,OAAA,EAAkE;AAC9E,IAAA,OAAO,IAAA,CAAK,QAAA,CAAS,OAAA,EAAS,OAAO,CAAA;AAAA,EACvC;AAAA,EAEA,iBAAiB,OAAA,EAAgC;AAC/C,IAAA,OAAO,IAAA,CAAK,QAAA,CAAS,UAAA,EAAY,OAAO,CAAA;AAAA,EAC1C;AAAA,EAEA,kBAAkB,OAAA,EAAgC;AAChD,IAAA,OAAO,IAAA,CAAK,QAAA,CAAS,WAAA,EAAa,OAAO,CAAA;AAAA,EAC3C;AAAA,EAEQ,QAAA,CAAS,MAAiB,OAAA,EAAgC;AAChE,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA,EAAG;AACjC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,OAAA,CAAQ,IAAI,CAAA,oBAAA,CAAsB,CAAA;AAAA,IAC5E;AACA,IAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,OAAA,CAAQ,KAAK,CAAA;AACxC,IAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,IAAA,EAAM,EAAE,IAAA,EAAM,OAAA,EAAS,GAAI,KAAA,GAAQ,EAAE,KAAA,EAAM,GAAI,IAAK,CAAA;AAC5E,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,KAAA,GAA0F;AACxF,IAAA,MAAM,QAAyC,EAAC;AAChD,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,CAAA,IAAK,KAAK,KAAA,EAAO;AACrC,MAAA,KAAA,CAAM,IAAI,CAAA,GAAI;AAAA,QACZ,IAAA;AAAA,QACA,QAAA,EAAU,CAAA,CAAA,EAAI,IAAA,CAAK,SAAS,IAAI,IAAI,CAAA,CAAA;AAAA,QACpC,aAAa,EAAC;AAAA,QACd,GAAI,KAAK,QAAA,GAAW,EAAE,UAAU,IAAA,CAAK,QAAA,KAAa,EAAC;AAAA;AAAA,QAEnD,GAAIC,eAAAA,CAAe,IAAA,CAAK,KAAK,CAAA,GAAI,EAAC,GAAI,EAAE,cAAA,EAAgB,IAAA,CAAK,KAAA;AAAM,OACrE;AAAA,IACF;AAEA,IAAA,MAAM,SAA2C,EAAC;AAClD,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,OAAO,CAAA,IAAK,KAAK,MAAA,EAAQ;AACzC,MAAA,MAAM,EAAE,SAAQ,GAAI,OAAA;AACpB,MAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,EAAA;AACjC,MAAA,IAAI,WAAW,EAAA,IAAM,CAAC,KAAK,KAAA,CAAM,GAAA,CAAI,MAAM,CAAA,EAAG;AAC5C,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,IAAI,CAAA,6BAAA,EAAgC,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,MACvF;AACA,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,QAAQ,KAAK,CAAA;AAC9C,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,qBAAA,EAAwB,IAAI,CAAA,4BAAA,EAA+B,OAAA,CAAQ,KAAK,CAAA,CAAA;AAAA,SAC1E;AAAA,MACF;AAEA,MAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,KAAA,IAAS,SAAA,CAAU,KAAA;AAC9C,MAAA,MAAM,WAAA,GAAc,WAAW,EAAA,GAAK,SAAA,KAAc,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,MAAM,CAAA,CAAG,KAAA;AAC1E,MAAA,MAAM,OAAO,eAAA,CAAgB,OAAA,CAAQ,MAAM,OAAA,CAAQ,KAAA,EAAO,QAAQ,KAAK,CAAA;AAEvE,MAAA,MAAA,CAAO,IAAI,CAAA,GAAI;AAAA,QACb,IAAA;AAAA,QACA,QAAA,EAAU,CAAA,CAAA,EAAI,IAAA,CAAK,SAAS,IAAI,IAAI,CAAA,CAAA;AAAA,QACpC,IAAA;AAAA,QACA,MAAA;AAAA,QACA,OAAO,OAAA,CAAQ,KAAA;AAAA,QACf,IAAA,EAAM,QAAQ,IAAA,IAAQ,GAAA;AAAA,QACtB,WAAA,EAAa,QAAA,CAAS,MAAA,CAAO,WAAW,GAAG,UAAU,CAAA;AAAA,QACrD,aAAa,QAAA,CAAS,MAAA,CAAO,SAAA,CAAU,KAAK,GAAG,UAAU,CAAA;AAAA,QACzD,GAAI,QAAQ,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAM,GAAI,EAAC;AAAA,QAC9D,GAAI,QAAQ,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAM,GAAI,EAAC;AAAA,QAC9D,GAAI,QAAQ,YAAA,KAAiB,MAAA,GAAY,EAAE,YAAA,EAAc,OAAA,CAAQ,YAAA,EAAa,GAAI,EAAC;AAAA,QACnF,GAAI,QAAQ,KAAA,GAAQ,EAAE,OAAO,OAAA,CAAQ,KAAA,KAAU;AAAC,OAClD;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,CAAK,qBAAqB,MAAA,IAAa,CAAC,KAAK,KAAA,CAAM,GAAA,CAAI,IAAA,CAAK,gBAAgB,CAAA,EAAG;AACjF,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gCAAA,EAAmC,IAAA,CAAK,gBAAgB,CAAA,eAAA,CAAiB,CAAA;AAAA,IAC3F;AAEA,IAAA,MAAM,IAAA,GAAyB;AAAA,MAC7B,MAAM,IAAA,CAAK,SAAA;AAAA,MACX,QAAA,EAAU,EAAA;AAAA,MACV,KAAA;AAAA,MACA,MAAA;AAAA,MACA,QAAQ,IAAA,CAAK,MAAA;AAAA,MACb,eAAe,IAAA,CAAK,aAAA;AAAA,MACpB,GAAI,IAAA,CAAK,gBAAA,KAAqB,MAAA,GAC1B,EAAE,iBAAA,EAAmB,CAAC,IAAA,CAAK,gBAAgB,CAAA,EAAE,GAC7C;AAAC,KACP;AAEA,IAAA,MAAM,OAAO,kBAAA,CAAmB,IAAA,EAAM,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAM,CAAA;AAC3D,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,IAAA;AACrB,IAAA,IAAI,KAAK,UAAA,CAAW,MAAA,GAAS,CAAA,EAAG,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA;AACvD,IAAA,IAAI,KAAK,QAAA,CAAS,MAAA,GAAS,CAAA,EAAG,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA;AAEnD,IAAA,MAAM,SAAS,IAAA,CAAK,KAAA;AACpB,IAAA,MAAM,QAAA,GAAkC,CAAC,OAAA,KAAY,MAAA,CAAO,IAAI,OAAO,CAAA,EAAG,UAAU,EAAC;AACrF,IAAA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAK;AAAA,EAChC;AAAA;AAAA,EAGA,MAAA,CAAO,OAAA,GAAgD,EAAC,EAAa;AACnE,IAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAS,GAAI,KAAK,KAAA,EAAM;AACtC,IAAA,OAAO,eAAA,CAAgB,MAAM,EAAE,MAAA,EAAQ,KAAK,IAAA,EAAM,GAAG,OAAA,EAAS,QAAA,EAAU,CAAA;AAAA,EAC1E;AAAA;AAAA,EAGQ,aACN,KAAA,EACA,SAAA,EACA,IAAA,EACA,eAAA,GAGI,EAAC,EACS;AACd,IAAA,MAAM,WAAA,GAAc,OAAO,SAAS,CAAA;AACpC,IAAA,MAAM,MAAoB,EAAC;AAC3B,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,IAAA,CAAK,iBAAA,CAAkB,MAAM,IAAI,CAAA;AACjC,MAAA,IAAA,CAAK,QAAA,CAAS,CAAC,GAAA,KAAQ;AACrB,QAAA,MAAM,OAAA,GAAU,GAAA;AAChB,QAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACrB,QAAA,MAAM,QAAA,GAAW,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,QAAQ,IAAI,OAAA,CAAQ,QAAA,CAAS,CAAC,CAAA,GAAI,OAAA,CAAQ,QAAA;AACjF,QAAA,IAAI,KAAA,CAAM,QAAQ,OAAA,CAAQ,QAAQ,KAAK,OAAA,CAAQ,QAAA,CAAS,SAAS,CAAA,EAAG;AAClE,UAAA,IAAA,CAAK,IAAA;AAAA,YACH,CAAA,MAAA,EAAS,QAAQ,IAAI,CAAA,yDAAA;AAAA,WACvB;AAAA,QACF;AACA,QAAA,MAAM,cAAA,GAAiB,QAAA,GAAW,IAAA,CAAK,eAAA,CAAgB,QAAQ,CAAA,GAAI,MAAA;AACnE,QAAA,MAAM,IAAA,GAAO,oBAAA,CAAqB,OAAA,CAAQ,QAAA,EAAU;AAAA,UAClD,IAAA,EAAM,QAAQ,IAAA,IAAQ,MAAA;AAAA,UACtB,IAAA;AAAA,UACA,SAAA,EAAW,SAAS,WAAA,EAAa,CAAC,GAAG,OAAA,CAAQ,WAAA,CAAY,QAAQ,CAAC,CAAA;AAAA,UAClE,GAAI,cAAA,GAAiB,EAAE,QAAA,EAAU,cAAA,KAAmB,EAAC;AAAA,UACrD,WAAA,EAAa,UAAU,IAAA,KAAeC,KAAA,CAAA;AAAA,SACvC,CAAA;AACD,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,IAAI,SAAS,WAAA,EAAa;AACxB,YAAA,IAAI,eAAA,CAAgB,kBAAkB,MAAA,EAAW;AAC/C,cAAA,IAAA,CAAK,yBAAyB,eAAA,CAAgB,aAAA;AAAA,YAChD;AACA,YAAA,IAAI,eAAA,CAAgB,QAAA,EAAU,IAAA,CAAK,eAAA,GAAkB,eAAA,CAAgB,QAAA;AAAA,UACvE;AACA,UAAA,GAAA,CAAI,KAAK,IAAI,CAAA;AAAA,QACf,CAAA,MAAO;AACL,UAAA,IAAA,CAAK,IAAA,CAAK,CAAA,MAAA,EAAS,OAAA,CAAQ,IAAI,CAAA,gCAAA,CAAkC,CAAA;AAAA,QACnE;AAAA,MACF,CAAC,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA,EAEQ,gBAAgB,QAAA,EAAsD;AAC5E,IAAA,IAAI,CAAC,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,QAAQ,CAAA,EAAG;AACrC,MAAA,MAAM,IAAA,GAAO,QAAA,CAAS,IAAA,IAAQ,CAAA,SAAA,EAAY,KAAK,cAAA,EAAgB,CAAA,CAAA;AAC/D,MAAA,IAAA,CAAK,aAAA,CAAc,IAAI,QAAA,EAAU,wBAAA,CAAyB,UAAU,IAAA,EAAM,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IACtF;AACA,IAAA,OAAO,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,QAAQ,CAAA;AAAA,EACxC;AACF;AAEA,SAASD,gBAAe,CAAA,EAAkB;AACxC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,IAAI,CAAA,CAAE,CAAC,CAAA,MAAO,CAAA,GAAI,MAAM,CAAA,GAAI,CAAA,GAAI,IAAI,OAAO,KAAA;AAAA,EAC7C;AACA,EAAA,OAAO,IAAA;AACT;AAGA,SAAS,aAAa,KAAA,EAAiD;AACrE,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,EAAA,IAAK,MAAyB,UAAA,EAAY;AACxC,IAAA,MAAM,GAAA,GAAM,KAAA;AACZ,IAAA,GAAA,CAAI,iBAAA,CAAkB,MAAM,KAAK,CAAA;AACjC,IAAA,OAAO,CAAC,GAAG,GAAA,CAAI,WAAA,CAAY,QAAQ,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,CAAC,GAAI,KAAA,CAAwB,QAAQ,CAAA;AAC9C","file":"index.js","sourcesContent":["/**\n * Three.js-side export (M14).\n *\n * Converts `BufferGeometry` / `MeshStandardMaterial` into the plain\n * {@link ExportMesh} data the exporter consumes, harvests the meshes attached\n * under a loaded robot's links, and re-exports a {@link ThreeUsdRobot} as a\n * USDA AST. Texture maps are not carried yet (M15) — constants only.\n */\n\nimport * as THREE from \"three\";\nimport type {\n ExportMaterial,\n ExportMesh,\n RobotGeometryProvider,\n} from \"../export/GeometryProvider.js\";\nimport { stageGeometryProvider } from \"../export/GeometryProvider.js\";\nimport { type ExportRobotOptions, exportRobotUsda } from \"../export/exportRobot.js\";\nimport type { Mat4 } from \"../kinematics/transforms.js\";\nimport type { UsdaFile, Vec2, Vec3 } from \"../parser/ast.js\";\nimport type { Stage } from \"../usd/Stage.js\";\nimport type { ThreeUsdRobot } from \"./ThreeUsdRobot.js\";\n\nexport type GeometryToExportMeshOptions = {\n name: string;\n kind?: \"visual\" | \"collision\";\n /** Transform relative to the link frame (column-major); identity when omitted. */\n transform?: Mat4;\n material?: ExportMaterial;\n doubleSided?: boolean;\n /**\n * Export only this slice of the index buffer — a `BufferGeometry` group, as\n * used by multi-material meshes. Vertices are re-indexed onto the slice.\n */\n group?: { start: number; count: number };\n};\n\n/**\n * Convert a triangle `BufferGeometry` into exportable mesh data. Non-indexed\n * geometry becomes sequential triangles; a trailing partial triangle (or the\n * absence of a position attribute) returns `null`.\n */\nexport function geometryToExportMesh(\n geometry: THREE.BufferGeometry,\n options: GeometryToExportMeshOptions,\n): ExportMesh | null {\n const position = geometry.getAttribute(\"position\");\n if (!position || position.count === 0) return null;\n\n const index = geometry.getIndex();\n const all = index\n ? Array.from(index.array as ArrayLike<number>)\n : Array.from({ length: position.count }, (_, i) => i);\n const slice = options.group\n ? all.slice(options.group.start, options.group.start + options.group.count)\n : all;\n const triangles = Math.floor(slice.length / 3);\n if (triangles === 0) return null;\n\n const normal = geometry.getAttribute(\"normal\");\n const uv = geometry.getAttribute(\"uv\");\n const hasNormals = !!normal && normal.count === position.count;\n const hasUv = !!uv && uv.count === position.count;\n\n const points: Vec3[] = [];\n const normals: Vec3[] = [];\n const st: Vec2[] = [];\n let faceVertexIndices: number[];\n\n if (options.group) {\n // Re-index onto just the vertices this group touches.\n const remap = new Map<number, number>();\n faceVertexIndices = [];\n for (const vertex of slice.slice(0, triangles * 3)) {\n let mapped = remap.get(vertex);\n if (mapped === undefined) {\n mapped = points.length;\n remap.set(vertex, mapped);\n points.push([position.getX(vertex), position.getY(vertex), position.getZ(vertex)]);\n if (hasNormals)\n normals.push([normal.getX(vertex), normal.getY(vertex), normal.getZ(vertex)]);\n if (hasUv) st.push([uv.getX(vertex), uv.getY(vertex)]);\n }\n faceVertexIndices.push(mapped);\n }\n } else {\n for (let i = 0; i < position.count; i++) {\n points.push([position.getX(i), position.getY(i), position.getZ(i)]);\n if (hasNormals) normals.push([normal.getX(i), normal.getY(i), normal.getZ(i)]);\n if (hasUv) st.push([uv.getX(i), uv.getY(i)]);\n }\n faceVertexIndices = slice.slice(0, triangles * 3);\n }\n\n const mesh: ExportMesh = {\n name: options.name,\n kind: options.kind ?? \"visual\",\n points,\n faceVertexCounts: new Array(triangles).fill(3),\n faceVertexIndices,\n };\n if (hasNormals) mesh.normals = normals;\n if (hasUv) mesh.st = st;\n\n if (options.transform && !isIdentityMat4(options.transform)) mesh.transform = options.transform;\n if (options.material) mesh.material = options.material;\n if (options.doubleSided) mesh.doubleSided = true;\n return mesh;\n}\n\n/**\n * Extract constant PBR parameters from a Three.js material. Only\n * `MeshStandardMaterial` maps onto `UsdPreviewSurface`; anything else returns\n * `undefined` (with a warning). Texture maps are reported but not carried.\n */\nexport function materialToExportMaterial(\n material: THREE.Material,\n name: string,\n onWarn?: (message: string) => void,\n): ExportMaterial | undefined {\n const std = material as THREE.MeshStandardMaterial;\n if (!std.isMeshStandardMaterial) {\n onWarn?.(`material \"${name}\": only MeshStandardMaterial exports to UsdPreviewSurface; skipped`);\n return undefined;\n }\n if (\n std.map ||\n std.normalMap ||\n std.roughnessMap ||\n std.metalnessMap ||\n std.aoMap ||\n std.emissiveMap ||\n std.alphaMap\n ) {\n onWarn?.(\n `material \"${name}\": texture maps are not carried from Three.js materials (image extraction is app-side); constants only`,\n );\n }\n\n const out: ExportMaterial = {\n name,\n diffuseColor: [std.color.r, std.color.g, std.color.b],\n metallic: std.metalness,\n roughness: std.roughness,\n };\n if (std.transparent && std.opacity < 1) out.opacity = std.opacity;\n if (std.emissive.r > 0 || std.emissive.g > 0 || std.emissive.b > 0) {\n out.emissiveColor = [std.emissive.r, std.emissive.g, std.emissive.b];\n }\n return out;\n}\n\n/**\n * Provider over the meshes `bindRobotMeshes` attached under each link of a\n * loaded robot (direct children tagged `userData.kind`), with their link-local\n * transforms and materials.\n */\nexport function threeGeometryProvider(\n robot: ThreeUsdRobot,\n onWarn?: (message: string) => void,\n): RobotGeometryProvider {\n const materialNames = new Map<THREE.Material, ExportMaterial | undefined>();\n let autoId = 0;\n const convertMaterial = (material: THREE.Material): ExportMaterial | undefined => {\n if (!materialNames.has(material)) {\n const name = material.name || `Material_${autoId++}`;\n materialNames.set(material, materialToExportMaterial(material, name, onWarn));\n }\n return materialNames.get(material);\n };\n\n return (linkKey) => {\n const linkObj = robot.getLinkObject(linkKey);\n if (!linkObj) return [];\n\n const out: ExportMesh[] = [];\n for (const childObj of linkObj.children) {\n const meshObj = childObj as THREE.Mesh;\n if (!meshObj.isMesh) continue;\n const kind = meshObj.userData.kind === \"collision\" ? \"collision\" : \"visual\";\n const transform = [...meshObj.matrix.elements];\n const baseName = meshObj.name || \"mesh\";\n const materials = Array.isArray(meshObj.material) ? meshObj.material : [meshObj.material];\n const groups = meshObj.geometry.groups;\n\n // A multi-material mesh exports one USD Mesh per geometry group, so each\n // group keeps its own material instead of collapsing to the first.\n if (materials.length > 1 && groups.length > 0) {\n for (const [i, group] of groups.entries()) {\n const material = materials[group.materialIndex ?? 0];\n const exportMaterial = material ? convertMaterial(material) : undefined;\n const mesh = geometryToExportMesh(meshObj.geometry, {\n name: `${baseName}_${material?.name || i}`,\n kind,\n transform,\n group: { start: group.start, count: group.count },\n ...(exportMaterial ? { material: exportMaterial } : {}),\n doubleSided: material?.side === THREE.DoubleSide,\n });\n if (mesh) out.push(mesh);\n }\n continue;\n }\n\n const material = materials[0];\n const exportMaterial = material ? convertMaterial(material) : undefined;\n const mesh = geometryToExportMesh(meshObj.geometry, {\n name: baseName,\n kind,\n transform,\n ...(exportMaterial ? { material: exportMaterial } : {}),\n doubleSided: material?.side === THREE.DoubleSide,\n });\n if (mesh) out.push(mesh);\n }\n return out;\n };\n}\n\nexport type ExportThreeUsdRobotOptions = Omit<ExportRobotOptions, \"geometry\"> & {\n /** Re-read mesh data from the source stage instead of the Three.js scene. */\n stage?: Stage;\n};\n\n/** Export a loaded robot back to a USDA AST (pass the result to `serializeUsda`). */\nexport function exportThreeUsdRobot(\n robot: ThreeUsdRobot,\n options: ExportThreeUsdRobotOptions = {},\n): UsdaFile {\n const { stage, ...rest } = options;\n const geometry = stage\n ? stageGeometryProvider(stage)\n : threeGeometryProvider(robot, options.onWarn);\n return exportRobotUsda(robot.robot, { ...rest, geometry });\n}\n\nfunction isIdentityMat4(m: Mat4): boolean {\n for (let i = 0; i < 16; i++) {\n if (m[i] !== (i % 5 === 0 ? 1 : 0)) return false;\n }\n return true;\n}\n","/**\n * Authoring API (M14): assemble a robot from Three.js objects and export it.\n *\n * Links and joints are declared by name. Every joint takes **one** world-space\n * frame; both body-local joint frames derive from it —\n * `frame0 = linkWorld(parent)⁻¹ · frame`, `frame1 = linkWorld(child)⁻¹ · frame`\n * — so the arrangement at build time is the robot's zero pose. Values are SI\n * (radians / stage linear units); the exporter converts to authored units on\n * write. World matrices are captured at `addLink`/`add*Joint` time.\n */\n\nimport * as THREE from \"three\";\nimport type {\n CollisionApproximation,\n ExportMaterial,\n ExportMesh,\n ExportPhysicsMaterial,\n RobotGeometryProvider,\n} from \"../export/GeometryProvider.js\";\nimport { type ExportRobotOptions, exportRobotUsda } from \"../export/exportRobot.js\";\nimport { type Mat4, identity4, invert, multiply } from \"../kinematics/transforms.js\";\nimport type { UsdaFile } from \"../parser/ast.js\";\nimport type {\n Axis,\n JointDescription,\n JointDriveDescription,\n JointType,\n LinkDescription,\n LinkInertialDescription,\n RobotDescription,\n} from \"../robot/RobotDescription.js\";\nimport { type KinematicTree, buildKinematicTree } from \"../robot/buildKinematicTree.js\";\nimport { refineJointType } from \"../robot/normalize.js\";\nimport { geometryToExportMesh, materialToExportMaterial } from \"./exportThreeUsdRobot.js\";\n\n/** A world-space frame: a matrix, or an object whose `matrixWorld` is used. */\nexport type WorldFrame = THREE.Matrix4 | THREE.Object3D;\n\nexport type RobotBuilderOptions = {\n name: string;\n /** Stage up axis; defaults to `\"Z\"` (Isaac Sim convention). */\n upAxis?: \"Y\" | \"Z\";\n /** Stage linear unit; defaults to `1` (meters). */\n metersPerUnit?: number;\n /** Link to flag with `PhysicsArticulationRootAPI` (default: the container prim). */\n articulationRoot?: string;\n onWarn?: (message: string) => void;\n};\n\nexport type AddLinkOptions = {\n name: string;\n /** Link frame in world space at build pose (default identity). */\n frame?: WorldFrame;\n /** Objects whose `THREE.Mesh` descendants become the link's visual meshes. */\n visuals?: THREE.Object3D[];\n /** Objects whose `THREE.Mesh` descendants become collision meshes. */\n collisions?: THREE.Object3D[];\n /** Mass properties, exported as `PhysicsMassAPI` (M16). */\n inertial?: LinkInertialDescription;\n /** `physics:approximation` applied to this link's collision meshes (M16). */\n collisionApproximation?: CollisionApproximation;\n /** Physics material bound to this link's collision meshes (M16). */\n physicsMaterial?: ExportPhysicsMaterial;\n};\n\nexport type AddJointOptions = {\n name: string;\n /** Parent link name; omit to fix the child to the world. */\n parent?: string;\n child: string;\n /** Joint frame in world space (default: the child link's frame). */\n frame?: WorldFrame;\n /** Rotation / sliding axis token in the joint frame (default `\"X\"`). */\n axis?: Axis;\n /** Limits in SI: radians (revolute) or stage linear units (prismatic). */\n lower?: number;\n upper?: number;\n /** Initial joint value in SI, exported as `PhysicsJointStateAPI`. */\n initialValue?: number;\n drive?: JointDriveDescription;\n};\n\ntype PendingJoint = {\n type: JointType;\n options: AddJointOptions;\n /** Joint frame world matrix captured at add time (undefined → child frame). */\n world?: Mat4;\n};\n\nexport class RobotBuilder {\n private readonly robotName: string;\n private readonly upAxis: \"Y\" | \"Z\";\n private readonly metersPerUnit: number;\n private readonly articulationRoot?: string;\n private readonly warn: (message: string) => void;\n\n private readonly links = new Map<\n string,\n { world: Mat4; meshes: ExportMesh[]; inertial?: LinkInertialDescription }\n >();\n private readonly joints = new Map<string, PendingJoint>();\n private readonly materialCache = new Map<THREE.Material, ExportMaterial | undefined>();\n private materialAutoId = 0;\n\n constructor(options: RobotBuilderOptions) {\n this.robotName = options.name;\n this.upAxis = options.upAxis ?? \"Z\";\n this.metersPerUnit = options.metersPerUnit ?? 1;\n if (options.articulationRoot !== undefined) this.articulationRoot = options.articulationRoot;\n this.warn = options.onWarn ?? (() => {});\n }\n\n addLink(options: AddLinkOptions): this {\n if (this.links.has(options.name)) {\n throw new Error(`RobotBuilder: link \"${options.name}\" is already defined`);\n }\n const world = resolveFrame(options.frame) ?? identity4();\n const collisionExtras = {\n ...(options.collisionApproximation !== undefined\n ? { approximation: options.collisionApproximation }\n : {}),\n ...(options.physicsMaterial ? { material: options.physicsMaterial } : {}),\n };\n const meshes = [\n ...this.gatherMeshes(options.visuals ?? [], world, \"visual\"),\n ...this.gatherMeshes(options.collisions ?? [], world, \"collision\", collisionExtras),\n ];\n this.links.set(options.name, {\n world,\n meshes,\n ...(options.inertial ? { inertial: options.inertial } : {}),\n });\n return this;\n }\n\n addFixedJoint(options: Omit<AddJointOptions, \"axis\" | \"lower\" | \"upper\">): this {\n return this.addJoint(\"fixed\", options);\n }\n\n addRevoluteJoint(options: AddJointOptions): this {\n return this.addJoint(\"revolute\", options);\n }\n\n addPrismaticJoint(options: AddJointOptions): this {\n return this.addJoint(\"prismatic\", options);\n }\n\n private addJoint(type: JointType, options: AddJointOptions): this {\n if (this.joints.has(options.name)) {\n throw new Error(`RobotBuilder: joint \"${options.name}\" is already defined`);\n }\n const world = resolveFrame(options.frame);\n this.joints.set(options.name, { type, options, ...(world ? { world } : {}) });\n return this;\n }\n\n /** Assemble the IR + geometry provider (validates the kinematic graph). */\n build(): { desc: RobotDescription; geometry: RobotGeometryProvider; tree: KinematicTree } {\n const links: Record<string, LinkDescription> = {};\n for (const [name, link] of this.links) {\n links[name] = {\n name,\n primPath: `/${this.robotName}/${name}`,\n visualPrims: [],\n ...(link.inertial ? { inertial: link.inertial } : {}),\n // Authored placement, so links no joint reaches keep their build pose.\n ...(isIdentityMat4(link.world) ? {} : { worldTransform: link.world }),\n };\n }\n\n const joints: Record<string, JointDescription> = {};\n for (const [name, pending] of this.joints) {\n const { options } = pending;\n const parent = options.parent ?? \"\";\n if (parent !== \"\" && !this.links.has(parent)) {\n throw new Error(`RobotBuilder: joint \"${name}\" references unknown parent \"${parent}\"`);\n }\n const childLink = this.links.get(options.child);\n if (!childLink) {\n throw new Error(\n `RobotBuilder: joint \"${name}\" references unknown child \"${options.child}\"`,\n );\n }\n\n const jointWorld = pending.world ?? childLink.world;\n const parentWorld = parent === \"\" ? identity4() : this.links.get(parent)!.world;\n const type = refineJointType(pending.type, options.lower, options.upper);\n\n joints[name] = {\n name,\n primPath: `/${this.robotName}/${name}`,\n type,\n parent,\n child: options.child,\n axis: options.axis ?? \"X\",\n jointFrame0: multiply(invert(parentWorld), jointWorld),\n jointFrame1: multiply(invert(childLink.world), jointWorld),\n ...(options.lower !== undefined ? { lower: options.lower } : {}),\n ...(options.upper !== undefined ? { upper: options.upper } : {}),\n ...(options.initialValue !== undefined ? { initialValue: options.initialValue } : {}),\n ...(options.drive ? { drive: options.drive } : {}),\n };\n }\n\n if (this.articulationRoot !== undefined && !this.links.has(this.articulationRoot)) {\n throw new Error(`RobotBuilder: articulationRoot \"${this.articulationRoot}\" is not a link`);\n }\n\n const desc: RobotDescription = {\n name: this.robotName,\n rootLink: \"\",\n links,\n joints,\n upAxis: this.upAxis,\n metersPerUnit: this.metersPerUnit,\n ...(this.articulationRoot !== undefined\n ? { articulationRoots: [this.articulationRoot] }\n : {}),\n };\n\n const tree = buildKinematicTree(desc, { onWarn: this.warn });\n desc.rootLink = tree.root;\n if (tree.loopJoints.length > 0) desc.loopJoints = tree.loopJoints;\n if (tree.warnings.length > 0) desc.warnings = tree.warnings;\n\n const byLink = this.links;\n const geometry: RobotGeometryProvider = (linkKey) => byLink.get(linkKey)?.meshes ?? [];\n return { desc, geometry, tree };\n }\n\n /** Build and export in one step (pass the result to `serializeUsda`). */\n toUsda(options: Omit<ExportRobotOptions, \"geometry\"> = {}): UsdaFile {\n const { desc, geometry } = this.build();\n return exportRobotUsda(desc, { onWarn: this.warn, ...options, geometry });\n }\n\n /** Collect `THREE.Mesh` descendants of `roots` as link-relative export meshes. */\n private gatherMeshes(\n roots: THREE.Object3D[],\n linkWorld: Mat4,\n kind: \"visual\" | \"collision\",\n collisionExtras: {\n approximation?: CollisionApproximation;\n material?: ExportPhysicsMaterial;\n } = {},\n ): ExportMesh[] {\n const linkInverse = invert(linkWorld);\n const out: ExportMesh[] = [];\n for (const root of roots) {\n root.updateWorldMatrix(true, true);\n root.traverse((obj) => {\n const meshObj = obj as THREE.Mesh;\n if (!meshObj.isMesh) return;\n const material = Array.isArray(meshObj.material) ? meshObj.material[0] : meshObj.material;\n if (Array.isArray(meshObj.material) && meshObj.material.length > 1) {\n this.warn(\n `mesh \"${meshObj.name}\": multi-material meshes export their first material only`,\n );\n }\n const exportMaterial = material ? this.convertMaterial(material) : undefined;\n const mesh = geometryToExportMesh(meshObj.geometry, {\n name: meshObj.name || \"mesh\",\n kind,\n transform: multiply(linkInverse, [...meshObj.matrixWorld.elements]),\n ...(exportMaterial ? { material: exportMaterial } : {}),\n doubleSided: material?.side === THREE.DoubleSide,\n });\n if (mesh) {\n if (kind === \"collision\") {\n if (collisionExtras.approximation !== undefined) {\n mesh.collisionApproximation = collisionExtras.approximation;\n }\n if (collisionExtras.material) mesh.physicsMaterial = collisionExtras.material;\n }\n out.push(mesh);\n } else {\n this.warn(`mesh \"${meshObj.name}\": no triangle geometry; skipped`);\n }\n });\n }\n return out;\n }\n\n private convertMaterial(material: THREE.Material): ExportMaterial | undefined {\n if (!this.materialCache.has(material)) {\n const name = material.name || `Material_${this.materialAutoId++}`;\n this.materialCache.set(material, materialToExportMaterial(material, name, this.warn));\n }\n return this.materialCache.get(material);\n }\n}\n\nfunction isIdentityMat4(m: Mat4): boolean {\n for (let i = 0; i < 16; i++) {\n if (m[i] !== (i % 5 === 0 ? 1 : 0)) return false;\n }\n return true;\n}\n\n/** World matrix of a frame argument (`matrixWorld` refreshed for objects). */\nfunction resolveFrame(frame: WorldFrame | undefined): Mat4 | undefined {\n if (!frame) return undefined;\n if ((frame as THREE.Object3D).isObject3D) {\n const obj = frame as THREE.Object3D;\n obj.updateWorldMatrix(true, false);\n return [...obj.matrixWorld.elements];\n }\n return [...(frame as THREE.Matrix4).elements];\n}\n"]}