three-usd-robot 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/core.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { U as UsdaFile, i as MetadataMap, q as UsdValue, P as PrimSpec, l as RelationshipSpec, m as SdfPath, f as AttributeSpec, r as Variability, n as Specifier, b as Vec3, V as Vec2, M as Mat4, L as LinkDescription, R as RobotDescription, J as JointType, A as Axis, d as LinkInertialDescription } from './buildKinematicTree-Ccd2DIKH.js';
2
- export { e as AssetPath, B as BuildTreeOptions, C as CompositionArc, D as DEG2RAD, a as JointDescription, c as JointDriveDescription, g as KinematicNode, K as KinematicTree, h as ListOp, j as PropertySpec, Q as Quat, k as RAD2DEG, S as SampleChannel, T as TreeEdge, o as UsdDictionary, p as UsdMatrix, s as Vec4, t as buildKinematicTree, u as channelFromSamples, v as decomposeRigid, w as fromUsdMatrix, x as getTranslation, y as identity4, z as interpolate, E as invert, F as makeEuler, G as makeRotationFromQuat, H as makeRotationX, I as makeRotationY, N as makeRotationZ, O as makeScale, W as makeTranslation, X as multiply, Y as multiplyAll, Z as toUsdMatrix } from './buildKinematicTree-Ccd2DIKH.js';
3
- import { A as AssetResolver } from './AssetResolver-CpIJNgWZ.js';
4
- export { D as DefaultAssetResolver, c as createMemoryResolver, j as joinPosix } from './AssetResolver-CpIJNgWZ.js';
1
+ import { U as UsdaFile, i as MetadataMap, q as UsdValue, P as PrimSpec, l as RelationshipSpec, m as SdfPath, f as AttributeSpec, r as Variability, n as Specifier, b as Vec3, V as Vec2, M as Mat4, L as LinkDescription, R as RobotDescription, J as JointType, A as Axis, d as LinkInertialDescription } from './buildKinematicTree-D4R0hEtN.js';
2
+ export { e as AssetPath, B as BuildTreeOptions, C as CompositionArc, D as DEG2RAD, a as JointDescription, c as JointDriveDescription, g as KinematicNode, K as KinematicTree, h as ListOp, j as PropertySpec, Q as Quat, k as RAD2DEG, S as SampleChannel, T as TreeEdge, o as UsdDictionary, p as UsdMatrix, s as Vec4, t as buildKinematicTree, u as channelFromSamples, v as decomposeRigid, w as fromUsdMatrix, x as getTranslation, y as identity4, z as interpolate, E as invert, F as makeEuler, G as makeRotationFromQuat, H as makeRotationX, I as makeRotationY, N as makeRotationZ, O as makeScale, W as makeTranslation, X as multiply, Y as multiplyAll, Z as toUsdMatrix } from './buildKinematicTree-D4R0hEtN.js';
3
+ import { A as AssetResolver } from './bytes-MOJ2oN-u.js';
4
+ export { B as BinarySource, D as DefaultAssetResolver, U as UsdSource, c as createMemoryResolver, j as joinPosix, t as toBytes } from './bytes-MOJ2oN-u.js';
5
5
 
6
6
  /** Package identity. Kept in one place so every entry point can re-export it. */
7
7
  declare const PACKAGE_NAME = "three-usd-robot";
@@ -446,6 +446,12 @@ declare function parseOpType(opName: string): string;
446
446
  * binary crate (`.usdc`), which composition sniffs and decodes (M10).
447
447
  */
448
448
 
