three-usd-robot 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/core.d.ts ADDED
@@ -0,0 +1,464 @@
1
+ import { n as UsdaFile, g as MetadataMap, m as UsdValue, P as PrimSpec, k as Specifier, j as RelationshipSpec, S as SdfPath, b as AttributeSpec, V as Variability, M as Mat4, R as RobotDescription, d as JointType, A as Axis } from './buildKinematicTree-2fg6ZN8m.js';
2
+ export { a as AssetPath, B as BuildTreeOptions, C as CompositionArc, D as DEG2RAD, J as JointDescription, c as JointDriveDescription, K as KinematicNode, e as KinematicTree, L as LinkDescription, f as ListOp, h as PropertySpec, Q as Quat, i as RAD2DEG, T as TreeEdge, U as UsdDictionary, l as UsdMatrix, o as Vec2, p as Vec3, q as Vec4, r as buildKinematicTree, s as fromUsdMatrix, t as getTranslation, u as identity4, v as invert, w as makeEuler, x as makeRotationFromQuat, y as makeRotationX, z as makeRotationY, E as makeRotationZ, F as makeScale, G as makeTranslation, H as multiply, I as multiplyAll } from './buildKinematicTree-2fg6ZN8m.js';
3
+
4
+ /** Package identity. Kept in one place so every entry point can re-export it. */
5
+ declare const PACKAGE_NAME = "three-usd-robot";
6
+ /** Library version. Replaced by the release tooling at publish time. */
7
+ declare const VERSION = "0.0.0";
8
+
9
+ /**
10
+ * Recursive-descent parser for the USDA (ASCII USD) format.
11
+ *
12
+ * Scope (M1): prims (`def`/`over`/`class`), nested prims, attributes
13
+ * (`uniform`/`custom`/array/connections/time samples), relationships (with
14
+ * list-op qualifiers), and layer/prim/property metadata blocks. References,
15
+ * payloads and variant sets are tolerated as metadata but not resolved (M8/M10).
16
+ */
17
+
18
+ declare function parseUsda(text: string): UsdaFile;
19
+
20
+ /**
21
+ * Tokenizer for the USDA (ASCII USD) format.
22
+ *
23
+ * Produces a flat token stream consumed by `parseUsda`. Comments (`#...`) are
24
+ * stripped. Paths (`<...>`) and asset paths (`@...@` / `@@@...@@@`) are scanned
25
+ * as whole tokens because their interior characters are otherwise significant.
26
+ */
27
+ type TokenType = "lbrace" | "rbrace" | "lparen" | "rparen" | "lbracket" | "rbracket" | "equals" | "comma" | "colon" | "dot" | "number" | "string" | "ident" | "path" | "asset" | "eof";
28
+ type Token = {
29
+ type: TokenType;
30
+ /** Raw lexeme / decoded value. For `number` this is the original text. */
31
+ value: string;
32
+ /** Decoded numeric value for `number` tokens. */
33
+ num?: number;
34
+ /** 1-based line number where the token starts. */
35
+ line: number;
36
+ col: number;
37
+ };
38
+ declare class TokenizeError extends Error {
39
+ readonly line: number;
40
+ readonly col: number;
41
+ constructor(message: string, line: number, col: number);
42
+ }
43
+ declare function tokenize(src: string): Token[];
44
+
45
+ declare class ParseError extends Error {
46
+ readonly line: number;
47
+ readonly col: number;
48
+ constructor(message: string, line: number, col: number);
49
+ }
50
+
51
+ /** A parsed USDA layer (`SdfLayer`-like, read-only). */
52
+ declare class Layer {
53
+ private readonly _file;
54
+ constructor(_file: UsdaFile);
55
+ GetVersion(): string;
56
+ GetPseudoRootMetadata(): MetadataMap;
57
+ GetMetadata(key: string): UsdValue | undefined;
58
+ GetDefaultPrimName(): string | undefined;
59
+ GetRootPrimSpecs(): PrimSpec[];
60
+ }
61
+
62
+ /** OpenUSD's fallback stage linear unit when `metersPerUnit` is unauthored. */
63
+ declare const DEFAULT_METERS_PER_UNIT = 0.01;
64
+ type UpAxis = "Y" | "Z";
65
+ /**
66
+ * A composed USD stage (`UsdStage`-like) backed by a single in-memory USDA
67
+ * layer. Multi-layer composition (sublayers / references / payloads) arrives in
68
+ * M8; for now a stage wraps exactly one parsed layer.
69
+ */
70
+ declare class Stage {
71
+ private readonly _layer;
72
+ private readonly _byPath;
73
+ private readonly _pseudoRoot;
74
+ private constructor();
75
+ /** Parse and open a stage from USDA source text. */
76
+ static OpenFromString(usda: string): Stage;
77
+ /** Open a stage from an already-parsed layer. */
78
+ static OpenFromFile(file: UsdaFile): Stage;
79
+ private buildPrim;
80
+ GetRootLayer(): Layer;
81
+ GetPseudoRoot(): Prim;
82
+ /** Returns the prim at the absolute path, or `null` if none exists. */
83
+ GetPrimAtPath(path: string): Prim | null;
84
+ /** The stage's default prim (from layer `defaultPrim` metadata), if any. */
85
+ GetDefaultPrim(): Prim | null;
86
+ /** Depth-first traversal of all prims (excludes the pseudo-root). */
87
+ Traverse(): Prim[];
88
+ GetMetadata(key: string): UsdValue | undefined;
89
+ /** Stage up axis (`upAxis` metadata); defaults to `"Y"` per OpenUSD. */
90
+ GetUpAxis(): UpAxis;
91
+ /** Stage linear unit (`metersPerUnit` metadata); defaults to {@link DEFAULT_METERS_PER_UNIT}. */
92
+ GetMetersPerUnit(): number;
93
+ }
94
+
95
+ /**
96
+ * A composed prim on a {@link Stage} (`UsdPrim`-like).
97
+ *
98
+ * The pseudo-root (path `/`) is represented by a Prim with a `null` spec; its
99
+ * children are the stage's root prims.
100
+ */
101
+ declare class Prim {
102
+ private readonly _stage;
103
+ private readonly _spec;
104
+ private readonly _path;
105
+ private readonly _parent;
106
+ private readonly _children;
107
+ private _attributes?;
108
+ private _relationships?;
109
+ constructor(_stage: Stage, _spec: PrimSpec | null, _path: string, _parent: Prim | null);
110
+ /** @internal Used by {@link Stage} while building the prim tree. */
111
+ _addChild(child: Prim): void;
112
+ GetStage(): Stage;
113
+ IsValid(): boolean;
114
+ IsPseudoRoot(): boolean;
115
+ GetName(): string;
116
+ GetPath(): string;
117
+ GetTypeName(): string;
118
+ GetSpecifier(): Specifier | null;
119
+ GetParent(): Prim | null;
120
+ GetChildren(): Prim[];
121
+ GetChild(name: string): Prim | null;
122
+ private attrMap;
123
+ /** Always returns an Attribute; check {@link Attribute.IsValid}. */
124
+ GetAttribute(name: string): Attribute;
125
+ HasAttribute(name: string): boolean;
126
+ GetAttributes(): Attribute[];
127
+ private relMap;
128
+ /** Always returns a Relationship; check {@link Relationship.IsValid}. */
129
+ GetRelationship(name: string): Relationship;
130
+ HasRelationship(name: string): boolean;
131
+ GetRelationships(): Relationship[];
132
+ GetMetadata(key: string): UsdValue | undefined;
133
+ GetAllMetadata(): MetadataMap;
134
+ /** Applied API schema names from `apiSchemas` (e.g. `PhysicsArticulationRootAPI`). */
135
+ GetAppliedSchemas(): string[];
136
+ /**
137
+ * Whether the given API schema is applied. Matches the bare schema name as
138
+ * well as multi-apply instances (e.g. `HasAPI("PhysicsDriveAPI")` is true for
139
+ * an applied `PhysicsDriveAPI:angular`).
140
+ */
141
+ HasAPI(schemaName: string): boolean;
142
+ }
143
+
144
+ /**
145
+ * A typed attribute on a prim (`UsdAttribute`-like).
146
+ *
147
+ * Mirrors the pxr USD API: `GetAttribute` always returns an `Attribute` object;
148
+ * call {@link Attribute.IsValid} to check whether the attribute is actually
149
+ * authored on the prim.
150
+ */
151
+ declare class Attribute {
152
+ private readonly _prim;
153
+ private readonly _name;
154
+ private readonly _spec;
155
+ constructor(_prim: Prim, _name: string, _spec: AttributeSpec | null);
156
+ IsValid(): boolean;
157
+ GetPrim(): Prim;
158
+ GetName(): string;
159
+ GetBaseName(): string;
160
+ GetNamespace(): string;
161
+ /** Scalar type name (without the `[]` suffix); pair with {@link IsArray}. */
162
+ GetTypeName(): string;
163
+ IsArray(): boolean;
164
+ GetVariability(): Variability;
165
+ IsCustom(): boolean;
166
+ /** True if a default value or any time sample is authored. */
167
+ HasValue(): boolean;
168
+ HasAuthoredValue(): boolean;
169
+ /**
170
+ * Resolve the attribute value. With no `time`, returns the default value (or
171
+ * the earliest time sample if only samples are authored). With a `time`,
172
+ * returns the exact sample if present, else the default, else the earliest
173
+ * sample. Returns `undefined` when nothing is authored.
174
+ */
175
+ Get(time?: number): UsdValue | undefined;
176
+ GetTimeSamples(): Map<number, UsdValue>;
177
+ GetConnections(): SdfPath[];
178
+ }
179
+ /** A relationship on a prim (`UsdRelationship`-like). */
180
+ declare class Relationship {
181
+ private readonly _prim;
182
+ private readonly _name;
183
+ private readonly _spec;
184
+ constructor(_prim: Prim, _name: string, _spec: RelationshipSpec | null);
185
+ IsValid(): boolean;
186
+ GetPrim(): Prim;
187
+ GetName(): string;
188
+ GetBaseName(): string;
189
+ GetNamespace(): string;
190
+ IsCustom(): boolean;
191
+ GetTargets(): SdfPath[];
192
+ }
193
+
194
+ /**
195
+ * Resolves USD asset paths (from references / payloads / sublayers) to URLs and
196
+ * fetches their text. Composition (`composition.ts`) is I/O-agnostic and goes
197
+ * through an {@link AssetResolver}, so the same engine works in the browser, in
198
+ * Node, or against an in-memory file map in tests.
199
+ */
200
+ interface AssetResolver {
201
+ /** Resolve an authored asset path against the layer's base URL to an absolute key. */
202
+ resolve(assetPath: string, baseUrl: string): string;
203
+ /** Fetch the text of a resolved asset; rejects if it cannot be read. */
204
+ fetchText(url: string): Promise<string>;
205
+ /** Fetch the raw bytes of a resolved asset (for binary USDC / USDZ). Optional. */
206
+ fetchBytes?(url: string): Promise<Uint8Array>;
207
+ }
208
+ /** URL-based resolver using the global `fetch` (browser / Node 18+). */
209
+ declare class DefaultAssetResolver implements AssetResolver {
210
+ resolve(assetPath: string, baseUrl: string): string;
211
+ fetchText(url: string): Promise<string>;
212
+ fetchBytes(url: string): Promise<Uint8Array>;
213
+ }
214
+ /** Resolver over an in-memory `{ path: contents }` map, with posix-style joins. */
215
+ declare function createMemoryResolver(files: Record<string, string>): AssetResolver;
216
+ /** Resolve `rel` against `baseUrl` using posix semantics, normalizing `.`/`..`. */
217
+ declare function joinPosix(baseUrl: string, rel: string): string;
218
+
219
+ /**
220
+ * Minimal USD composition: flattens references, payloads and sublayers into a
221
+ * single {@link UsdaFile} so the rest of the pipeline keeps working on one layer.
222
+ *
223
+ * Scope (M8): the arcs robots actually use. References and payloads pull a prim
224
+ * subtree from another asset (weaker than local opinions); sublayers overlay a
225
+ * weaker layer stack. Inherits / variants / specializes are out of scope (M10).
226
+ * This is not a full LIVRPS implementation — it is a pragmatic flattener.
227
+ */
228
+
229
+ type ComposeOptions = {
230
+ onWarn?: (message: string) => void;
231
+ /** Guard against pathological recursion (default 64). */
232
+ maxDepth?: number;
233
+ };
234
+ /**
235
+ * Parse and fully compose a layer: resolve its sublayers and every prim's
236
+ * references/payloads (recursively), returning a flattened layer. Unresolvable
237
+ * arcs are reported via `onWarn` and skipped.
238
+ */
239
+ declare function composeLayer(text: string, baseUrl: string, resolver: AssetResolver, options?: ComposeOptions, stack?: ReadonlySet<string>): Promise<UsdaFile>;
240
+
241
+ /**
242
+ * USDZ (zipped USD package) support.
243
+ *
244
+ * A `.usdz` is an uncompressed zip whose entries are USD layers + textures.
245
+ * {@link openUsdz} unzips it (via `fflate`) and returns the root layer entry
246
+ * plus an {@link AssetResolver} that serves the package's other entries, so
247
+ * references inside the package resolve through the normal composition path.
248
+ * USDC (binary crate) entries are not decodable yet (M10).
249
+ */
250
+
251
+ type UsdzPackage = {
252
+ /** Archive path of the root layer to open. */
253
+ rootEntry: string;
254
+ /** Resolver over the package's entries. */
255
+ resolver: AssetResolver;
256
+ };
257
+ /** Unzip a `.usdz` package and build a resolver over its entries. */
258
+ declare function openUsdz(bytes: Uint8Array): UsdzPackage;
259
+
260
+ /**
261
+ * Reader for the OpenUSD binary "crate" format (`.usdc` / binary `.usd`).
262
+ *
263
+ * Built incrementally (M10): bootstrap header + table of contents + the TOKENS
264
+ * section first; STRINGS/FIELDS/FIELDSETS/PATHS/SPECS and value reps follow.
265
+ * References pxr `Usd/crateFile.cpp`. This is a from-scratch TS reader — not a
266
+ * binding to OpenUSD.
267
+ */
268
+
269
+ type CrateSection = {
270
+ name: string;
271
+ start: number;
272
+ size: number;
273
+ };
274
+ type CrateField = {
275
+ /** Field name (token index). */
276
+ nameIndex: number;
277
+ /** Packed `ValueRep` (decoded in M10c). */
278
+ rep: bigint;
279
+ };
280
+ type CrateSpec = {
281
+ pathIndex: number;
282
+ fieldSetIndex: number;
283
+ specType: number;
284
+ };
285
+ declare class CrateReader {
286
+ readonly version: readonly [number, number, number];
287
+ readonly view: DataView;
288
+ private readonly bytes;
289
+ private readonly sections;
290
+ private _tokens?;
291
+ private _strings?;
292
+ private _fields?;
293
+ private _fieldSets?;
294
+ private _paths?;
295
+ private _specs?;
296
+ constructor(bytes: Uint8Array);
297
+ /** True if `bytes` begins with the crate magic. */
298
+ static isCrate(bytes: Uint8Array): boolean;
299
+ getSection(name: string): CrateSection | undefined;
300
+ /** Read a little-endian uint64 as a JS number (safe for crate-sized files). */
301
+ u64(offset: number): number;
302
+ i64(offset: number): bigint;
303
+ private readToc;
304
+ getTokens(): string[];
305
+ getToken(index: number): string;
306
+ private readTokens;
307
+ /** String values are token indices. */
308
+ getStrings(): number[];
309
+ private readStrings;
310
+ /** Read a `TfFastCompression`-wrapped, delta+integer-compressed array of `count` ints. */
311
+ private readCompressedInts;
312
+ getFields(): CrateField[];
313
+ private readFields;
314
+ getFieldSets(): number[];
315
+ private readFieldSets;
316
+ /** The field indices of the field set starting at `index` (until the sentinel). */
317
+ getFieldSet(index: number): number[];
318
+ getPaths(): string[];
319
+ private readPaths;
320
+ /** Reconstruct path strings from the compressed path tree (pxr `_BuildDecompressedPathsImpl`). */
321
+ private buildPaths;
322
+ getSpecs(): CrateSpec[];
323
+ private readSpecs;
324
+ /** Decode a `ValueRep` into a {@link UsdValue} (or `undefined` if unsupported). */
325
+ getValue(rep: bigint): UsdValue | undefined;
326
+ private readInlined;
327
+ private readScalar;
328
+ private readArray;
329
+ private readFloat32s;
330
+ private readFloat64s;
331
+ private readVec3fArray;
332
+ /** Read a `[u64 count][count × uint32|int32 index]` vector → resolved strings. */
333
+ private readIndexVector;
334
+ /** Read an SdfListOp; returns the effective (explicit ∪ prepended ∪ added ∪ appended) items. */
335
+ private readListOp;
336
+ }
337
+
338
+ /**
339
+ * Bridges a parsed crate ({@link CrateReader}) into the in-memory {@link UsdaFile}
340
+ * AST, so the rest of the pipeline (Stage / composition / extractor / runtime)
341
+ * works on binary `.usd` exactly like ASCII `.usda`.
342
+ */
343
+
344
+ declare function crateToUsdaFile(crate: CrateReader): UsdaFile;
345
+
346
+ /**
347
+ * Resolves a prim's `xformOpOrder` into a single local transform matrix.
348
+ *
349
+ * Supports `translate`, `scale`, `orient` (quat), `transform` (matrix4d),
350
+ * single-axis `rotateX|Y|Z`, and the six `rotate<ORDER>` Euler ops, plus the
351
+ * `!invert!` op prefix and the `!resetXformStack!` sentinel. Rotation op values
352
+ * are in degrees and converted to radians here.
353
+ */
354
+
355
+ type ResolvedXform = {
356
+ /** Local-to-parent transform (column-major {@link Mat4}). */
357
+ matrix: Mat4;
358
+ /**
359
+ * True if `xformOpOrder` began with `!resetXformStack!`, meaning this prim
360
+ * does not inherit its parent's transform. Honored by FK in M5.
361
+ */
362
+ resetsXformStack: boolean;
363
+ };
364
+ /**
365
+ * Compute a prim's local transform from its `xformOpOrder`. Returns identity
366
+ * when the prim authors no `xformOpOrder`.
367
+ */
368
+ declare function computeLocalTransform(prim: Prim): ResolvedXform;
369
+ /** Extract the op type token from an op attribute name (`xformOp:translate:pivot` → `translate`). */
370
+ declare function parseOpType(opName: string): string;
371
+
372
+ /**
373
+ * Extracts a {@link RobotDescription} from a USD {@link Stage}.
374
+ *
375
+ * Collects links (rigid bodies / joint-referenced prims) and the
376
+ * Fixed/Revolute/Prismatic joints connecting them, resolves `body0`/`body1` to
377
+ * link keys, and normalizes limits to SI. The authoritative root link and
378
+ * closed-loop detection come from {@link buildKinematicTree} (M4), whose result
379
+ * is written back into `rootLink` / `loopJoints`.
380
+ */
381
+
382
+ type ExtractOptions = {
383
+ /** Override the robot name (defaults to the stage default prim or first root prim). */
384
+ robotName?: string;
385
+ /** Receives non-fatal diagnostics; also collected into `RobotDescription.warnings`. */
386
+ onWarn?: (message: string) => void;
387
+ };
388
+ declare function extractRobotDescription(stage: Stage, options?: ExtractOptions): RobotDescription;
389
+
390
+ /** SI normalization for joint values. */
391
+
392
+ /**
393
+ * Normalize raw joint limits to SI: revolute/continuous degrees → radians;
394
+ * prismatic kept in stage linear units (global metersPerUnit scaling is applied
395
+ * at the root in M9). Non-finite or unauthored limits become `undefined`.
396
+ */
397
+ declare function normalizeJointLimits(type: JointType, rawLower: number | undefined, rawUpper: number | undefined): {
398
+ lower?: number;
399
+ upper?: number;
400
+ };
401
+ /** Convert an authored joint value to SI (angular degrees → radians). */
402
+ declare function jointValueToSI(angular: boolean, raw: number): number;
403
+ /**
404
+ * A revolute joint with no finite limits is a continuous (unbounded) joint.
405
+ * Returns the refined joint type.
406
+ */
407
+ declare function refineJointType(base: JointType, lower: number | undefined, upper: number | undefined): JointType;
408
+
409
+ /** UsdGeom schema helpers (type checks and geometry gathering). */
410
+
411
+ declare function isXform(prim: Prim): boolean;
412
+ declare function isScope(prim: Prim): boolean;
413
+ declare function isMesh(prim: Prim): boolean;
414
+ /** Depth-first iterator over all descendant prims (excluding `prim` itself). */
415
+ declare function iterDescendants(prim: Prim): Generator<Prim>;
416
+ /** Collect the prim paths of all Mesh descendants of a link prim. */
417
+ declare function gatherMeshDescendants(prim: Prim): string[];
418
+
419
+ /**
420
+ * UsdPhysics schema helpers for robot extraction.
421
+ *
422
+ * Reads the joint/body attributes that matter for kinematics. Values are
423
+ * returned as authored (degrees for revolute limits, stage units for lengths);
424
+ * SI normalization happens in `robot/normalize.ts`.
425
+ */
426
+
427
+ declare const ARTICULATION_ROOT_API = "PhysicsArticulationRootAPI";
428
+ declare const RIGID_BODY_API = "PhysicsRigidBodyAPI";
429
+ declare const COLLISION_API = "PhysicsCollisionAPI";
430
+ /** Base joint type from the prim's schema type, or `null` if not a joint. */
431
+ declare function getJointType(prim: Prim): JointType | null;
432
+ /** Resolve `physics:body0` / `physics:body1` target paths (first target each). */
433
+ declare function getJointBodies(prim: Prim): {
434
+ body0?: SdfPath;
435
+ body1?: SdfPath;
436
+ };
437
+ /** Joint axis token (`physics:axis`); defaults to `"X"` per UsdPhysics. */
438
+ declare function getJointAxis(prim: Prim): Axis;
439
+ /** Raw joint limits as authored (degrees for revolute; `undefined` if unauthored). */
440
+ declare function getJointLimits(prim: Prim): {
441
+ lower?: number;
442
+ upper?: number;
443
+ };
444
+ /**
445
+ * The joint frame relative to body `index` (0 or 1), as a column-major matrix
446
+ * `T(localPos) · R(localRot)`. Missing components default to identity.
447
+ */
448
+ declare function getJointLocalFrame(prim: Prim, index: 0 | 1): Mat4;
449
+ declare function hasArticulationRootAPI(prim: Prim): boolean;
450
+ declare function hasRigidBodyAPI(prim: Prim): boolean;
451
+ declare function hasCollisionAPI(prim: Prim): boolean;
452
+ /** Drive instance name for a joint type (`angular` for revolute, `linear` otherwise). */
453
+ declare function driveKindFor(type: JointType): "angular" | "linear";
454
+ /** Read `UsdPhysicsDriveAPI` parameters for the given instance, as authored. */
455
+ declare function getJointDrive(prim: Prim, kind: "angular" | "linear"): {
456
+ targetPosition?: number;
457
+ stiffness?: number;
458
+ damping?: number;
459
+ maxForce?: number;
460
+ };
461
+ /** Read `PhysicsJointStateAPI` position for the given instance, as authored. */
462
+ declare function getJointStatePosition(prim: Prim, kind: "angular" | "linear"): number | undefined;
463
+
464
+ export { ARTICULATION_ROOT_API, type AssetResolver, Attribute, AttributeSpec, Axis, COLLISION_API, type ComposeOptions, CrateReader, DEFAULT_METERS_PER_UNIT, DefaultAssetResolver, type ExtractOptions, JointType, Layer, Mat4, MetadataMap, PACKAGE_NAME, ParseError, Prim, PrimSpec, RIGID_BODY_API, Relationship, RelationshipSpec, type ResolvedXform, RobotDescription, SdfPath, Specifier, Stage, TokenizeError, type UpAxis, UsdValue, UsdaFile, type UsdzPackage, VERSION, Variability, composeLayer, computeLocalTransform, crateToUsdaFile, createMemoryResolver, driveKindFor, extractRobotDescription, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, isMesh, isScope, isXform, iterDescendants, joinPosix, jointValueToSI, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, tokenize };
package/dist/core.js ADDED
@@ -0,0 +1,3 @@
1
+ export { ARTICULATION_ROOT_API, AssetPath, Attribute, COLLISION_API, CrateReader, DEFAULT_METERS_PER_UNIT, DEG2RAD, DefaultAssetResolver, Layer, PACKAGE_NAME, ParseError, Prim, Quat, RAD2DEG, RIGID_BODY_API, Relationship, Stage, TokenizeError, UsdMatrix, VERSION, buildKinematicTree, composeLayer, computeLocalTransform, crateToUsdaFile, createMemoryResolver, driveKindFor, extractRobotDescription, fromUsdMatrix, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getTranslation, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, identity4, invert, isMesh, isScope, isXform, iterDescendants, joinPosix, jointValueToSI, makeEuler, makeRotationFromQuat, makeRotationX, makeRotationY, makeRotationZ, makeScale, makeTranslation, multiply, multiplyAll, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, tokenize } from './chunk-XCP5GZPY.js';
2
+ //# sourceMappingURL=core.js.map
3
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"core.js"}
@@ -0,0 +1,50 @@
1
+ import { T as ThreeUsdRobot } from './ThreeUsdRobot-lMZHW-it.js';
2
+ import 'three';
3
+ import './buildKinematicTree-2fg6ZN8m.js';
4
+
5
+ /**
6
+ * `three-usd-robot/extras`
7
+ *
8
+ * Heavier convenience utilities kept out of the main bundle. Currently a
9
+ * `lil-gui` joint slider panel — but this module does **not** depend on
10
+ * `lil-gui`: the caller passes in a GUI instance (typed structurally), so no UI
11
+ * library leaks into the bundle.
12
+ */
13
+
14
+ /** Minimal structural view of a `lil-gui` controller (only what we use). */
15
+ interface GuiController {
16
+ name(name: string): GuiController;
17
+ onChange(callback: (value: number) => void): GuiController;
18
+ updateDisplay?(): GuiController;
19
+ }
20
+ /** Minimal structural view of a `lil-gui` GUI / folder. */
21
+ interface GuiLike {
22
+ add(target: Record<string, number>, key: string, min?: number, max?: number, step?: number): GuiController;
23
+ }
24
+ type JointSliderPanelOptions = {
25
+ /** Half-range used when a revolute joint has no limits (radians, default π). */
26
+ defaultAngularRange?: number;
27
+ /** Half-range used when a prismatic joint has no limits (default `1`). */
28
+ defaultLinearRange?: number;
29
+ /** Slider step (default `0.01`). */
30
+ step?: number;
31
+ };
32
+ type JointSliderPanel = {
33
+ controllers: GuiController[];
34
+ /** Re-read joint values from the robot into the sliders. */
35
+ update(): void;
36
+ };
37
+ /**
38
+ * Add one slider per articulated joint to a `lil-gui` GUI (or folder). Moving a
39
+ * slider drives the robot and refreshes its kinematics.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * import GUI from "lil-gui";
44
+ * import { createJointSliderPanel } from "three-usd-robot/extras";
45
+ * createJointSliderPanel(robot, new GUI());
46
+ * ```
47
+ */
48
+ declare function createJointSliderPanel(robot: ThreeUsdRobot, gui: GuiLike, options?: JointSliderPanelOptions): JointSliderPanel;
49
+
50
+ export { type GuiController, type GuiLike, type JointSliderPanel, type JointSliderPanelOptions, createJointSliderPanel };
package/dist/extras.js ADDED
@@ -0,0 +1,35 @@
1
+ // src/extras.ts
2
+ function createJointSliderPanel(robot, gui, options = {}) {
3
+ const angular = options.defaultAngularRange ?? Math.PI;
4
+ const linear = options.defaultLinearRange ?? 1;
5
+ const step = options.step ?? 0.01;
6
+ const state = {};
7
+ const controllers = [];
8
+ for (const name of robot.getJointNames()) {
9
+ const joint = robot.getJointObject(name);
10
+ if (!joint?.articulated) continue;
11
+ const fallback = joint.jointType === "prismatic" ? linear : angular;
12
+ const lo = joint.lower ?? -fallback;
13
+ const hi = joint.upper ?? fallback;
14
+ state[name] = joint.value;
15
+ const controller = gui.add(state, name, lo, hi, step).name(name).onChange((value) => {
16
+ robot.setJointValue(name, value);
17
+ robot.updateKinematics();
18
+ });
19
+ controllers.push(controller);
20
+ }
21
+ return {
22
+ controllers,
23
+ update() {
24
+ for (const name of Object.keys(state)) {
25
+ const value = robot.getJointValue(name);
26
+ if (value !== void 0) state[name] = value;
27
+ }
28
+ for (const c of controllers) c.updateDisplay?.();
29
+ }
30
+ };
31
+ }
32
+
33
+ export { createJointSliderPanel };
34
+ //# sourceMappingURL=extras.js.map
35
+ //# sourceMappingURL=extras.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/extras.ts"],"names":[],"mappings":";AAuDO,SAAS,sBAAA,CACd,KAAA,EACA,GAAA,EACA,OAAA,GAAmC,EAAC,EAClB;AAClB,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,mBAAA,IAAuB,IAAA,CAAK,EAAA;AACpD,EAAA,MAAM,MAAA,GAAS,QAAQ,kBAAA,IAAsB,CAAA;AAC7C,EAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,IAAQ,IAAA;AAE7B,EAAA,MAAM,QAAgC,EAAC;AACvC,EAAA,MAAM,cAA+B,EAAC;AAEtC,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,aAAA,EAAc,EAAG;AACxC,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,cAAA,CAAe,IAAI,CAAA;AACvC,IAAA,IAAI,CAAC,OAAO,WAAA,EAAa;AAEzB,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,SAAA,KAAc,WAAA,GAAc,MAAA,GAAS,OAAA;AAC5D,IAAA,MAAM,EAAA,GAAK,KAAA,CAAM,KAAA,IAAS,CAAC,QAAA;AAC3B,IAAA,MAAM,EAAA,GAAK,MAAM,KAAA,IAAS,QAAA;AAE1B,IAAA,KAAA,CAAM,IAAI,IAAI,KAAA,CAAM,KAAA;AACpB,IAAA,MAAM,UAAA,GAAa,GAAA,CAChB,GAAA,CAAI,KAAA,EAAO,MAAM,EAAA,EAAI,EAAA,EAAI,IAAI,CAAA,CAC7B,IAAA,CAAK,IAAI,CAAA,CACT,QAAA,CAAS,CAAC,KAAA,KAAU;AACnB,MAAA,KAAA,CAAM,aAAA,CAAc,MAAM,KAAK,CAAA;AAC/B,MAAA,KAAA,CAAM,gBAAA,EAAiB;AAAA,IACzB,CAAC,CAAA;AACH,IAAA,WAAA,CAAY,KAAK,UAAU,CAAA;AAAA,EAC7B;AAEA,EAAA,OAAO;AAAA,IACL,WAAA;AAAA,IACA,MAAA,GAAS;AACP,MAAA,KAAA,MAAW,IAAA,IAAQ,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,EAAG;AACrC,QAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,aAAA,CAAc,IAAI,CAAA;AACtC,QAAA,IAAI,KAAA,KAAU,MAAA,EAAW,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA;AAAA,MACzC;AACA,MAAA,KAAA,MAAW,CAAA,IAAK,WAAA,EAAa,CAAA,CAAE,aAAA,IAAgB;AAAA,IACjD;AAAA,GACF;AACF","file":"extras.js","sourcesContent":["/**\n * `three-usd-robot/extras`\n *\n * Heavier convenience utilities kept out of the main bundle. Currently a\n * `lil-gui` joint slider panel — but this module does **not** depend on\n * `lil-gui`: the caller passes in a GUI instance (typed structurally), so no UI\n * library leaks into the bundle.\n */\n\nimport type { ThreeUsdRobot } from \"./three/ThreeUsdRobot.js\";\n\n/** Minimal structural view of a `lil-gui` controller (only what we use). */\nexport interface GuiController {\n name(name: string): GuiController;\n onChange(callback: (value: number) => void): GuiController;\n updateDisplay?(): GuiController;\n}\n\n/** Minimal structural view of a `lil-gui` GUI / folder. */\nexport interface GuiLike {\n add(\n target: Record<string, number>,\n key: string,\n min?: number,\n max?: number,\n step?: number,\n ): GuiController;\n}\n\nexport type JointSliderPanelOptions = {\n /** Half-range used when a revolute joint has no limits (radians, default π). */\n defaultAngularRange?: number;\n /** Half-range used when a prismatic joint has no limits (default `1`). */\n defaultLinearRange?: number;\n /** Slider step (default `0.01`). */\n step?: number;\n};\n\nexport type JointSliderPanel = {\n controllers: GuiController[];\n /** Re-read joint values from the robot into the sliders. */\n update(): void;\n};\n\n/**\n * Add one slider per articulated joint to a `lil-gui` GUI (or folder). Moving a\n * slider drives the robot and refreshes its kinematics.\n *\n * @example\n * ```ts\n * import GUI from \"lil-gui\";\n * import { createJointSliderPanel } from \"three-usd-robot/extras\";\n * createJointSliderPanel(robot, new GUI());\n * ```\n */\nexport function createJointSliderPanel(\n robot: ThreeUsdRobot,\n gui: GuiLike,\n options: JointSliderPanelOptions = {},\n): JointSliderPanel {\n const angular = options.defaultAngularRange ?? Math.PI;\n const linear = options.defaultLinearRange ?? 1;\n const step = options.step ?? 0.01;\n\n const state: Record<string, number> = {};\n const controllers: GuiController[] = [];\n\n for (const name of robot.getJointNames()) {\n const joint = robot.getJointObject(name);\n if (!joint?.articulated) continue;\n\n const fallback = joint.jointType === \"prismatic\" ? linear : angular;\n const lo = joint.lower ?? -fallback;\n const hi = joint.upper ?? fallback;\n\n state[name] = joint.value;\n const controller = gui\n .add(state, name, lo, hi, step)\n .name(name)\n .onChange((value) => {\n robot.setJointValue(name, value);\n robot.updateKinematics();\n });\n controllers.push(controller);\n }\n\n return {\n controllers,\n update() {\n for (const name of Object.keys(state)) {\n const value = robot.getJointValue(name);\n if (value !== undefined) state[name] = value;\n }\n for (const c of controllers) c.updateDisplay?.();\n },\n };\n}\n"]}
@@ -0,0 +1,39 @@
1
+ import * as THREE from 'three';
2
+ import { J as JointObject, T as ThreeUsdRobot } from './ThreeUsdRobot-lMZHW-it.js';
3
+ import './buildKinematicTree-2fg6ZN8m.js';
4
+
5
+ /**
6
+ * An arrow drawn along a joint's motion axis (the rotation axis for
7
+ * revolute/continuous joints, the slide direction for prismatic). Add it to the
8
+ * joint's motion node so it tracks the joint.
9
+ */
10
+ declare class JointAxisHelper extends THREE.ArrowHelper {
11
+ readonly isJointAxisHelper = true;
12
+ constructor(joint: JointObject, length?: number, color?: THREE.ColorRepresentation);
13
+ }
14
+
15
+ /**
16
+ * Visualizes a joint's range of motion: an arc swept between the lower and
17
+ * upper limits (revolute/continuous) or a line segment between them
18
+ * (prismatic). A limitless revolute joint draws a full circle. Add it to the
19
+ * joint's motion node's parent frame (or the joint node) to anchor it.
20
+ */
21
+ declare class JointLimitHelper extends THREE.Line {
22
+ readonly isJointLimitHelper = true;
23
+ constructor(joint: JointObject, radius?: number, color?: THREE.ColorRepresentation);
24
+ }
25
+
26
+ /** A small RGB axes gizmo for a link's local frame. Add it to a `LinkObject`. */
27
+ declare class LinkFrameHelper extends THREE.AxesHelper {
28
+ readonly isLinkFrameHelper = true;
29
+ constructor(size?: number);
30
+ }
31
+
32
+ /** Attach a {@link JointAxisHelper} to every articulated joint. Returns the helpers. */
33
+ declare function addJointAxisHelpers(robot: ThreeUsdRobot, length?: number, color?: THREE.ColorRepresentation): JointAxisHelper[];
34
+ /** Attach a {@link JointLimitHelper} to every articulated joint. Returns the helpers. */
35
+ declare function addJointLimitHelpers(robot: ThreeUsdRobot, radius?: number, color?: THREE.ColorRepresentation): JointLimitHelper[];
36
+ /** Attach a {@link LinkFrameHelper} to every link. Returns the helpers. */
37
+ declare function addLinkFrameHelpers(robot: ThreeUsdRobot, size?: number): LinkFrameHelper[];
38
+
39
+ export { JointAxisHelper, JointLimitHelper, LinkFrameHelper, addJointAxisHelpers, addJointLimitHelpers, addLinkFrameHelpers };