@openusd-wasm/three-loader 0.0.4 → 0.0.5

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 CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  Three.js loader for OpenUSD `.usd`, `.usda`, `.usdc`, and `.usdz` assets.
4
4
  Parsing runs through `@openusd-wasm/pxr`; this package converts the opened USD
5
- stage into a Three.js object tree and keeps OpenUSD metadata available in
6
- `Object3D.userData`.
5
+ stage into a Three.js object tree, returns extracted USD scene data, and keeps
6
+ runtime lookup state separate from Three.js `userData`.
7
7
 
8
8
  ```ts
9
9
  import createOpenUsdPxrWasm from '@openusd-wasm/core'
@@ -18,10 +18,13 @@ const loader = new USDLoader({
18
18
  },
19
19
  })
20
20
 
21
- const { scene, metadata } = await loader.loadAsync('/models/robot.usda')
21
+ const model = await loader.loadAsync('/models/robot.usda')
22
+ const { scene, data, index } = model
22
23
  threeScene.add(scene)
23
24
 
24
- console.log(metadata.joints)
25
+ console.log(data.physics)
26
+ console.log(data.joints)
27
+ console.log(index.objectsByPath.get('/World/Robot'))
25
28
  ```
26
29
 
27
30
  ## Returned Data
@@ -29,21 +32,58 @@ console.log(metadata.joints)
29
32
  `USDLoader` returns:
30
33
 
31
34
  - `scene`: a `THREE.Group` containing mesh/group objects that mirror the USD prim hierarchy.
32
- - `metadata`: stage info, view prims, mesh geometry summaries, material/shader inputs, and physics joint info.
35
+ - `data`: extracted stage info, view prims, mesh geometry summaries, material/shader inputs, animation data, variants, and USD physics info.
36
+ - `index`: runtime lookup maps such as `objectsByPath`, `meshesByPath`, `materialsByPath`, `rigidBodiesByPath`, `jointsByBodyPath`, and `bonesBySkeletonPath`.
37
+ - `resources`: object URL maps for images discovered in USDZ packages or auto-resolved next to the root layer.
33
38
  - `sourcePath` and `rootLayerIdentifier`: useful for diagnostics and texture resolution.
34
39
 
35
- The same metadata is attached to the scene:
40
+ Generated prim objects only store a lightweight USD bridge in `userData`:
36
41
 
37
42
  ```ts
38
- scene.userData.usdMetadata
39
- scene.userData.usdJoints
40
- scene.userData.usdObjectsByPath
43
+ object.userData.usd
44
+ // { kind: 'prim', path: '/World/Mesh', typeName: 'Mesh' }
41
45
  ```
42
46
 
43
- Each generated object gets `userData.usdPath` and `userData.usdTypeName`.
44
- Joint prim objects get `userData.usdJoint`; body objects referenced by joints
45
- get a `userData.usdJoints` array. This mirrors the URDFLoader pattern where
46
- clients can restore articulation controls from exported joint metadata.
47
+ Use `model.index` to look up heavy USD data or Three.js runtime objects. The
48
+ loader does not mirror scene data, physics summaries, texture URL maps, or
49
+ object indexes into `Object3D.userData`.
50
+
51
+ Skeleton bones and animation clips use the same lightweight bridge:
52
+
53
+ ```ts
54
+ bone.userData.usd
55
+ // { kind: 'skelJoint', skeletonPath: '/World/Skeleton', jointPath: 'root', jointIndex: 0 }
56
+
57
+ clip.userData.usd
58
+ // { kind: 'animation', id: 'skel:/World/Skeleton/Animation', source: 'skel', variant: null }
59
+ ```
60
+
61
+ Call `model.dispose()` or `disposeUSDLoadedModel(model)` when a loaded model is
62
+ removed. This releases generated Three.js resources, preserved USD stages, and
63
+ object URLs created for auto-resolved or USDZ textures stored in
64
+ `model.resources`.
65
+
66
+ ## Lower-Level APIs
67
+
68
+ Use `parseDataAsync()` when an application needs the OpenUSD scene facts before
69
+ creating Three.js objects:
70
+
71
+ ```ts
72
+ const parsed = await loader.parseDataAsync(file, { sourcePath: 'robot.usda' })
73
+ console.log(parsed.data.stage)
74
+ console.log(parsed.data.materials)
75
+ ```
76
+
77
+ Use `extractUSDSceneData()` when you already opened a `Usd.Stage` through
78
+ `@openusd-wasm/pxr`, and `buildUSDScene()` when you want to convert extracted
79
+ data into Three.js manually:
80
+
81
+ ```ts
82
+ import { buildUSDScene, extractUSDSceneData } from '@openusd-wasm/three-loader'
83
+
84
+ const data = extractUSDSceneData(pxr, stage, { sourcePath: 'robot.usda' })
85
+ const { scene, index } = buildUSDScene(data, { loadTextures: false })
86
+ ```
47
87
 
