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/README.md +87 -7
- package/dist/{ThreeUsdRobot-Ljh4PDVD.d.ts → ThreeUsdRobot-BZ_vlr1R.d.ts} +51 -7
- package/dist/ThreeUsdRobotLoader-HteyMZf1.d.ts +92 -0
- package/dist/{buildKinematicTree-Ccd2DIKH.d.ts → buildKinematicTree-D4R0hEtN.d.ts} +2 -2
- package/dist/{AssetResolver-CpIJNgWZ.d.ts → bytes-MOJ2oN-u.d.ts} +14 -1
- package/dist/chunk-FUPFJOXW.js +387 -0
- package/dist/chunk-FUPFJOXW.js.map +1 -0
- package/dist/chunk-IYKPVUZ2.js +406 -0
- package/dist/chunk-IYKPVUZ2.js.map +1 -0
- package/dist/{chunk-FL554IS5.js → chunk-JHOX3VUW.js} +115 -367
- package/dist/chunk-JHOX3VUW.js.map +1 -0
- package/dist/{chunk-O7XP5FQ4.js → chunk-P6CHTMGW.js} +4 -3
- package/dist/chunk-P6CHTMGW.js.map +1 -0
- package/dist/{chunk-4GPCBXUS.js → chunk-PHHMWMCA.js} +45 -410
- package/dist/chunk-PHHMWMCA.js.map +1 -0
- package/dist/core.d.ts +17 -5
- package/dist/core.js +3 -2
- package/dist/extras.d.ts +2 -2
- package/dist/helpers.d.ts +73 -3
- package/dist/helpers.js +125 -13
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts +28 -18
- package/dist/index.js +8 -5
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +4 -4
- package/dist/react.js +4 -2
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/dist/ThreeUsdRobotLoader-BSIVFA48.d.ts +0 -67
- package/dist/chunk-4GPCBXUS.js.map +0 -1
- package/dist/chunk-FL554IS5.js.map +0 -1
- package/dist/chunk-O7XP5FQ4.js.map +0 -1
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-
|
|
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-
|
|
3
|
-
import { A as AssetResolver } from './
|
|
4
|
-
export { D as DefaultAssetResolver, c as createMemoryResolver, j as joinPosix } from './
|
|
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-
|
|
2
|
-
export { ARTICULATION_ROOT_API,
|
|
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-
|
|
1
|
+
import { T as ThreeUsdRobot } from './ThreeUsdRobot-BZ_vlr1R.js';
|
|
2
2
|
import 'three';
|
|
3
|
-
import './buildKinematicTree-
|
|
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 {
|
|
3
|
-
import './buildKinematicTree-
|
|
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
|
|
1
|
+
import { ThreeUsdRobot } from './chunk-FUPFJOXW.js';
|
|
2
|
+
import './chunk-IYKPVUZ2.js';
|
|
3
|
+
import * as THREE3 from 'three';
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
var
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
151
|
+
return new THREE3.BufferGeometry().setFromPoints(points);
|
|
40
152
|
}
|
|
41
153
|
function perpendicularBasis(axis) {
|
|
42
|
-
const ref = Math.abs(axis.x) < 0.9 ? new
|
|
43
|
-
const u = new
|
|
44
|
-
const v = new
|
|
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
|
|
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
|
package/dist/helpers.js.map
CHANGED
|
@@ -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-
|
|
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-
|
|
6
|
-
import { T as ThreeUsdRobot } from './ThreeUsdRobot-
|
|
7
|
-
export { J as JointObject, L as LinkObject, a as ThreeUsdRobotOptions } from './ThreeUsdRobot-
|
|
8
|
-
import { A as AssetResolver } from './
|
|
9
|
-
export { D as DefaultAssetResolver, c as createMemoryResolver, j as joinPosix } from './
|
|
10
|
-
export { a as ThreeUsdRobotLoader, T as ThreeUsdRobotLoaderOptions } from './ThreeUsdRobotLoader-
|
|
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`
|
|
119
|
-
*
|
|
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
|
-
*
|
|
122
|
-
* when present (else
|
|
123
|
-
* `primvars:displayColor`.
|
|
124
|
-
* `metersPerUnit` scale is applied
|
|
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
|
|
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
|
|
162
|
-
*
|
|
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-
|
|
2
|
-
export { PACKAGE_NAME, VERSION, exportRobotUsda, stageGeometryProvider, validateRobotDescription, writeUsdz } from './chunk-
|
|
3
|
-
export {
|
|
4
|
-
import {
|
|
5
|
-
export { ARTICULATION_ROOT_API,
|
|
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) {
|