449
+ /**
450
+ * True when the bytes start with a zip magic (`PK\x03\x04`, or the empty /
451
+ * spanned archive markers). A `.usdz` always begins with a local file header,
452
+ * so this is the sniff counterpart of {@link CrateReader.isCrate}.
453
+ */
454
+ declare function isZip(bytes: Uint8Array): boolean;
449
455
  type UsdzPackage = {
450
456
  /** Archive path of the root layer to open. */
451
457
  rootEntry: string;
@@ -597,10 +603,16 @@ declare function refineJointType(base: JointType, lower: number | undefined, upp
597
603
  declare function isXform(prim: Prim): boolean;
598
604
  declare function isScope(prim: Prim): boolean;
599
605
  declare function isMesh(prim: Prim): boolean;
606
+ /** True for a `Cube` / `Sphere` / `Cylinder` / `Capsule` / `Cone` prim. */
607
+ declare function isSolidGprim(prim: Prim): boolean;
608
+ /** True for any gprim the runtime can render: a `Mesh` or a parametric solid. */
609
+ declare function isRenderableGprim(prim: Prim): boolean;
600
610
  /** Depth-first iterator over all descendant prims (excluding `prim` itself). */
601
611
  declare function iterDescendants(prim: Prim): Generator<Prim>;
602
612
  /** Collect the prim paths of all Mesh descendants of a link prim. */
603
613
  declare function gatherMeshDescendants(prim: Prim): string[];
614
+ /** Collect the prim paths of all renderable gprim descendants (meshes + solids). */
615
+ declare function gatherGprimDescendants(prim: Prim): string[];
604
616
 
605
617
  /**
606
618
  * UsdPhysics schema helpers for robot extraction.
@@ -652,4 +664,4 @@ declare function getJointStatePosition(prim: Prim, kind: "angular" | "linear"):
652
664
  /** Read `UsdPhysicsMassAPI` properties, or `undefined` when none are authored (M16). */
653
665
  declare function getMassProperties(prim: Prim): LinkInertialDescription | undefined;
654
666
 
655
- export { ARTICULATION_ROOT_API, AssetResolver, Attribute, AttributeSpec, Axis, COLLISION_API, type CollisionApproximation, type ComposeOptions, CrateReader, DEFAULT_METERS_PER_UNIT, type ExportMaterial, type ExportMesh, type ExportPhysicsMaterial, type ExportRobotOptions, type ExtractOptions, JointType, Layer, LinkDescription, LinkInertialDescription, MASS_API, MESH_COLLISION_API, Mat4, MetadataMap, PACKAGE_NAME, PHYSICS_MATERIAL_API, ParseError, Prim, PrimSpec, RIGID_BODY_API, Relationship, RelationshipSpec, type ResolvedXform, RobotDescription, type RobotGeometryProvider, SdfPath, Specifier, Stage, type TextureChannel, TokenizeError, type UpAxis, UsdValue, UsdaFile, type UsdzPackage, VERSION, type ValidateRobotOptions, type ValidationIssue, type ValidationSeverity, Variability, Vec2, Vec3, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, driveKindFor, exportRobotUsda, extractRobotDescription, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, isMesh, isScope, isXform, iterDescendants, jointValueFromSI, jointValueToSI, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, serializeUsda, stageGeometryProvider, tokenize, validateRobotDescription, writeUsdz };
667
+ export { ARTICULATION_ROOT_API, AssetResolver, Attribute, AttributeSpec, Axis, COLLISION_API, type CollisionApproximation, type ComposeOptions, CrateReader, DEFAULT_METERS_PER_UNIT, type ExportMaterial, type ExportMesh, type ExportPhysicsMaterial, type ExportRobotOptions, type ExtractOptions, JointType, Layer, LinkDescription, LinkInertialDescription, MASS_API, MESH_COLLISION_API, Mat4, MetadataMap, PACKAGE_NAME, PHYSICS_MATERIAL_API, ParseError, Prim, PrimSpec, RIGID_BODY_API, Relationship, RelationshipSpec, type ResolvedXform, RobotDescription, type RobotGeometryProvider, SdfPath, Specifier, Stage, type TextureChannel, TokenizeError, type UpAxis, UsdValue, UsdaFile, type UsdzPackage, VERSION, type ValidateRobotOptions, type ValidationIssue, type ValidationSeverity, Variability, Vec2, Vec3, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, driveKindFor, exportRobotUsda, extractRobotDescription, gatherGprimDescendants, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, isMesh, isRenderableGprim, isScope, isSolidGprim, isXform, isZip, iterDescendants, jointValueFromSI, jointValueToSI, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, serializeUsda, stageGeometryProvider, tokenize, validateRobotDescription, writeUsdz };
package/dist/core.js CHANGED
@@ -1,4 +1,5 @@
1
- export { PACKAGE_NAME, VERSION, exportRobotUsda, stageGeometryProvider, validateRobotDescription, writeUsdz } from './chunk-O7XP5FQ4.js';
2
- export { ARTICULATION_ROOT_API, AssetPath, Attribute, COLLISION_API, CrateReader, DEFAULT_METERS_PER_UNIT, DEG2RAD, DefaultAssetResolver, Layer, MASS_API, MESH_COLLISION_API, PHYSICS_MATERIAL_API, ParseError, Prim, Quat, RAD2DEG, RIGID_BODY_API, Relationship, Stage, TokenizeError, UsdMatrix, buildKinematicTree, channelFromSamples, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, createMemoryResolver, decomposeRigid, driveKindFor, extractRobotDescription, fromUsdMatrix, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, getTranslation, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, identity4, interpolate, invert, isMesh, isScope, isXform, iterDescendants, joinPosix, jointValueFromSI, jointValueToSI, makeEuler, makeRotationFromQuat, makeRotationX, makeRotationY, makeRotationZ, makeScale, makeTranslation, multiply, multiplyAll, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, serializeUsda, toUsdMatrix, tokenize } from './chunk-4GPCBXUS.js';
1
+ export { PACKAGE_NAME, VERSION, exportRobotUsda, stageGeometryProvider, validateRobotDescription, writeUsdz } from './chunk-P6CHTMGW.js';
2
+ export { ARTICULATION_ROOT_API, Attribute, COLLISION_API, CrateReader, DEFAULT_METERS_PER_UNIT, DefaultAssetResolver, Layer, MASS_API, MESH_COLLISION_API, PHYSICS_MATERIAL_API, ParseError, Prim, RIGID_BODY_API, Relationship, Stage, TokenizeError, buildKinematicTree, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, createMemoryResolver, driveKindFor, extractRobotDescription, gatherGprimDescendants, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, isMesh, isRenderableGprim, isScope, isSolidGprim, isXform, isZip, iterDescendants, joinPosix, jointValueFromSI, jointValueToSI, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, serializeUsda, toBytes, tokenize } from './chunk-PHHMWMCA.js';
3
+ export { AssetPath, DEG2RAD, Quat, RAD2DEG, UsdMatrix, channelFromSamples, decomposeRigid, fromUsdMatrix, getTranslation, identity4, interpolate, invert, makeEuler, makeRotationFromQuat, makeRotationX, makeRotationY, makeRotationZ, makeScale, makeTranslation, multiply, multiplyAll, toUsdMatrix } from './chunk-IYKPVUZ2.js';
3
4
  //# sourceMappingURL=core.js.map
4
5
  //# sourceMappingURL=core.js.map
package/dist/extras.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { T as ThreeUsdRobot } from './ThreeUsdRobot-Ljh4PDVD.js';
1
+ import { T as ThreeUsdRobot } from './ThreeUsdRobot-BZ_vlr1R.js';
2
2
  import 'three';
3
- import './buildKinematicTree-Ccd2DIKH.js';
3
+ import './buildKinematicTree-D4R0hEtN.js';
4
4
 
5
5
  /**
6
6
  * `three-usd-robot/extras`
package/dist/helpers.d.ts CHANGED
@@ -1,6 +1,76 @@
1
1
  import * as THREE from 'three';
2
- import { J as JointObject, T as ThreeUsdRobot } from './ThreeUsdRobot-Ljh4PDVD.js';
3
- import './buildKinematicTree-Ccd2DIKH.js';
2
+ import { T as ThreeUsdRobot, J as JointObject } from './ThreeUsdRobot-BZ_vlr1R.js';
3
+ import './buildKinematicTree-D4R0hEtN.js';
4
+
5
+ /**
6
+ * Per-link appearance helpers: highlight (tint), material replacement, and
7
+ * translucent "ghost" clones for pose previews.
8
+ *
9
+ * Material overrides are reversible — the original materials are kept aside on
10
+ * first override and put back exactly by {@link restoreLinkMaterials} /
11
+ * {@link restoreAllLinkMaterials}. Links are addressed like everywhere else:
12
+ * by key or by full prim path.
13
+ */
14
+
15
+ /** Which meshes of a link an operation affects. */
16
+ type LinkMeshKind = "visual" | "collision" | "all";
17
+ /**
18
+ * The meshes belonging to exactly this link — not those of child links, which
19
+ * live under their own `LinkObject` deeper in the kinematic chain. Helpers and
20
+ * joint-frame groups are excluded.
21
+ */
22
+ declare function getLinkMeshes(robot: ThreeUsdRobot, link: string, kind?: LinkMeshKind): THREE.Mesh[];
23
+ type HighlightLinkOptions = {
24
+ /** Highlight color (default red `0xff4444`). */
25
+ color?: THREE.ColorRepresentation;
26
+ /** Emissive strength of the tint (default `0.8`). */
27
+ emissiveIntensity?: number;
28
+ /** Force translucency while highlighted (e.g. `0.5`); default keeps the material's own. */
29
+ opacity?: number;
30
+ /** Which meshes of the link to affect (default `"visual"`). */
31
+ kind?: LinkMeshKind;
32
+ };
33
+ /**
34
+ * Tint a link's meshes (emissive red by default) while keeping their maps and
35
+ * base colors — e.g. to flag a colliding link. Repeated calls re-tint from the
36
+ * *original* materials, so highlights don't stack; restore with
37
+ * {@link restoreLinkMaterials}. Returns `false` when the link has no matching
38
+ * meshes.
39
+ */
40
+ declare function highlightLink(robot: ThreeUsdRobot, link: string, options?: HighlightLinkOptions): boolean;
41
+ /**
42
+ * Replace a link's mesh materials with `material` (one shared instance). The
43
+ * caller keeps ownership — it is never disposed here. Restore the originals
44
+ * with {@link restoreLinkMaterials}. Returns `false` when the link has no
45
+ * matching meshes.
46
+ */
47
+ declare function setLinkMaterial(robot: ThreeUsdRobot, link: string, material: THREE.Material, kind?: LinkMeshKind): boolean;
48
+ /** Put back a link's original materials (no-op for untouched meshes). */
49
+ declare function restoreLinkMaterials(robot: ThreeUsdRobot, link: string): void;
50
+ /** Put back the original materials of every link of the robot. */
51
+ declare function restoreAllLinkMaterials(robot: ThreeUsdRobot): void;
52
+ type GhostRobotOptions = {
53
+ /** Ghost tint (default `0x66aaff`). */
54
+ color?: THREE.ColorRepresentation;
55
+ /** Ghost opacity (default `0.35`). */
56
+ opacity?: number;
57
+ /** Complete material override; `color` / `opacity` are ignored when given. */
58
+ material?: THREE.Material;
59
+ /** Which meshes to clone (default `"visual"`). */
60
+ kind?: "visual" | "collision";
61
+ /** Joint overrides applied on top of the source robot's current pose. */
62
+ jointValues?: Record<string, number>;
63
+ };
64
+ /**
65
+ * Build a translucent clone of the robot for pose previews (target pose,
66
+ * onion-skinning). Geometry is shared with the source; every mesh uses one
67
+ * ghost material and is tagged `userData.kind = "ghost"`, so the source's
68
+ * `showVisual` / `showCollision` toggles never affect it. The clone is a full
69
+ * {@link ThreeUsdRobot} — drive it with `setJointValues` — starting from the
70
+ * source's current joint values (plus `jointValues` overrides) and mirroring
71
+ * its root transform. Add it to the same parent/scene as the source.
72
+ */
73
+ declare function createGhostRobot(robot: ThreeUsdRobot, options?: GhostRobotOptions): ThreeUsdRobot;
4
74
 
5
75
  /**
6
76
  * An arrow drawn along a joint's motion axis (the rotation axis for
@@ -36,4 +106,4 @@ declare function addJointLimitHelpers(robot: ThreeUsdRobot, radius?: number, col
36
106
  /** Attach a {@link LinkFrameHelper} to every link. Returns the helpers. */
37
107
  declare function addLinkFrameHelpers(robot: ThreeUsdRobot, size?: number): LinkFrameHelper[];
38
108
 
39
- export { JointAxisHelper, JointLimitHelper, LinkFrameHelper, addJointAxisHelpers, addJointLimitHelpers, addLinkFrameHelpers };
109
+ export { type GhostRobotOptions, type HighlightLinkOptions, JointAxisHelper, JointLimitHelper, LinkFrameHelper, type LinkMeshKind, addJointAxisHelpers, addJointLimitHelpers, addLinkFrameHelpers, createGhostRobot, getLinkMeshes, highlightLink, restoreAllLinkMaterials, restoreLinkMaterials, setLinkMaterial };
package/dist/helpers.js CHANGED
@@ -1,17 +1,129 @@
1
- import * as THREE2 from 'three';
1
+ import { ThreeUsdRobot } from './chunk-FUPFJOXW.js';
2
+ import './chunk-IYKPVUZ2.js';
3
+ import * as THREE3 from 'three';
2
4
 
3
- // src/helpers/JointAxisHelper.ts
4
- var JointAxisHelper = class extends THREE2.ArrowHelper {
5
+ var savedMaterials = /* @__PURE__ */ new WeakMap();
6
+ var HIGHLIGHT_FLAG = "__threeUsdRobotHighlight";
7
+ function getLinkMeshes(robot, link, kind = "all") {
8
+ const obj = robot.getLinkObject(link);
9
+ if (!obj) return [];
10
+ const out = [];
11
+ for (const child of obj.children) {
12
+ const mesh = child;
13
+ if (!mesh.isMesh) continue;
14
+ const k = mesh.userData.kind;
15
+ if (k !== "visual" && k !== "collision") continue;
16
+ if (kind !== "all" && k !== kind) continue;
17
+ out.push(mesh);
18
+ }
19
+ return out;
20
+ }
21
+ function highlightLink(robot, link, options = {}) {
22
+ const meshes = getLinkMeshes(robot, link, options.kind ?? "visual");
23
+ if (meshes.length === 0) return false;
24
+ const color = new THREE3.Color(options.color ?? 16729156);
25
+ for (const mesh of meshes) {
26
+ if (!savedMaterials.has(mesh)) savedMaterials.set(mesh, mesh.material);
27
+ const base = savedMaterials.get(mesh);
28
+ disposeHighlightClones(mesh.material);
29
+ mesh.material = Array.isArray(base) ? base.map((m) => tintClone(m, color, options)) : tintClone(base, color, options);
30
+ }
31
+ return true;
32
+ }
33
+ function tintClone(base, color, options) {
34
+ const m = base.clone();
35
+ m.userData[HIGHLIGHT_FLAG] = true;
36
+ const std = m;
37
+ if (std.isMeshStandardMaterial) {
38
+ std.emissive.copy(color);
39
+ std.emissiveIntensity = options.emissiveIntensity ?? 0.8;
40
+ } else if ("color" in m) {
41
+ m.color.copy(color);
42
+ }
43
+ if (options.opacity !== void 0) {
44
+ m.transparent = options.opacity < 1;
45
+ m.opacity = options.opacity;
46
+ }
47
+ return m;
48
+ }
49
+ function setLinkMaterial(robot, link, material, kind = "visual") {
50
+ const meshes = getLinkMeshes(robot, link, kind);
51
+ if (meshes.length === 0) return false;
52
+ for (const mesh of meshes) {
53
+ if (!savedMaterials.has(mesh)) savedMaterials.set(mesh, mesh.material);
54
+ disposeHighlightClones(mesh.material);
55
+ mesh.material = material;
56
+ }
57
+ return true;
58
+ }
59
+ function restoreLinkMaterials(robot, link) {
60
+ for (const mesh of getLinkMeshes(robot, link, "all")) {
61
+ const original = savedMaterials.get(mesh);
62
+ if (original === void 0) continue;
63
+ disposeHighlightClones(mesh.material);
64
+ mesh.material = original;
65
+ savedMaterials.delete(mesh);
66
+ }
67
+ }
68
+ function restoreAllLinkMaterials(robot) {
69
+ for (const name of robot.getLinkNames()) restoreLinkMaterials(robot, name);
70
+ }
71
+ function disposeHighlightClones(current) {
72
+ for (const m of Array.isArray(current) ? current : [current]) {
73
+ if (m.userData[HIGHLIGHT_FLAG]) m.dispose();
74
+ }
75
+ }
76
+ function createGhostRobot(robot, options = {}) {
77
+ const ghost = new ThreeUsdRobot(robot.robot, robot.tree, {
78
+ clampJointLimits: robot.clampJointLimits,
79
+ applyInitialPose: false,
80
+ upAxisConversion: "none"
81
+ });
82
+ ghost.name = `${robot.name}_ghost`;
83
+ ghost.position.copy(robot.position);
84
+ ghost.quaternion.copy(robot.quaternion);
85
+ ghost.scale.copy(robot.scale);
86
+ const material = options.material ?? new THREE3.MeshStandardMaterial({
87
+ color: options.color ?? 6728447,
88
+ transparent: true,
89
+ opacity: options.opacity ?? 0.35,
90
+ depthWrite: false,
91
+ metalness: 0,
92
+ roughness: 1
93
+ });
94
+ const kind = options.kind ?? "visual";
95
+ for (const key of robot.getLinkNames()) {
96
+ const target = ghost.getLinkObject(key);
97
+ if (!target) continue;
98
+ for (const src of getLinkMeshes(robot, key, kind)) {
99
+ const mesh = new THREE3.Mesh(src.geometry, material);
100
+ mesh.name = `${src.name}_ghost`;
101
+ mesh.userData.kind = "ghost";
102
+ mesh.userData.primPath = src.userData.primPath;
103
+ mesh.matrixAutoUpdate = false;
104
+ mesh.matrix.copy(src.matrix);
105
+ mesh.matrixWorldNeedsUpdate = true;
106
+ target.add(mesh);
107
+ }
108
+ }
109
+ for (const name of robot.getJointNames()) {
110
+ const value = robot.getJointValue(name);
111
+ if (value !== void 0) ghost.setJointValue(name, value);
112
+ }
113
+ if (options.jointValues) ghost.setJointValues(options.jointValues);
114
+ return ghost;
115
+ }
116
+ var JointAxisHelper = class extends THREE3.ArrowHelper {
5
117
  isJointAxisHelper = true;
6
118
  constructor(joint, length = 0.2, color = 16764928) {
7
- super(joint.axis.clone().normalize(), new THREE2.Vector3(0, 0, 0), length, color);
119
+ super(joint.axis.clone().normalize(), new THREE3.Vector3(0, 0, 0), length, color);
8
120
  this.name = `${joint.jointName}:axis`;
9
121
  }
10
122
  };
11
- var JointLimitHelper = class extends THREE2.Line {
123
+ var JointLimitHelper = class extends THREE3.Line {
12
124
  isJointLimitHelper = true;
13
125
  constructor(joint, radius = 0.15, color = 43775) {
14
- super(buildLimitGeometry(joint, radius), new THREE2.LineBasicMaterial({ color }));
126
+ super(buildLimitGeometry(joint, radius), new THREE3.LineBasicMaterial({ color }));
15
127
  this.name = `${joint.jointName}:limit`;
16
128
  }
17
129
  };
@@ -20,7 +132,7 @@ function buildLimitGeometry(joint, radius) {
20
132
  if (joint.jointType === "prismatic") {
21
133
  const lo2 = joint.lower ?? -radius;
22
134
  const hi2 = joint.upper ?? radius;
23
- return new THREE2.BufferGeometry().setFromPoints([
135
+ return new THREE3.BufferGeometry().setFromPoints([
24
136
  axis.clone().multiplyScalar(lo2),
25
137
  axis.clone().multiplyScalar(hi2)
26
138
  ]);
@@ -36,15 +148,15 @@ function buildLimitGeometry(joint, radius) {
36
148
  u.clone().multiplyScalar(Math.cos(t) * radius).addScaledVector(v, Math.sin(t) * radius)
37
149
  );
38
150
  }
39
- return new THREE2.BufferGeometry().setFromPoints(points);
151
+ return new THREE3.BufferGeometry().setFromPoints(points);
40
152
  }
41
153
  function perpendicularBasis(axis) {
42
- const ref = Math.abs(axis.x) < 0.9 ? new THREE2.Vector3(1, 0, 0) : new THREE2.Vector3(0, 1, 0);
43
- const u = new THREE2.Vector3().crossVectors(axis, ref).normalize();
44
- const v = new THREE2.Vector3().crossVectors(axis, u).normalize();
154
+ const ref = Math.abs(axis.x) < 0.9 ? new THREE3.Vector3(1, 0, 0) : new THREE3.Vector3(0, 1, 0);
155
+ const u = new THREE3.Vector3().crossVectors(axis, ref).normalize();
156
+ const v = new THREE3.Vector3().crossVectors(axis, u).normalize();
45
157
  return { u, v };
46
158
  }
47
- var LinkFrameHelper = class extends THREE2.AxesHelper {
159
+ var LinkFrameHelper = class extends THREE3.AxesHelper {
48
160
  isLinkFrameHelper = true;
49
161
  constructor(size = 0.2) {
50
162
  super(size);
@@ -87,6 +199,6 @@ function addLinkFrameHelpers(robot, size) {
87
199
  return out;
88
200
  }
89
201
 
90
- export { JointAxisHelper, JointLimitHelper, LinkFrameHelper, addJointAxisHelpers, addJointLimitHelpers, addLinkFrameHelpers };
202
+ export { JointAxisHelper, JointLimitHelper, LinkFrameHelper, addJointAxisHelpers, addJointLimitHelpers, addLinkFrameHelpers, createGhostRobot, getLinkMeshes, highlightLink, restoreAllLinkMaterials, restoreLinkMaterials, setLinkMaterial };
91
203
  //# sourceMappingURL=helpers.js.map
92
204
  //# sourceMappingURL=helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/helpers/JointAxisHelper.ts","../src/helpers/JointLimitHelper.ts","../src/helpers/LinkFrameHelper.ts","../src/helpers/attach.ts"],"names":["THREE","lo","hi","THREE3"],"mappings":"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","file":"helpers.js","sourcesContent":["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,13 +1,13 @@
1
1
  import { Stage, Prim, CollisionApproximation, ExportPhysicsMaterial, RobotGeometryProvider, ExportRobotOptions, ExportMaterial, ExportMesh } from './core.js';
2
- export { ARTICULATION_ROOT_API, Attribute, COLLISION_API, ComposeOptions, CrateReader, DEFAULT_METERS_PER_UNIT, ExtractOptions, Layer, MASS_API, MESH_COLLISION_API, PACKAGE_NAME, PHYSICS_MATERIAL_API, ParseError, RIGID_BODY_API, Relationship, ResolvedXform, TextureChannel, TokenizeError, UpAxis, UsdzPackage, VERSION, ValidateRobotOptions, ValidationIssue, ValidationSeverity, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, driveKindFor, exportRobotUsda, extractRobotDescription, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, isMesh, isScope, isXform, iterDescendants, jointValueFromSI, jointValueToSI, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, serializeUsda, stageGeometryProvider, tokenize, validateRobotDescription, writeUsdz } from './core.js';
2
+ export { ARTICULATION_ROOT_API, Attribute, COLLISION_API, ComposeOptions, CrateReader, DEFAULT_METERS_PER_UNIT, ExtractOptions, Layer, MASS_API, MESH_COLLISION_API, PACKAGE_NAME, PHYSICS_MATERIAL_API, ParseError, RIGID_BODY_API, Relationship, ResolvedXform, TextureChannel, TokenizeError, UpAxis, UsdzPackage, VERSION, ValidateRobotOptions, ValidationIssue, ValidationSeverity, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, driveKindFor, exportRobotUsda, extractRobotDescription, gatherGprimDescendants, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, isMesh, isRenderableGprim, isScope, isSolidGprim, isXform, isZip, iterDescendants, jointValueFromSI, jointValueToSI, 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, R as RobotDescription, c as JointDriveDescription, d as LinkInertialDescription, K as KinematicTree, U as UsdaFile, M as Mat4 } from './buildKinematicTree-Ccd2DIKH.js';
5
- export { e as AssetPath, f as AttributeSpec, B as BuildTreeOptions, C as CompositionArc, D as DEG2RAD, a as JointDescription, J as JointType, g as KinematicNode, L as LinkDescription, h as ListOp, i as MetadataMap, P as PrimSpec, j as PropertySpec, Q as Quat, k as RAD2DEG, l as RelationshipSpec, S as SampleChannel, m as SdfPath, n as Specifier, T as TreeEdge, o as UsdDictionary, p as UsdMatrix, q as UsdValue, r as Variability, s as Vec4, t as buildKinematicTree, u as channelFromSamples, v as decomposeRigid, w as fromUsdMatrix, x as getTranslation, y as identity4, z as interpolate, E as invert, F as makeEuler, G as makeRotationFromQuat, H as makeRotationX, I as makeRotationY, N as makeRotationZ, O as makeScale, W as makeTranslation, X as multiply, Y as multiplyAll, Z as toUsdMatrix } from './buildKinematicTree-Ccd2DIKH.js';
6
- import { T as ThreeUsdRobot } from './ThreeUsdRobot-Ljh4PDVD.js';
7
- export { J as JointObject, L as LinkObject, a as ThreeUsdRobotOptions } from './ThreeUsdRobot-Ljh4PDVD.js';
8
- import { A as AssetResolver } from './AssetResolver-CpIJNgWZ.js';
9
- export { D as DefaultAssetResolver, c as createMemoryResolver, j as joinPosix } from './AssetResolver-CpIJNgWZ.js';
10
- export { a as ThreeUsdRobotLoader, T as ThreeUsdRobotLoaderOptions } from './ThreeUsdRobotLoader-BSIVFA48.js';
4
+ import { A as Axis, V as Vec2, b as Vec3, R as RobotDescription, c as JointDriveDescription, d as LinkInertialDescription, K as KinematicTree, U as UsdaFile, M as Mat4 } from './buildKinematicTree-D4R0hEtN.js';
5
+ export { e as AssetPath, f as AttributeSpec, B as BuildTreeOptions, C as CompositionArc, D as DEG2RAD, a as JointDescription, J as JointType, g as KinematicNode, L as LinkDescription, h as ListOp, i as MetadataMap, P as PrimSpec, j as PropertySpec, Q as Quat, k as RAD2DEG, l as RelationshipSpec, S as SampleChannel, m as SdfPath, n as Specifier, T as TreeEdge, o as UsdDictionary, p as UsdMatrix, q as UsdValue, r as Variability, s as Vec4, t as buildKinematicTree, u as channelFromSamples, v as decomposeRigid, w as fromUsdMatrix, x as getTranslation, y as identity4, z as interpolate, E as invert, F as makeEuler, G as makeRotationFromQuat, H as makeRotationX, I as makeRotationY, N as makeRotationZ, O as makeScale, W as makeTranslation, X as multiply, Y as multiplyAll, Z as toUsdMatrix } from './buildKinematicTree-D4R0hEtN.js';
6
+ import { T as ThreeUsdRobot } from './ThreeUsdRobot-BZ_vlr1R.js';
7
+ export { J as JointObject, L as LinkObject, a as ThreeUsdRobotOptions, W as WorldUpAxis } from './ThreeUsdRobot-BZ_vlr1R.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-HteyMZf1.js';
11
11
 
12
12
  /** Unit vector for a USD joint axis token. Returns a fresh vector each call. */
13
13
  declare function axisVector(axis: Axis): THREE.Vector3;
@@ -115,13 +115,15 @@ type TextureProvider = (assetPath: string, options?: TextureOptions) => THREE.Te
115
115
  declare function createTextureProvider(resolver: AssetResolver, baseUrl: string): TextureProvider;
116
116
 
117
117
  /**
118
- * Binds `UsdGeom.Mesh` prims to Three.js geometry and attaches them under the
119
- * robot's link objects.
118
+ * Binds renderable gprims — `UsdGeom.Mesh` plus the parametric solids (`Cube` /
119
+ * `Sphere` / `Cylinder` / `Capsule` / `Cone`) — to Three.js geometry and
120
+ * attaches them under the robot's link objects.
120
121
  *
121
- * Triangulates polygons with a simple fan, uses authored per-vertex normals
122
- * when present (else computes smooth normals), and reads `primvars:st` UVs and
123
- * `primvars:displayColor`. Geometry is left in stage units; the global
124
- * `metersPerUnit` scale is applied at the root in M9.
122
+ * Meshes are triangulated with a simple fan, use authored per-vertex normals
123
+ * when present (else computed smooth normals), and read `primvars:st` UVs and
124
+ * `primvars:displayColor`. Solids tessellate from their schema attributes.
125
+ * Geometry is left in stage units; the global `metersPerUnit` scale is applied
126
+ * at the root in M9.
125
127
  */
126
128
 
127
129
  type MeshKind = "visual" | "collision";
@@ -141,7 +143,15 @@ type BindMeshesOptions = {
141
143
  */
142
144
  declare function buildMeshGeometry(meshPrim: Prim): THREE.BufferGeometry | null;
143
145
  /**
144
- * Build a material for a Mesh prim. Color priority: bound `UsdShade` material
146
+ * Build geometry for any renderable gprim: `Mesh` via {@link buildMeshGeometry},
147
+ * parametric solids from their schema attributes. Solids follow UsdGeom
148
+ * semantics — sizes in stage units, centered at the origin, `axis` (default
149
+ * `"Z"`) along the spine, and a capsule's `height` spans only its cylindrical
150
+ * section. Returns `null` for unsupported prim types.
151
+ */
152
+ declare function buildGprimGeometry(prim: Prim): THREE.BufferGeometry | null;
153
+ /**
154
+ * Build a material for a gprim. Color priority: bound `UsdShade` material
145
155
  * (when `stage` is given) → `primvars:displayColor` → default gray. Textures
146
156
  * (via `textures`) become the matching `MeshStandardMaterial` maps — diffuse →
147
157
  * `map` (sRGB), plus `normalMap` / `roughnessMap` / `metalnessMap` / `aoMap`
@@ -158,8 +168,8 @@ bindingPrim?: Prim): THREE.Material;
158
168
  */
159
169
  declare function bindRobotMeshes(stage: Stage, robot3d: ThreeUsdRobot, desc: RobotDescription, options?: BindMeshesOptions): void;
160
170
  /**
161
- * Attach the Mesh prims that belong to no link — the static scenery of a cell
162
- * that also contains robots. They are placed by their authored stage transform
171
+ * Attach the gprims that belong to no link — the static scenery of a cell that
172
+ * also contains robots. They are placed by their authored stage transform
163
173
  * under the robot root, so the loader's up-axis and unit normalization applies
164
174
  * to them too. Collision-only and guide/proxy prims are skipped.
165
175
  */
@@ -300,4 +310,4 @@ type ExportThreeUsdRobotOptions = Omit<ExportRobotOptions, "geometry"> & {
300
310
  /** Export a loaded robot back to a USDA AST (pass the result to `serializeUsda`). */
301
311
  declare function exportThreeUsdRobot(robot: ThreeUsdRobot, options?: ExportThreeUsdRobotOptions): UsdaFile;
302
312
 
303
- export { type AddJointOptions, type AddLinkOptions, AssetResolver, Axis, type BindMeshesOptions, CollisionApproximation, ExportMaterial, ExportMesh, ExportPhysicsMaterial, ExportRobotOptions, type ExportThreeUsdRobotOptions, type GeometryToExportMeshOptions, JointDriveDescription, KinematicTree, LinkInertialDescription, Mat4, type MeshKind, Prim, 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, buildMeshGeometry, buildMeshMaterial, createTextureProvider, exportThreeUsdRobot, geometryToExportMesh, materialToExportMaterial, resolveBoundMaterial, threeGeometryProvider };
313
+ export { type AddJointOptions, type AddLinkOptions, AssetResolver, Axis, type BindMeshesOptions, CollisionApproximation, ExportMaterial, ExportMesh, ExportPhysicsMaterial, ExportRobotOptions, type ExportThreeUsdRobotOptions, type GeometryToExportMeshOptions, JointDriveDescription, KinematicTree, LinkInertialDescription, Mat4, type MeshKind, Prim, 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, buildMeshGeometry, buildMeshMaterial, createTextureProvider, exportThreeUsdRobot, geometryToExportMesh, materialToExportMaterial, resolveBoundMaterial, threeGeometryProvider };
package/dist/index.js CHANGED
@@ -1,8 +1,11 @@
1
- import { stageGeometryProvider, exportRobotUsda } from './chunk-O7XP5FQ4.js';
2
- export { PACKAGE_NAME, VERSION, exportRobotUsda, stageGeometryProvider, validateRobotDescription, writeUsdz } from './chunk-O7XP5FQ4.js';
3
- export { JointObject, LinkObject, ThreeUsdRobot, ThreeUsdRobotLoader, axisVector, bindRobotMeshes, bindSceneMeshes, buildMeshGeometry, buildMeshMaterial, createTextureProvider } from './chunk-FL554IS5.js';
4
- import { identity4, refineJointType, multiply, invert, buildKinematicTree } from './chunk-4GPCBXUS.js';
5
- export { ARTICULATION_ROOT_API, AssetPath, Attribute, COLLISION_API, CrateReader, DEFAULT_METERS_PER_UNIT, DEG2RAD, DefaultAssetResolver, Layer, MASS_API, MESH_COLLISION_API, PHYSICS_MATERIAL_API, ParseError, Prim, Quat, RAD2DEG, RIGID_BODY_API, Relationship, Stage, TokenizeError, UsdMatrix, buildKinematicTree, channelFromSamples, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, createMemoryResolver, decomposeRigid, driveKindFor, extractRobotDescription, fromUsdMatrix, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, getTranslation, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, identity4, interpolate, invert, isMesh, isScope, isXform, iterDescendants, joinPosix, jointValueFromSI, jointValueToSI, makeEuler, makeRotationFromQuat, makeRotationX, makeRotationY, makeRotationZ, makeScale, makeTranslation, multiply, multiplyAll, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, resolveBoundMaterial, serializeUsda, toUsdMatrix, tokenize } from './chunk-4GPCBXUS.js';
1
+ import { stageGeometryProvider, exportRobotUsda } from './chunk-P6CHTMGW.js';
2
+ export { PACKAGE_NAME, VERSION, exportRobotUsda, stageGeometryProvider, validateRobotDescription, writeUsdz } from './chunk-P6CHTMGW.js';
3
+ export { ThreeUsdRobotLoader, bindRobotMeshes, bindSceneMeshes, buildGprimGeometry, buildMeshGeometry, buildMeshMaterial, createTextureProvider } from './chunk-JHOX3VUW.js';
4
+ import { refineJointType, buildKinematicTree } from './chunk-PHHMWMCA.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, composeFile, composeLayer, computeLocalTransform, computeWorldTransform, crateToUsdaFile, createMemoryResolver, driveKindFor, extractRobotDescription, gatherGprimDescendants, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getMassProperties, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, isMesh, isRenderableGprim, isScope, isSolidGprim, isXform, isZip, iterDescendants, joinPosix, jointValueFromSI, jointValueToSI, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, resolveBoundMaterial, serializeUsda, toBytes, tokenize } from './chunk-PHHMWMCA.js';
6
+ export { JointObject, LinkObject, ThreeUsdRobot, axisVector } from './chunk-FUPFJOXW.js';
7
+ import { identity4, multiply, invert } from './chunk-IYKPVUZ2.js';
8
+ export { AssetPath, DEG2RAD, Quat, RAD2DEG, UsdMatrix, channelFromSamples, decomposeRigid, fromUsdMatrix, getTranslation, identity4, interpolate, invert, makeEuler, makeRotationFromQuat, makeRotationX, makeRotationY, makeRotationZ, makeScale, makeTranslation, multiply, multiplyAll, toUsdMatrix } from './chunk-IYKPVUZ2.js';
6
9
  import * as THREE from 'three';
7
10
 
8
11
  function geometryToExportMesh(geometry, options) {