48
88
  ## USDZ
49
89
 
@@ -28,9 +28,10 @@ interface USDViewPrim {
28
28
  resetsXformStack: boolean;
29
29
  }
30
30
  interface USDMeshGeometryData {
31
- positions: number[];
32
- normals: number[];
33
- uvs: number[];
31
+ positions: number[] | Float32Array;
32
+ pointIndices?: number[] | Int32Array;
33
+ normals: number[] | Float32Array;
34
+ uvs: number[] | Float32Array;
34
35
  displayColor: USDVector3 | null;
35
36
  displayOpacity: number | null;
36
37
  }
@@ -51,12 +52,19 @@ interface USDMaterialInfo {
51
52
  shaders: USDShaderInfo[];
52
53
  }
53
54
  interface USDJointDriveInfo {
55
+ dof?: string;
56
+ type?: string | null;
54
57
  targetPosition: number | null;
55
58
  targetVelocity: number | null;
56
59
  stiffness: number | null;
57
60
  damping: number | null;
58
61
  maxForce: number | null;
59
62
  }
63
+ interface USDJointLimitInfo {
64
+ dof: string;
65
+ low: number | null;
66
+ high: number | null;
67
+ }
60
68
  interface USDJointInfo {
61
69
  path: string;
62
70
  name: string;
@@ -72,9 +80,77 @@ interface USDJointInfo {
72
80
  lowerLimit: number | null;
73
81
  upperLimit: number | null;
74
82
  enabled: boolean;
83
+ collisionEnabled: boolean;
84
+ excludeFromArticulation: boolean;
85
+ breakForce: number | null;
86
+ breakTorque: number | null;
87
+ limits: USDJointLimitInfo[];
75
88
  drive: USDJointDriveInfo | null;
76
89
  drives: Record<string, USDJointDriveInfo>;
77
90
  }
91
+ interface USDPhysicsMassInfo {
92
+ mass: number | null;
93
+ density: number | null;
94
+ centerOfMass: USDVector3 | null;
95
+ diagonalInertia: USDVector3 | null;
96
+ principalAxes: USDVector4 | null;
97
+ }
98
+ interface USDPhysicsRigidBodyInfo {
99
+ path: string;
100
+ name: string;
101
+ typeName: string;
102
+ enabled: boolean;
103
+ kinematicEnabled: boolean;
104
+ startsAsleep: boolean | null;
105
+ velocity: USDVector3 | null;
106
+ angularVelocity: USDVector3 | null;
107
+ mass: USDPhysicsMassInfo | null;
108
+ }
109
+ interface USDPhysicsColliderInfo {
110
+ path: string;
111
+ name: string;
112
+ typeName: string;
113
+ bodyPath: string | null;
114
+ enabled: boolean;
115
+ approximation: string | null;
116
+ material: string | null;
117
+ }
118
+ interface USDPhysicsMaterialInfo {
119
+ path: string;
120
+ name: string;
121
+ staticFriction: number | null;
122
+ dynamicFriction: number | null;
123
+ restitution: number | null;
124
+ density: number | null;
125
+ }
126
+ interface USDPhysicsSceneInfo {
127
+ path: string;
128
+ name: string;
129
+ gravityDirection: USDVector3 | null;
130
+ gravityMagnitude: number | null;
131
+ }
132
+ interface USDPhysicsArticulationRootInfo {
133
+ path: string;
134
+ name: string;
135
+ joints: string[];
136
+ }
137
+ interface USDPhysicsInfo {
138
+ scenes: USDPhysicsSceneInfo[];
139
+ rigidBodies: USDPhysicsRigidBodyInfo[];
140
+ colliders: USDPhysicsColliderInfo[];
141
+ materials: USDPhysicsMaterialInfo[];
142
+ articulationRoots: USDPhysicsArticulationRootInfo[];
143
+ }
144
+ interface USDStageCameraInfo {
145
+ path: string;
146
+ name: string;
147
+ projection: 'perspective' | 'orthographic';
148
+ horizontalAperture: number | null;
149
+ verticalAperture: number | null;
150
+ focalLength: number | null;
151
+ clippingRange: [number, number] | null;
152
+ localMatrix: number[] | null;
153
+ }
78
154
  interface USDTransformAnimationSample {
79
155
  time: number;
80
156
  localMatrix: number[];
@@ -83,37 +159,173 @@ interface USDTransformAnimation {
83
159
  primPath: string;
84
160
  samples: USDTransformAnimationSample[];
85
161
  }
162
+ interface USDSkelBindingInfo {
163
+ primPath: string;
164
+ skeletonPath: string | null;
165
+ animationSource: string | null;
166
+ joints: string[];
167
+ jointIndices: number[];
168
+ jointWeights: number[];
169
+ elementSize: number;
170
+ geomBindTransform: number[] | null;
171
+ }
172
+ interface USDSkeletonInfo {
173
+ path: string;
174
+ joints: string[];
175
+ bindTransforms: number[][];
176
+ restTransforms: number[][];
177
+ restSkelTransforms?: number[][];
178
+ }
179
+ interface USDSkelJointVec3Sample {
180
+ time: number;
181
+ values: USDVector3[];
182
+ }
183
+ interface USDSkelJointQuatSample {
184
+ time: number;
185
+ values: USDVector4[];
186
+ }
187
+ interface USDSkelJointMatrixSample {
188
+ time: number;
189
+ values: number[][];
190
+ }
191
+ interface USDSkelAnimationSkeletonSamples {
192
+ skeletonPath: string;
193
+ samples: USDSkelJointMatrixSample[];
194
+ }
195
+ interface USDSkelAnimationInfo {
196
+ path: string;
197
+ name: string;
198
+ joints: string[];
199
+ translations: USDSkelJointVec3Sample[];
200
+ rotations: USDSkelJointQuatSample[];
201
+ scales: USDSkelJointVec3Sample[];
202
+ jointSkelTransformSamples?: USDSkelAnimationSkeletonSamples[];
203
+ }
204
+ interface USDSkelAnimationTrack {
205
+ skeletonPath: string;
206
+ animationPath: string;
207
+ samplesStartTimeCode: number;
208
+ samplesEndTimeCode: number;
209
+ }
210
+ type USDAnimationClipSource = 'stage' | 'skel' | 'variant' | 'clipsApi';
211
+ interface USDAnimationVariantRef {
212
+ primPath: string;
213
+ setName: string;
214
+ selection: string;
215
+ }
86
216
  interface USDAnimationInfo {
217
+ id: string;
218
+ name: string;
219
+ source: USDAnimationClipSource;
220
+ variant: USDAnimationVariantRef | null;
87
221
  startTimeCode: number;
88
222
  endTimeCode: number;
89
223
  timeCodesPerSecond: number;
90
224
  transforms: USDTransformAnimation[];
225
+ skelAnimations: USDSkelAnimationTrack[];
226
+ }
227
+ interface USDVariantSetInfo {
228
+ primPath: string;
229
+ primName: string;
230
+ setName: string;
231
+ variantNames: string[];
232
+ selection: string | null;
91
233
  }
92
- interface USDModelData {
234
+ interface USDVariantSelection {
235
+ primPath: string;
236
+ setName: string;
237
+ selection: string | null;
238
+ }
239
+ interface USDSkelInfo {
240
+ skeletons: USDSkeletonInfo[];
241
+ bindings: USDSkelBindingInfo[];
242
+ animations: USDSkelAnimationInfo[];
243
+ }
244
+ interface USDSceneData {
93
245
  stage: USDStageInfo;
94
246
  view: {
95
247
  prims: USDViewPrim[];
96
248
  };
97
249
  elements: USDMeshElement[];
98
250
  materials: USDMaterialInfo[];
251
+ physics: USDPhysicsInfo;
99
252
  joints: USDJointInfo[];
253
+ cameras: USDStageCameraInfo[];
254
+ skels: USDSkelInfo;
100
255
  animations: USDAnimationInfo[];
256
+ variants: USDVariantSetInfo[];
257
+ }
258
+ type USDUserDataValue = {
259
+ kind: 'prim';
260
+ path: string;
261
+ typeName: string;
262
+ } | {
263
+ kind: 'skelJoint';
264
+ skeletonPath: string;
265
+ jointPath: string;
266
+ jointIndex: number;
267
+ } | {
268
+ kind: 'animation';
269
+ id: string;
270
+ source: USDAnimationClipSource;
271
+ variant: USDAnimationVariantRef | null;
272
+ };
273
+ interface USDUserData {
274
+ usd?: USDUserDataValue;
275
+ }
276
+ interface USDSceneIndex {
277
+ objectsByPath: Map<string, THREE.Object3D>;
278
+ bonesBySkeletonPath: Map<string, THREE.Bone[]>;
279
+ boneHostsBySkeletonPath: Map<string, THREE.Object3D>;
280
+ primsByPath: Map<string, USDViewPrim>;
281
+ meshesByPath: Map<string, USDMeshElement>;
282
+ materialsByPath: Map<string, USDMaterialInfo>;
283
+ rigidBodiesByPath: Map<string, USDPhysicsRigidBodyInfo>;
284
+ collidersByPath: Map<string, USDPhysicsColliderInfo>;
285
+ jointsByPath: Map<string, USDJointInfo>;
286
+ jointsByBodyPath: Map<string, USDJointInfo[]>;
287
+ skelBindingsByPrimPath: Map<string, USDSkelBindingInfo>;
288
+ skeletonsByPath: Map<string, USDSkeletonInfo>;
289
+ camerasByPath: Map<string, USDStageCameraInfo>;
290
+ variantsByPrimPath: Map<string, USDVariantSetInfo[]>;
291
+ animationsById: Map<string, USDAnimationInfo>;
292
+ }
293
+ interface USDSceneBuildResult {
294
+ scene: THREE.Group;
295
+ index: USDSceneIndex;
296
+ }
297
+ interface USDLoadedModelResources {
298
+ usdzTextureURLs: Map<string, string>;
299
+ autoTextureURLs: Map<string, string>;
101
300
  }
102
301
  interface USDLoadedModel {
103
302
  scene: THREE.Group;
104
- metadata: USDModelData;
303
+ data: USDSceneData;
304
+ index: USDSceneIndex;
305
+ resources: USDLoadedModelResources;
105
306
  stage?: unknown;
106
307
  pxr: Pxr;
107
308
  sourcePath: string;
108
309
  rootLayerIdentifier: string;
310
+ dispose(): void;
109
311
  }
110
- interface ExtractUSDModelDataOptions {
312
+ interface USDParsedStageData {
313
+ data: USDSceneData;
314
+ stage?: unknown;
315
+ pxr: Pxr;
316
+ sourcePath: string;
317
+ rootLayerIdentifier: string;
318
+ textureResolver?: USDTextureResolver;
319
+ usdzTextureURLs?: Map<string, string>;
320
+ autoTextureURLs?: Map<string, string>;
321
+ }
322
+ interface ExtractUSDSceneDataOptions {
111
323
  sourcePath?: string;
112
324
  rootLayerIdentifier?: string;
113
325
  }
114
326
  type USDTextureResolverContext = USDTextureResolverContext$1<USDMaterialInfo, USDShaderInfo>;
115
327
  type USDTextureResolver = USDTextureResolver$1<USDMaterialInfo, USDShaderInfo>;
116
- interface BuildUSDObjectOptions {
328
+ interface BuildUSDSceneOptions {
117
329
  sourcePath?: string;
118
330
  convertZUp?: boolean;
119
331
  loadTextures?: boolean;
@@ -121,7 +333,7 @@ interface BuildUSDObjectOptions {
121
333
  textureLoader?: THREE.TextureLoader;
122
334
  textureCache?: Map<string, THREE.Texture>;
123
335
  }
124
- interface USDLoaderParseOptions extends BuildUSDObjectOptions {
336
+ interface USDLoaderParseOptions extends BuildUSDSceneOptions {
125
337
  sourcePath?: string;
126
338
  fileName?: string;
127
339
  files?: Record<string, USDSourceInput>;
@@ -134,8 +346,9 @@ interface USDLoaderParseOptions extends BuildUSDObjectOptions {
134
346
  usdzLayer?: string;
135
347
  preserveStage?: boolean;
136
348
  cleanupAfterParse?: boolean;
349
+ variantSelections?: USDVariantSelection[];
137
350
  }
138
- interface USDLoaderOptions extends BuildUSDObjectOptions {
351
+ interface USDLoaderOptions extends BuildUSDSceneOptions {
139
352
  pxr?: Pxr | Promise<Pxr>;
140
353
  pxrOptions?: Parameters<typeof import('@openusd-wasm/pxr').createPxr>[0];
141
354
  workingDirectory?: string;
@@ -143,6 +356,7 @@ interface USDLoaderOptions extends BuildUSDObjectOptions {
143
356
  usdzLayer?: string;
144
357
  preserveStage?: boolean;
145
358
  cleanupAfterParse?: boolean;
359
+ variantSelections?: USDVariantSelection[];
146
360
  }
147
361
  type PxrObject = Record<string, any> & {
148
362
  delete?: () => void;
@@ -159,77 +373,17 @@ declare class USDLoader extends Loader<USDLoadedModel, string> {
159
373
  setWorkingDirectory(path: string): this;
160
374
  load(url: string, onLoad: (data: USDLoadedModel) => void, onProgress?: (event: ProgressEvent) => void, onError?: (err: unknown) => void): void;
161
375
  parse(input: USDSourceInput, onLoad: (data: USDLoadedModel) => void, onError?: (err: unknown) => void, options?: USDLoaderParseOptions): void;
376
+ parseDataAsync(input: USDSourceInput, options?: USDLoaderParseOptions): Promise<USDParsedStageData>;
162
377
  parseAsync(input: USDSourceInput, options?: USDLoaderParseOptions): Promise<USDLoadedModel>;
163
378
  private getPxr;
164
379
  }
165
380
  //#endregion
166
- //#region src/manipulation-controls.d.ts
167
- interface USDManipulationControlsOptions {
168
- scene: THREE.Scene;
169
- camera: THREE.Camera;
170
- domElement: HTMLElement;
171
- controls?: {
172
- enabled: boolean;
173
- } | null;
174
- highlightColor?: THREE.ColorRepresentation;
175
- enabled?: boolean;
176
- onChange?: (event: USDManipulationChangeEvent) => void;
177
- onHoverChange?: (event: USDManipulationHoverEvent) => void;
178
- }
179
- interface USDManipulationChangeEvent {
180
- joint: USDJointInfo;
181
- object: THREE.Object3D;
182
- body0: THREE.Object3D | null;
183
- value: number;
184
- previousValue: number;
185
- }
186
- interface USDManipulationHoverEvent {
187
- joint: USDJointInfo | null;
188
- object: THREE.Object3D | null;
189
- }
190
- declare class USDManipulationControls {
191
- private readonly raycaster;
192
- private readonly pointer;
193
- private readonly jointValues;
194
- private readonly highlighted;
195
- private activeDrag;
196
- private hovered;
197
- private modelStateSignature;
198
- private _enabled;
199
- private disposed;
200
- scene: THREE.Scene;
201
- camera: THREE.Camera;
202
- domElement: HTMLElement;
203
- controls: {
204
- enabled: boolean;
205
- } | null;
206
- highlightColor: THREE.Color;
207
- onChange?: (event: USDManipulationChangeEvent) => void;
208
- onHoverChange?: (event: USDManipulationHoverEvent) => void;
209
- constructor(options: USDManipulationControlsOptions);
210
- get enabled(): boolean;
211
- set enabled(value: boolean);
212
- dispose(): void;
213
- update(): void;
214
- clearSelection(): void;
215
- getJointValue(joint: USDJointInfo, root?: THREE.Object3D): number | undefined;
216
- setJointValue(joint: USDJointInfo, value: number, root?: THREE.Object3D): boolean;
217
- private readonly onPointerMove;
218
- private readonly onPointerDown;
219
- private readonly onPointerUp;
220
- private pickJoint;
221
- private updatePointer;
222
- private syncModelState;
223
- private endDrag;
224
- private applyHighlight;
225
- private restoreHighlight;
226
- }
227
- //#endregion
228
- //#region src/metadata.d.ts
229
- declare function extractUSDModelData(pxr: Pxr, stage: PxrObject, options?: ExtractUSDModelDataOptions): USDModelData;
381
+ //#region src/scene-data.d.ts
382
+ declare function extractUSDSceneData(pxr: Pxr, stage: PxrObject, options?: ExtractUSDSceneDataOptions): USDSceneData;
230
383
  //#endregion
231
- //#region src/three.d.ts
232
- declare function buildUSDObject(data: USDModelData, options?: BuildUSDObjectOptions): THREE.Group;
233
- declare function createUSDLoadedModel(data: USDModelData, pxr: USDLoadedModel['pxr'], rootLayerIdentifier: string, options?: BuildUSDObjectOptions, stage?: unknown): USDLoadedModel;
384
+ //#region src/three/scene.d.ts
385
+ declare function buildUSDScene(data: USDSceneData, options?: BuildUSDSceneOptions): USDSceneBuildResult;
386
+ declare function createUSDLoadedModel(data: USDSceneData, pxr: USDLoadedModel['pxr'], rootLayerIdentifier: string, options?: BuildUSDSceneOptions, stage?: unknown, resources?: Partial<USDLoadedModelResources>): USDLoadedModel;
387
+ declare function disposeUSDLoadedModel(model: USDLoadedModel): void;
234
388
  //#endregion
235
- export { type BuildUSDObjectOptions, type ExtractUSDModelDataOptions, type PxrObject, type USDAnimationInfo, type USDAssetValue, type USDFileExtension, type USDJointDriveInfo, type USDJointInfo, type USDLoadedModel, USDLoader, type USDLoaderOptions, type USDLoaderParseOptions, type USDManipulationChangeEvent, USDManipulationControls, type USDManipulationControlsOptions, type USDManipulationHoverEvent, type USDMaterialInfo, type USDMeshElement, type USDMeshGeometryData, type USDModelData, type USDShaderInfo, type USDSourceInput, type USDStageInfo, type USDTextureResolver, type USDTextureResolverContext, type USDTransformAnimation, type USDTransformAnimationSample, type USDVector2, type USDVector3, type USDVector4, type USDViewPrim, buildUSDObject, createUSDLoadedModel, extractUSDModelData };
389
+ export { type BuildUSDSceneOptions, type ExtractUSDSceneDataOptions, type PxrObject, type USDAnimationInfo, type USDAssetValue, type USDFileExtension, type USDJointDriveInfo, type USDJointInfo, type USDJointLimitInfo, type USDLoadedModel, type USDLoadedModelResources, USDLoader, type USDLoaderOptions, type USDLoaderParseOptions, type USDMaterialInfo, type USDMeshElement, type USDMeshGeometryData, type USDParsedStageData, type USDPhysicsArticulationRootInfo, type USDPhysicsColliderInfo, type USDPhysicsInfo, type USDPhysicsMassInfo, type USDPhysicsMaterialInfo, type USDPhysicsRigidBodyInfo, type USDPhysicsSceneInfo, type USDSceneBuildResult, type USDSceneData, type USDSceneIndex, type USDShaderInfo, type USDSourceInput, type USDStageCameraInfo, type USDStageInfo, type USDTextureResolver, type USDTextureResolverContext, type USDTransformAnimation, type USDTransformAnimationSample, type USDUserData, type USDUserDataValue, type USDVariantSelection, type USDVariantSetInfo, type USDVector2, type USDVector3, type USDVector4, type USDViewPrim, buildUSDScene, createUSDLoadedModel, disposeUSDLoadedModel, extractUSDSceneData };