three-usd-robot 0.4.0 → 0.5.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/index.js CHANGED
@@ -1,664 +1,5 @@
1
- import { AssetPath, identity4, multiply, computeLocalTransform, invert, interpolate, DefaultAssetResolver, CrateReader, openUsdz, crateToUsdaFile, composeFile, Stage, extractRobotDescription, buildKinematicTree, composeLayer } from './chunk-FYVZ7YPW.js';
2
- 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, channelFromSamples, composeFile, composeLayer, computeLocalTransform, crateToUsdaFile, createMemoryResolver, driveKindFor, extractRobotDescription, fromUsdMatrix, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getTranslation, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, identity4, interpolate, invert, isMesh, isScope, isXform, iterDescendants, joinPosix, jointValueToSI, makeEuler, makeRotationFromQuat, makeRotationX, makeRotationY, makeRotationZ, makeScale, makeTranslation, multiply, multiplyAll, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, tokenize } from './chunk-FYVZ7YPW.js';
3
- import * as THREE4 from 'three';
4
-
5
- function axisVector(axis) {
6
- switch (axis) {
7
- case "X":
8
- return new THREE4.Vector3(1, 0, 0);
9
- case "Y":
10
- return new THREE4.Vector3(0, 1, 0);
11
- case "Z":
12
- return new THREE4.Vector3(0, 0, 1);
13
- }
14
- }
15
- var JointObject = class extends THREE4.Object3D {
16
- isJointObject = true;
17
- jointName;
18
- jointType;
19
- axisToken;
20
- axis;
21
- lower;
22
- upper;
23
- _value = 0;
24
- constructor(joint) {
25
- super();
26
- this.name = joint.name;
27
- this.jointName = joint.name;
28
- this.jointType = joint.type;
29
- this.axisToken = joint.axis;
30
- this.axis = axisVector(joint.axis);
31
- this.lower = joint.lower;
32
- this.upper = joint.upper;
33
- }
34
- get value() {
35
- return this._value;
36
- }
37
- get articulated() {
38
- return this.jointType !== "fixed";
39
- }
40
- /**
41
- * Set the joint value (radians for revolute/continuous, length for prismatic).
42
- * Optionally clamps to authored limits. Returns the value actually applied.
43
- */
44
- setValue(value, clampToLimits = true) {
45
- if (!this.articulated) return this._value;
46
- let v = value;
47
- if (clampToLimits) {
48
- if (this.lower !== void 0 && v < this.lower) v = this.lower;
49
- if (this.upper !== void 0 && v > this.upper) v = this.upper;
50
- }
51
- this._value = v;
52
- if (this.jointType === "prismatic") {
53
- this.position.copy(this.axis).multiplyScalar(v);
54
- this.quaternion.identity();
55
- } else {
56
- this.quaternion.setFromAxisAngle(this.axis, v);
57
- this.position.set(0, 0, 0);
58
- }
59
- return v;
60
- }
61
- };
62
- var LinkObject = class extends THREE4.Object3D {
63
- isLinkObject = true;
64
- linkName;
65
- primPath;
66
- constructor(link) {
67
- super();
68
- this.name = link.name;
69
- this.linkName = link.name;
70
- this.primPath = link.primPath;
71
- this.matrixAutoUpdate = false;
72
- }
73
- };
74
-
75
- // src/three/MaterialBinding.ts
76
- var DIFFUSE_INPUTS = [
77
- "inputs:diffuseColor",
78
- // UsdPreviewSurface
79
- "inputs:diffuse_color_constant",
80
- // OmniPBR
81
- "inputs:diffuse_tint",
82
- "inputs:base_color",
83
- "inputs:baseColor"
84
- ];
85
- var OPACITY_INPUTS = ["inputs:opacity", "inputs:opacity_constant"];
86
- var METALLIC_INPUTS = ["inputs:metallic", "inputs:metallic_constant"];
87
- var ROUGHNESS_INPUTS = ["inputs:roughness", "inputs:reflection_roughness_constant"];
88
- var SURFACE_OUTPUTS = ["outputs:surface", "outputs:mdl:surface"];
89
- function resolveBoundMaterial(stage, prim) {
90
- const materialPath = findBinding(prim);
91
- if (!materialPath) return void 0;
92
- const material = stage.GetPrimAtPath(materialPath);
93
- if (!material) return void 0;
94
- const shader = findSurfaceShader(material);
95
- if (!shader) return void 0;
96
- const result = {};
97
- const color = firstColor(shader, DIFFUSE_INPUTS);
98
- if (color) result.color = color;
99
- const opacity = firstNumber(shader, OPACITY_INPUTS);
100
- if (opacity !== void 0) result.opacity = opacity;
101
- const metalness = firstNumber(shader, METALLIC_INPUTS);
102
- if (metalness !== void 0) result.metalness = metalness;
103
- const roughness = firstNumber(shader, ROUGHNESS_INPUTS);
104
- if (roughness !== void 0) result.roughness = roughness;
105
- const texture = findDiffuseTexture(shader);
106
- if (texture !== void 0) result.colorTexture = texture;
107
- return result;
108
- }
109
- var DIFFUSE_TEXTURE_INPUTS = ["inputs:diffuse_texture", "inputs:diffuse_color_texture"];
110
- function findDiffuseTexture(shader) {
111
- for (const name of DIFFUSE_TEXTURE_INPUTS) {
112
- const v = shader.GetAttribute(name).Get();
113
- if (v instanceof AssetPath && v.path) return v.path;
114
- }
115
- const conn = shader.GetAttribute("inputs:diffuseColor").GetConnections()[0];
116
- if (conn) {
117
- const texPrim = shader.GetStage().GetPrimAtPath(conn.split(".")[0]);
118
- const file = texPrim?.GetAttribute("inputs:file").Get();
119
- if (file instanceof AssetPath && file.path) return file.path;
120
- }
121
- return void 0;
122
- }
123
- function findBinding(prim) {
124
- let p = prim;
125
- while (p) {
126
- const targets = p.GetRelationship("material:binding").GetTargets();
127
- if (targets.length > 0) return targets[0];
128
- p = p.GetParent();
129
- }
130
- return void 0;
131
- }
132
- function findSurfaceShader(material) {
133
- for (const out of SURFACE_OUTPUTS) {
134
- const conn = material.GetAttribute(out).GetConnections()[0];
135
- if (conn) {
136
- const shaderPath = conn.split(".")[0];
137
- const shader = material.GetStage().GetPrimAtPath(shaderPath);
138
- if (shader) return shader;
139
- }
140
- }
141
- return material.GetChildren().find((c) => c.GetTypeName() === "Shader") ?? void 0;
142
- }
143
- function firstColor(shader, names) {
144
- for (const name of names) {
145
- const v = shader.GetAttribute(name).Get();
146
- if (Array.isArray(v) && v.length >= 3 && v.every((n) => typeof n === "number")) {
147
- return [v[0], v[1], v[2]];
148
- }
149
- }
150
- return void 0;
151
- }
152
- function firstNumber(shader, names) {
153
- for (const name of names) {
154
- const v = shader.GetAttribute(name).Get();
155
- if (typeof v === "number") return v;
156
- }
157
- return void 0;
158
- }
159
-
160
- // src/three/MeshBinding.ts
161
- var DEFAULT_COLOR = 10132122;
162
- function buildMeshGeometry(meshPrim) {
163
- const points = meshPrim.GetAttribute("points").Get();
164
- if (!isVec3Array(points) || points.length === 0) return null;
165
- const geometry = new THREE4.BufferGeometry();
166
- geometry.setAttribute("position", new THREE4.Float32BufferAttribute(flat3(points), 3));
167
- const counts = meshPrim.GetAttribute("faceVertexCounts").Get();
168
- const indices = meshPrim.GetAttribute("faceVertexIndices").Get();
169
- if (isNumberArray(counts) && isNumberArray(indices)) {
170
- geometry.setIndex(triangulate(counts, indices));
171
- } else if (isNumberArray(indices)) {
172
- geometry.setIndex(indices.slice());
173
- }
174
- const normals = meshPrim.GetAttribute("normals").Get();
175
- if (isVec3Array(normals) && normals.length === points.length) {
176
- geometry.setAttribute("normal", new THREE4.Float32BufferAttribute(flat3(normals), 3));
177
- } else {
178
- geometry.computeVertexNormals();
179
- }
180
- const st = meshPrim.GetAttribute("primvars:st").Get();
181
- if (isVec2Array(st) && st.length === points.length) {
182
- geometry.setAttribute("uv", new THREE4.Float32BufferAttribute(flat2(st), 2));
183
- }
184
- return geometry;
185
- }
186
- function buildMeshMaterial(meshPrim, stage, textures) {
187
- const color = new THREE4.Color(DEFAULT_COLOR);
188
- let metalness = 0.1;
189
- let roughness = 0.8;
190
- let opacity = 1;
191
- const bound = stage ? resolveBoundMaterial(stage, meshPrim) : void 0;
192
- if (bound?.color) {
193
- color.setRGB(bound.color[0], bound.color[1], bound.color[2]);
194
- } else {
195
- const displayColor = meshPrim.GetAttribute("primvars:displayColor").Get();
196
- if (isVec3Array(displayColor) && displayColor[0]) {
197
- const [r, g, b] = displayColor[0];
198
- color.setRGB(r, g, b);
199
- }
200
- }
201
- if (bound?.metalness !== void 0) metalness = bound.metalness;
202
- if (bound?.roughness !== void 0) roughness = bound.roughness;
203
- if (bound?.opacity !== void 0) opacity = bound.opacity;
204
- const map = bound?.colorTexture && textures ? textures(bound.colorTexture) : null;
205
- if (map) color.setRGB(1, 1, 1);
206
- const doubleSided = meshPrim.GetAttribute("doubleSided").Get() === true;
207
- return new THREE4.MeshStandardMaterial({
208
- color,
209
- metalness,
210
- roughness,
211
- transparent: opacity < 1,
212
- opacity,
213
- side: doubleSided ? THREE4.DoubleSide : THREE4.FrontSide,
214
- ...map ? { map } : {}
215
- });
216
- }
217
- function bindRobotMeshes(stage, robot3d, desc, options = {}) {
218
- const loadVisuals = options.loadVisuals ?? true;
219
- const loadCollisions = options.loadCollisions ?? false;
220
- const textures = options.textureProvider;
221
- for (const [key, link] of Object.entries(desc.links)) {
222
- const linkObj = robot3d.getLinkObject(key);
223
- const linkPrim = stage.GetPrimAtPath(link.primPath);
224
- if (!linkObj || !linkPrim) continue;
225
- const collisionSet = new Set(link.collisionPrims ?? []);
226
- if (loadVisuals) {
227
- for (const meshPath of link.visualPrims) {
228
- if (collisionSet.has(meshPath)) continue;
229
- attachMesh(stage, linkPrim, meshPath, linkObj, "visual", textures);
230
- }
231
- }
232
- if (loadCollisions) {
233
- for (const meshPath of link.collisionPrims ?? []) {
234
- attachMesh(stage, linkPrim, meshPath, linkObj, "collision", textures);
235
- }
236
- }
237
- }
238
- }
239
- function attachMesh(stage, linkPrim, meshPath, parent, kind, textures) {
240
- const meshPrim = stage.GetPrimAtPath(meshPath);
241
- if (!meshPrim) return;
242
- const geometry = buildMeshGeometry(meshPrim);
243
- if (!geometry) return;
244
- const mesh = new THREE4.Mesh(geometry, buildMeshMaterial(meshPrim, stage, textures));
245
- mesh.name = meshPrim.GetName();
246
- mesh.userData.kind = kind;
247
- mesh.userData.primPath = meshPath;
248
- if (kind === "collision") mesh.visible = false;
249
- mesh.matrixAutoUpdate = false;
250
- mesh.matrix.fromArray(relativeTransform(linkPrim, meshPrim));
251
- mesh.matrixWorldNeedsUpdate = true;
252
- parent.add(mesh);
253
- }
254
- function relativeTransform(linkPrim, meshPrim) {
255
- const chain = [];
256
- let p = meshPrim;
257
- const stop = linkPrim.GetPath();
258
- while (p && p.GetPath() !== stop) {
259
- chain.push(p);
260
- p = p.GetParent();
261
- }
262
- chain.reverse();
263
- let m = identity4();
264
- for (const prim of chain) {
265
- m = multiply(m, computeLocalTransform(prim).matrix);
266
- }
267
- return m;
268
- }
269
- function triangulate(faceVertexCounts, faceVertexIndices) {
270
- const tris = [];
271
- let offset = 0;
272
- for (const count of faceVertexCounts) {
273
- for (let k = 2; k < count; k++) {
274
- tris.push(
275
- faceVertexIndices[offset],
276
- faceVertexIndices[offset + k - 1],
277
- faceVertexIndices[offset + k]
278
- );
279
- }
280
- offset += count;
281
- }
282
- return tris;
283
- }
284
- function flat3(v) {
285
- const out = new Array(v.length * 3);
286
- for (let i = 0; i < v.length; i++) {
287
- out[i * 3] = v[i][0];
288
- out[i * 3 + 1] = v[i][1];
289
- out[i * 3 + 2] = v[i][2];
290
- }
291
- return out;
292
- }
293
- function flat2(v) {
294
- const out = new Array(v.length * 2);
295
- for (let i = 0; i < v.length; i++) {
296
- out[i * 2] = v[i][0];
297
- out[i * 2 + 1] = v[i][1];
298
- }
299
- return out;
300
- }
301
- function isNumberArray(v) {
302
- return Array.isArray(v) && v.every((n) => typeof n === "number");
303
- }
304
- function isVec3Array(v) {
305
- return Array.isArray(v) && v.every((e) => Array.isArray(e) && e.length === 3);
306
- }
307
- function isVec2Array(v) {
308
- return Array.isArray(v) && v.every((e) => Array.isArray(e) && e.length === 2);
309
- }
310
- function createTextureProvider(resolver, baseUrl) {
311
- const loader = new THREE4.TextureLoader();
312
- const cache = /* @__PURE__ */ new Map();
313
- return (assetPath) => {
314
- let url;
315
- try {
316
- url = resolver.resolve(assetPath, baseUrl);
317
- } catch {
318
- return null;
319
- }
320
- const cached = cache.get(url);
321
- if (cached) return cached;
322
- const texture = loader.load(url);
323
- texture.colorSpace = THREE4.SRGBColorSpace;
324
- texture.wrapS = THREE4.RepeatWrapping;
325
- texture.wrapT = THREE4.RepeatWrapping;
326
- cache.set(url, texture);
327
- return texture;
328
- };
329
- }
330
- var ThreeUsdRobot = class extends THREE4.Object3D {
331
- isThreeUsdRobot = true;
332
- robot;
333
- tree;
334
- clampJointLimits;
335
- linkObjects = /* @__PURE__ */ new Map();
336
- jointObjects = /* @__PURE__ */ new Map();
337
- dirty = true;
338
- helperSize;
339
- _showVisual = true;
340
- _showCollision = false;
341
- _showJointAxes = false;
342
- _showLinkFrames = false;
343
- jointAxesHelpers = [];
344
- linkFrameHelpers = [];
345
- constructor(robot, tree, options = {}) {
346
- super();
347
- this.name = robot.name;
348
- this.robot = robot;
349
- this.tree = tree;
350
- this.clampJointLimits = options.clampJointLimits ?? true;
351
- this.helperSize = options.helperSize ?? 0.15;
352
- for (const [key, link] of Object.entries(robot.links)) {
353
- this.linkObjects.set(key, new LinkObject(link));
354
- }
355
- this.attachRoot();
356
- this.attachTreeEdges();
357
- this.attachIsolatedLinks();
358
- this.applyStageNormalization(robot, options);
359
- if (options.applyInitialPose ?? true) this.applyInitialPose(robot);
360
- }
361
- /** Orient (Z-up → Y-up) and scale (metersPerUnit × unitScale) the robot root. */
362
- applyStageNormalization(robot, options) {
363
- const scale = (robot.metersPerUnit || 1) * (options.unitScale ?? 1);
364
- if (scale !== 1) this.scale.setScalar(scale);
365
- const conv = options.upAxisConversion ?? "none";
366
- const toY = conv === "Z" || conv === "auto" && robot.upAxis === "Z";
367
- if (toY) this.quaternion.setFromAxisAngle(new THREE4.Vector3(1, 0, 0), -Math.PI / 2);
368
- }
369
- /** Apply each joint's authored initial value, if any. */
370
- applyInitialPose(robot) {
371
- for (const [key, joint] of Object.entries(robot.joints)) {
372
- if (joint.initialValue === void 0) continue;
373
- this.jointObjects.get(key)?.setValue(joint.initialValue, this.clampJointLimits);
374
- }
375
- this.dirty = true;
376
- }
377
- attachRoot() {
378
- const rootObj = this.linkObjects.get(this.tree.root);
379
- if (!rootObj) return;
380
- const rootJointKey = this.tree.rootJoint;
381
- if (rootJointKey) {
382
- const j = this.robot.joints[rootJointKey];
383
- if (j) setMatrix(rootObj, multiply(j.jointFrame0, invert(j.jointFrame1)));
384
- }
385
- this.add(rootObj);
386
- }
387
- attachTreeEdges() {
388
- for (const linkKey of this.tree.order) {
389
- const node = this.tree.nodes[linkKey];
390
- if (!node || node.parent === null || node.jointToParent === null) continue;
391
- const parentObj = this.linkObjects.get(node.parent);
392
- const childObj = this.linkObjects.get(linkKey);
393
- const joint = this.robot.joints[node.jointToParent];
394
- if (!parentObj || !childObj || !joint) continue;
395
- this.attachJointChain(parentObj, childObj, node.jointToParent, joint);
396
- }
397
- }
398
- /** Build `parent → frame0 → motion → frame1⁻¹ → child` for one joint. */
399
- attachJointChain(parent, child, jointKey, joint) {
400
- const frame0 = new THREE4.Group();
401
- frame0.name = `${joint.name}:frame0`;
402
- setMatrix(frame0, joint.jointFrame0);
403
- const motion = new JointObject(joint);
404
- const frame1Inv = new THREE4.Group();
405
- frame1Inv.name = `${joint.name}:frame1Inv`;
406
- setMatrix(frame1Inv, invert(joint.jointFrame1));
407
- parent.add(frame0);
408
- frame0.add(motion);
409
- motion.add(frame1Inv);
410
- frame1Inv.add(child);
411
- this.jointObjects.set(jointKey, motion);
412
- }
413
- attachIsolatedLinks() {
414
- for (const key of this.tree.isolatedLinks) {
415
- const obj = this.linkObjects.get(key);
416
- if (obj && !obj.parent) this.add(obj);
417
- }
418
- }
419
- // -- Joint control -------------------------------------------------------
420
- /** Set one joint value. Unknown joints are ignored. Returns whether it applied. */
421
- setJointValue(name, value) {
422
- const joint = this.jointObjects.get(name);
423
- if (!joint) return false;
424
- joint.setValue(value, this.clampJointLimits);
425
- this.dirty = true;
426
- return true;
427
- }
428
- /** Set several joint values at once (matrix update is coalesced). */
429
- setJointValues(values) {
430
- for (const [name, value] of Object.entries(values)) {
431
- const joint = this.jointObjects.get(name);
432
- if (joint) {
433
- joint.setValue(value, this.clampJointLimits);
434
- this.dirty = true;
435
- }
436
- }
437
- }
438
- getJointValue(name) {
439
- return this.jointObjects.get(name)?.value;
440
- }
441
- /** Recompute world matrices. Called lazily by the getters; safe to call directly. */
442
- updateKinematics() {
443
- this.updateMatrixWorld(true);
444
- this.dirty = false;
445
- }
446
- ensureUpdated() {
447
- if (this.dirty) this.updateKinematics();
448
- }
449
- // -- Queries -------------------------------------------------------------
450
- getLinkWorldMatrix(name) {
451
- const obj = this.linkObjects.get(name);
452
- if (!obj) throw new Error(`unknown link "${name}"`);
453
- this.ensureUpdated();
454
- return obj.matrixWorld.clone();
455
- }
456
- getLinkWorldPosition(name) {
457
- return new THREE4.Vector3().setFromMatrixPosition(this.getLinkWorldMatrix(name));
458
- }
459
- getLinkObject(name) {
460
- return this.linkObjects.get(name);
461
- }
462
- getJointObject(name) {
463
- return this.jointObjects.get(name);
464
- }
465
- getJoints() {
466
- return Object.values(this.robot.joints);
467
- }
468
- getLinks() {
469
- return Object.values(this.robot.links);
470
- }
471
- /** Names of the articulated (controllable) joints. */
472
- getJointNames() {
473
- return [...this.jointObjects.keys()];
474
- }
475
- getLinkNames() {
476
- return [...this.linkObjects.keys()];
477
- }
478
- getKinematicTree() {
479
- return this.tree;
480
- }
481
- // -- Animation playback --------------------------------------------------
482
- /** Playback rate in time codes per second (from the stage; default 24). */
483
- getTimeCodesPerSecond() {
484
- return this.robot.timeCodesPerSecond ?? 24;
485
- }
486
- /** Whether any joint has a time-sampled trajectory. */
487
- hasAnimation() {
488
- return Object.values(this.robot.joints).some((j) => j.valueSamples !== void 0);
489
- }
490
- /**
491
- * Animation range in time codes: the union of authored joint sample ranges,
492
- * falling back to the stage `startTimeCode`/`endTimeCode`. `null` if neither.
493
- */
494
- getTimeRange() {
495
- let start = Number.POSITIVE_INFINITY;
496
- let end = Number.NEGATIVE_INFINITY;
497
- for (const joint of Object.values(this.robot.joints)) {
498
- const times = joint.valueSamples?.times;
499
- if (!times || times.length === 0) continue;
500
- start = Math.min(start, times[0]);
501
- end = Math.max(end, times[times.length - 1]);
502
- }
503
- if (start <= end) return { start, end };
504
- const { startTimeCode, endTimeCode } = this.robot;
505
- if (startTimeCode !== void 0 && endTimeCode !== void 0) {
506
- return { start: startTimeCode, end: endTimeCode };
507
- }
508
- return null;
509
- }
510
- /** Sample every animated joint at time code `t` and apply the values. */
511
- setTime(t) {
512
- for (const [key, joint] of Object.entries(this.robot.joints)) {
513
- if (joint.valueSamples) this.setJointValue(key, interpolate(joint.valueSamples, t));
514
- }
515
- }
516
- // -- Display toggles -----------------------------------------------------
517
- get showVisual() {
518
- return this._showVisual;
519
- }
520
- set showVisual(v) {
521
- this._showVisual = v;
522
- this.setKindVisibility("visual", v);
523
- }
524
- get showCollision() {
525
- return this._showCollision;
526
- }
527
- set showCollision(v) {
528
- this._showCollision = v;
529
- this.setKindVisibility("collision", v);
530
- }
531
- get showJointAxes() {
532
- return this._showJointAxes;
533
- }
534
- set showJointAxes(v) {
535
- this._showJointAxes = v;
536
- if (v && this.jointAxesHelpers.length === 0) {
537
- for (const joint of this.jointObjects.values()) {
538
- const h = new THREE4.AxesHelper(this.helperSize);
539
- h.name = `${joint.jointName}:axes`;
540
- joint.add(h);
541
- this.jointAxesHelpers.push(h);
542
- }
543
- }
544
- for (const h of this.jointAxesHelpers) h.visible = v;
545
- }
546
- get showLinkFrames() {
547
- return this._showLinkFrames;
548
- }
549
- set showLinkFrames(v) {
550
- this._showLinkFrames = v;
551
- if (v && this.linkFrameHelpers.length === 0) {
552
- for (const link of this.linkObjects.values()) {
553
- const h = new THREE4.AxesHelper(this.helperSize);
554
- h.name = `${link.linkName}:frame`;
555
- link.add(h);
556
- this.linkFrameHelpers.push(h);
557
- }
558
- }
559
- for (const h of this.linkFrameHelpers) h.visible = v;
560
- }
561
- setKindVisibility(kind, visible) {
562
- this.traverse((o) => {
563
- if (o.userData.kind === kind) o.visible = visible;
564
- });
565
- }
566
- };
567
- function setMatrix(obj, m) {
568
- obj.matrixAutoUpdate = false;
569
- obj.matrix.fromArray(m);
570
- obj.matrixWorldNeedsUpdate = true;
571
- }
572
-
573
- // src/three/ThreeUsdRobotLoader.ts
574
- var ThreeUsdRobotLoader = class {
575
- options;
576
- constructor(options = {}) {
577
- this.options = options;
578
- }
579
- get resolver() {
580
- return this.options.assetResolver ?? new DefaultAssetResolver();
581
- }
582
- /**
583
- * Fetch an asset by URL and build the robot. `.usdz` packages are unzipped and
584
- * composed from their entries; everything else is treated as USDA text.
585
- */
586
- async loadAsync(url) {
587
- if (/\.usdz$/i.test(url)) {
588
- return this.parseUsdz(await this.fetchRootBytes(url));
589
- }
590
- const bytes = await this.fetchRootBytes(url);
591
- if (CrateReader.isCrate(bytes)) return this.parseCrate(bytes, url);
592
- return this.parse(new TextDecoder().decode(bytes), url);
593
- }
594
- async fetchRootBytes(url) {
595
- const resolver = this.resolver;
596
- if (resolver.fetchBytes) return resolver.fetchBytes(url);
597
- return new TextEncoder().encode(await resolver.fetchText(url));
598
- }
599
- /** Build a robot (composed, with meshes) from USDA source text. */
600
- async parse(text, baseUrl = "") {
601
- return this.buildFromStage(
602
- await this.composeStage(text, baseUrl, this.resolver),
603
- baseUrl,
604
- this.resolver
605
- );
606
- }
607
- /** Build a robot from the bytes of a `.usdz` package. */
608
- async parseUsdz(bytes) {
609
- const pkg = openUsdz(bytes);
610
- const rootText = await pkg.resolver.fetchText(pkg.rootEntry);
611
- const stage = await this.composeStage(rootText, pkg.rootEntry, pkg.resolver);
612
- return this.buildFromStage(stage, pkg.rootEntry, pkg.resolver);
613
- }
614
- /** Build a robot from the bytes of a binary crate (`.usdc` / binary `.usd`). */
615
- async parseCrate(bytes, baseUrl = "") {
616
- const file = crateToUsdaFile(new CrateReader(bytes));
617
- const composeOptions = this.options.onWarn ? { onWarn: this.options.onWarn } : {};
618
- const composed = await composeFile(file, baseUrl, this.resolver, composeOptions);
619
- return this.buildFromStage(Stage.OpenFromFile(composed), baseUrl, this.resolver);
620
- }
621
- /** Parse + compose USDA source into the Three.js-independent robot IR. */
622
- async parseRobotDescription(text, baseUrl = "") {
623
- const stage = await this.composeStage(text, baseUrl, this.resolver);
624
- return extractRobotDescription(stage, this.extractOptions());
625
- }
626
- buildFromStage(stage, baseUrl, resolver) {
627
- const robot = extractRobotDescription(stage, this.extractOptions());
628
- const tree = buildKinematicTree(robot);
629
- const robot3d = new ThreeUsdRobot(robot, tree, this.robotOptions());
630
- const loadVisuals = this.options.loadVisuals ?? true;
631
- const loadCollisions = this.options.loadCollisions ?? false;
632
- if (loadVisuals || loadCollisions) {
633
- const textureProvider = this.options.loadTextures ?? true ? createTextureProvider(resolver, baseUrl) : void 0;
634
- bindRobotMeshes(stage, robot3d, robot, {
635
- loadVisuals,
636
- loadCollisions,
637
- ...textureProvider ? { textureProvider } : {}
638
- });
639
- }
640
- return robot3d;
641
- }
642
- async composeStage(text, baseUrl, resolver) {
643
- const composeOptions = this.options.onWarn ? { onWarn: this.options.onWarn } : {};
644
- return Stage.OpenFromFile(await composeLayer(text, baseUrl, resolver, composeOptions));
645
- }
646
- robotOptions() {
647
- return {
648
- upAxisConversion: this.options.upAxisConversion ?? "auto",
649
- ...this.options.clampJointLimits !== void 0 ? { clampJointLimits: this.options.clampJointLimits } : {},
650
- ...this.options.unitScale !== void 0 ? { unitScale: this.options.unitScale } : {},
651
- ...this.options.applyDriveTargetsAsInitialPose !== void 0 ? { applyInitialPose: this.options.applyDriveTargetsAsInitialPose } : {}
652
- };
653
- }
654
- extractOptions() {
655
- return {
656
- ...this.options.robotName !== void 0 ? { robotName: this.options.robotName } : {},
657
- ...this.options.onWarn !== void 0 ? { onWarn: this.options.onWarn } : {}
658
- };
659
- }
660
- };
661
-
662
- export { JointObject, LinkObject, ThreeUsdRobot, ThreeUsdRobotLoader, axisVector, bindRobotMeshes, buildMeshGeometry, buildMeshMaterial, createTextureProvider, resolveBoundMaterial };
1
+ export { PACKAGE_NAME, VERSION } from './chunk-OFUMT72H.js';
2
+ export { JointObject, LinkObject, ThreeUsdRobot, ThreeUsdRobotLoader, axisVector, bindRobotMeshes, buildMeshGeometry, buildMeshMaterial, createTextureProvider, resolveBoundMaterial } from './chunk-Y3NXBSX3.js';
3
+ export { ARTICULATION_ROOT_API, AssetPath, Attribute, COLLISION_API, CrateReader, DEFAULT_METERS_PER_UNIT, DEG2RAD, DefaultAssetResolver, Layer, ParseError, Prim, Quat, RAD2DEG, RIGID_BODY_API, Relationship, Stage, TokenizeError, UsdMatrix, buildKinematicTree, channelFromSamples, composeFile, composeLayer, computeLocalTransform, crateToUsdaFile, createMemoryResolver, driveKindFor, extractRobotDescription, fromUsdMatrix, gatherMeshDescendants, getJointAxis, getJointBodies, getJointDrive, getJointLimits, getJointLocalFrame, getJointStatePosition, getJointType, getTranslation, hasArticulationRootAPI, hasCollisionAPI, hasRigidBodyAPI, identity4, interpolate, invert, isMesh, isScope, isXform, iterDescendants, joinPosix, jointValueToSI, makeEuler, makeRotationFromQuat, makeRotationX, makeRotationY, makeRotationZ, makeScale, makeTranslation, multiply, multiplyAll, normalizeJointLimits, openUsdz, parseOpType, parseUsda, refineJointType, tokenize } from './chunk-36T6YOEX.js';
663
4
  //# sourceMappingURL=index.js.map
664
5
  //# sourceMappingURL=index.js.map