@openusd-wasm/three-loader 0.0.1 → 0.0.2
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.
|
@@ -233,6 +233,18 @@ declare class USDManipulationControls {
|
|
|
233
233
|
private restoreHighlight;
|
|
234
234
|
}
|
|
235
235
|
//#endregion
|
|
236
|
+
//#region src/asset-resolver.d.ts
|
|
237
|
+
declare function autoResolveAssetFiles(rootData: Uint8Array, options: USDLoaderParseOptions): Promise<Record<string, Uint8Array>>;
|
|
238
|
+
declare function autoResolveTextureFiles(metadata: USDModelData, existingFiles: Record<string, Uint8Array>, options: USDLoaderParseOptions): Promise<Record<string, Uint8Array>>;
|
|
239
|
+
declare function createTextureResolverFromEntries(entries: Map<string, Uint8Array>): {
|
|
240
|
+
resolve: USDTextureResolver;
|
|
241
|
+
urls: Map<string, string>;
|
|
242
|
+
} | null;
|
|
243
|
+
declare function createPackageTextureResolver(data: Uint8Array): {
|
|
244
|
+
resolve: USDTextureResolver;
|
|
245
|
+
urls: Map<string, string>;
|
|
246
|
+
} | null;
|
|
247
|
+
//#endregion
|
|
236
248
|
//#region src/metadata.d.ts
|
|
237
249
|
declare function extractUSDModelData(pxr: Pxr, stage: PxrObject, options?: ExtractUSDModelDataOptions): USDModelData;
|
|
238
250
|
//#endregion
|
|
@@ -240,4 +252,4 @@ declare function extractUSDModelData(pxr: Pxr, stage: PxrObject, options?: Extra
|
|
|
240
252
|
declare function buildUSDObject(data: USDModelData, options?: BuildUSDObjectOptions): THREE.Group;
|
|
241
253
|
declare function createUSDLoadedModel(data: USDModelData, pxr: USDLoadedModel['pxr'], rootLayerIdentifier: string, options?: BuildUSDObjectOptions, stage?: unknown): USDLoadedModel;
|
|
242
254
|
//#endregion
|
|
243
|
-
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 };
|
|
255
|
+
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, autoResolveAssetFiles, autoResolveTextureFiles, buildUSDObject, createPackageTextureResolver, createTextureResolverFromEntries, createUSDLoadedModel, extractUSDModelData };
|
|
@@ -13,7 +13,8 @@ const DEFAULT_ASSET_SEARCH_EXTENSIONS = [
|
|
|
13
13
|
".webp",
|
|
14
14
|
".ktx2",
|
|
15
15
|
".exr",
|
|
16
|
-
".hdr"
|
|
16
|
+
".hdr",
|
|
17
|
+
".mdl"
|
|
17
18
|
];
|
|
18
19
|
const DEFAULT_ASSET_SEARCH_ROOTS = [
|
|
19
20
|
"resource",
|
|
@@ -30,6 +31,20 @@ const DEFAULT_ASSET_SEARCH_ROOTS = [
|
|
|
30
31
|
];
|
|
31
32
|
const DEFAULT_MAX_ASSET_REFERENCES = 80;
|
|
32
33
|
const DEFAULT_MAX_ASSET_REFERENCE_DEPTH = 4;
|
|
34
|
+
const DEFAULT_PACKAGE_REMAP_ALIAS_COUNT = 16;
|
|
35
|
+
const USD_LAYER_EXTENSIONS = new Set([
|
|
36
|
+
".usd",
|
|
37
|
+
".usda",
|
|
38
|
+
".usdc",
|
|
39
|
+
".usdz"
|
|
40
|
+
]);
|
|
41
|
+
const TEXTURE_DIRECTORY_NAMES = new Set([
|
|
42
|
+
"img",
|
|
43
|
+
"image",
|
|
44
|
+
"images",
|
|
45
|
+
"texture",
|
|
46
|
+
"textures"
|
|
47
|
+
]);
|
|
33
48
|
function toFetchableUrl(value) {
|
|
34
49
|
try {
|
|
35
50
|
const url = new URL(value, globalThis.location?.href);
|
|
@@ -91,8 +106,8 @@ function trimAssetReference(value) {
|
|
|
91
106
|
if (/^[A-Za-z]:[\\/]/.test(ref)) return null;
|
|
92
107
|
if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(ref)) return null;
|
|
93
108
|
if (ref.startsWith("/")) return null;
|
|
94
|
-
if (
|
|
95
|
-
if (!/^[A-Za-z0-9._~!$&'()+,;=@/-]+$/.test(ref)) return null;
|
|
109
|
+
if (/[\0\r\n\t\f\v]/.test(ref)) return null;
|
|
110
|
+
if (!/^[ A-Za-z0-9._~!$&'()+,;=@/-]+$/.test(ref)) return null;
|
|
96
111
|
return ref;
|
|
97
112
|
}
|
|
98
113
|
function isUsdCrate(data) {
|
|
@@ -192,6 +207,41 @@ function buildReferencePathVariants(relativePath) {
|
|
|
192
207
|
aliases: [normalized]
|
|
193
208
|
}];
|
|
194
209
|
}
|
|
210
|
+
function buildPackageRemapAliases(sourceRelativePath, assetPath) {
|
|
211
|
+
const extension = extensionOf(assetPath);
|
|
212
|
+
if (!extension || USD_LAYER_EXTENSIONS.has(extension)) return [];
|
|
213
|
+
const name = baseName(assetPath);
|
|
214
|
+
if (!name) return [];
|
|
215
|
+
const aliasDirs = new Set([dirname(sourceRelativePath)]);
|
|
216
|
+
const assetDir = dirname(assetPath);
|
|
217
|
+
const assetParentDir = dirname(assetDir);
|
|
218
|
+
const assetTextureDir = baseName(assetDir).toLowerCase();
|
|
219
|
+
if (TEXTURE_DIRECTORY_NAMES.has(assetTextureDir)) aliasDirs.add(assetParentDir);
|
|
220
|
+
return unique([...aliasDirs].flatMap((aliasDir) => Array.from({ length: DEFAULT_PACKAGE_REMAP_ALIAS_COUNT }, (_, index) => joinRelativePath(aliasDir, `${index}/${name}`))));
|
|
221
|
+
}
|
|
222
|
+
function addPackageRemapAliases(files, aliases, data, ownedAliases, aliasConflicts, existingFiles = {}) {
|
|
223
|
+
for (const alias of aliases) {
|
|
224
|
+
if (aliasConflicts.has(alias)) continue;
|
|
225
|
+
const existingInput = existingFiles[alias];
|
|
226
|
+
if (existingInput && existingInput !== data) {
|
|
227
|
+
aliasConflicts.add(alias);
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
const existing = files[alias];
|
|
231
|
+
if (existing && existing !== data) {
|
|
232
|
+
if (ownedAliases.has(alias)) {
|
|
233
|
+
delete files[alias];
|
|
234
|
+
ownedAliases.delete(alias);
|
|
235
|
+
}
|
|
236
|
+
aliasConflicts.add(alias);
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (!existing) {
|
|
240
|
+
files[alias] = data;
|
|
241
|
+
ownedAliases.add(alias);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
195
245
|
function unique(values) {
|
|
196
246
|
return [...new Set(values)];
|
|
197
247
|
}
|
|
@@ -246,7 +296,9 @@ function buildFetchAttempts(ref, sourceUrl, sourceRelativePath, searchExtensions
|
|
|
246
296
|
seen.add(url);
|
|
247
297
|
attempts.push({
|
|
248
298
|
url,
|
|
249
|
-
fsPaths: [...fsAliases]
|
|
299
|
+
fsPaths: [...fsAliases],
|
|
300
|
+
sourceRelativePath: pathWithExtension,
|
|
301
|
+
packageRemapAliases: buildPackageRemapAliases(sourceRelativePath, pathWithExtension)
|
|
250
302
|
});
|
|
251
303
|
} catch {}
|
|
252
304
|
}
|
|
@@ -273,6 +325,8 @@ async function autoResolveAssetFiles(rootData, options) {
|
|
|
273
325
|
const maxDepth = options.maxAssetReferenceDepth ?? DEFAULT_MAX_ASSET_REFERENCE_DEPTH;
|
|
274
326
|
const rootRelativePath = normalizeFsRelativePath(options.fileName ?? fileNameForSource$1(sourcePath));
|
|
275
327
|
const files = {};
|
|
328
|
+
const ownedPackageAliases = /* @__PURE__ */ new Set();
|
|
329
|
+
const packageAliasConflicts = /* @__PURE__ */ new Set();
|
|
276
330
|
const fetchedUrls = /* @__PURE__ */ new Set();
|
|
277
331
|
const queued = /* @__PURE__ */ new Set();
|
|
278
332
|
const rootRefs = discoverAssetReferences(rootData, searchExtensions, true);
|
|
@@ -294,9 +348,13 @@ async function autoResolveAssetFiles(rootData, options) {
|
|
|
294
348
|
fetchedUrls.add(attempt.url);
|
|
295
349
|
const data = await fetchBinary(attempt.url);
|
|
296
350
|
if (!data) continue;
|
|
297
|
-
for (const fsPath of attempt.fsPaths)
|
|
351
|
+
for (const fsPath of attempt.fsPaths) {
|
|
352
|
+
ownedPackageAliases.delete(fsPath);
|
|
353
|
+
files[fsPath] = data;
|
|
354
|
+
}
|
|
355
|
+
addPackageRemapAliases(files, attempt.packageRemapAliases, data, ownedPackageAliases, packageAliasConflicts);
|
|
298
356
|
if (item.depth < maxDepth) {
|
|
299
|
-
const sourceRelativePath = attempt.
|
|
357
|
+
const sourceRelativePath = attempt.sourceRelativePath;
|
|
300
358
|
if (sourceRelativePath) for (const ref of discoverAssetReferences(data, searchExtensions, !isUsdCrate(data))) {
|
|
301
359
|
const queueKey = `${attempt.url}\n${ref}`;
|
|
302
360
|
if (queued.has(queueKey)) continue;
|
|
@@ -317,27 +375,22 @@ async function autoResolveAssetFiles(rootData, options) {
|
|
|
317
375
|
}
|
|
318
376
|
return files;
|
|
319
377
|
}
|
|
320
|
-
function
|
|
378
|
+
function isMetadataAssetReference(value, searchExtensions) {
|
|
321
379
|
if (/^(blob|data):/i.test(value)) return false;
|
|
322
380
|
if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(value)) return false;
|
|
323
381
|
if (value.startsWith("/")) return false;
|
|
324
|
-
return
|
|
325
|
-
".png",
|
|
326
|
-
".jpg",
|
|
327
|
-
".jpeg",
|
|
328
|
-
".webp"
|
|
329
|
-
].includes(extensionOf(value));
|
|
382
|
+
return searchExtensions.includes(extensionOf(value));
|
|
330
383
|
}
|
|
331
|
-
function
|
|
384
|
+
function collectMetadataAssetReferences(value, searchExtensions, refs = /* @__PURE__ */ new Set()) {
|
|
332
385
|
if (!value) return refs;
|
|
333
386
|
if (Array.isArray(value)) {
|
|
334
|
-
for (const item of value)
|
|
387
|
+
for (const item of value) collectMetadataAssetReferences(item, searchExtensions, refs);
|
|
335
388
|
return refs;
|
|
336
389
|
}
|
|
337
390
|
if (typeof value !== "object") return refs;
|
|
338
391
|
const asset = value;
|
|
339
|
-
for (const item of [asset.path, asset.url]) if (typeof item === "string" &&
|
|
340
|
-
for (const item of Object.values(value))
|
|
392
|
+
for (const item of [asset.path, asset.url]) if (typeof item === "string" && isMetadataAssetReference(item, searchExtensions)) refs.add(item);
|
|
393
|
+
for (const item of Object.values(value)) collectMetadataAssetReferences(item, searchExtensions, refs);
|
|
341
394
|
return refs;
|
|
342
395
|
}
|
|
343
396
|
async function autoResolveTextureFiles(metadata, existingFiles, options) {
|
|
@@ -347,13 +400,15 @@ async function autoResolveTextureFiles(metadata, existingFiles, options) {
|
|
|
347
400
|
if (!sourceUrl) return {};
|
|
348
401
|
const searchExtensions = options.assetSearchExtensions ?? DEFAULT_ASSET_SEARCH_EXTENSIONS;
|
|
349
402
|
const configuredSearchRoots = normalizeSearchRoots(options.assetSearchRoots);
|
|
350
|
-
const textureRefs = [...
|
|
403
|
+
const textureRefs = [...collectMetadataAssetReferences(metadata, searchExtensions)];
|
|
351
404
|
const searchRoots = unique([...inferReferencedSearchRoots(Object.keys(existingFiles), configuredSearchRoots), ...inferReferencedSearchRoots(textureRefs, configuredSearchRoots)]);
|
|
352
405
|
const maxFiles = options.maxAssetReferences ?? DEFAULT_MAX_ASSET_REFERENCES;
|
|
353
406
|
const remainingFiles = Math.max(maxFiles - uniqueFileCount(existingFiles), 0);
|
|
354
407
|
if (remainingFiles === 0) return {};
|
|
355
408
|
const rootRelativePath = normalizeFsRelativePath(options.fileName ?? fileNameForSource$1(sourcePath));
|
|
356
409
|
const files = {};
|
|
410
|
+
const ownedPackageAliases = /* @__PURE__ */ new Set();
|
|
411
|
+
const packageAliasConflicts = /* @__PURE__ */ new Set();
|
|
357
412
|
const fetchedUrls = /* @__PURE__ */ new Set();
|
|
358
413
|
let resolvedFiles = 0;
|
|
359
414
|
for (const ref of textureRefs) {
|
|
@@ -364,7 +419,11 @@ async function autoResolveTextureFiles(metadata, existingFiles, options) {
|
|
|
364
419
|
fetchedUrls.add(attempt.url);
|
|
365
420
|
const data = await fetchBinary(attempt.url);
|
|
366
421
|
if (!data) continue;
|
|
367
|
-
for (const fsPath of attempt.fsPaths)
|
|
422
|
+
for (const fsPath of attempt.fsPaths) {
|
|
423
|
+
ownedPackageAliases.delete(fsPath);
|
|
424
|
+
files[fsPath] = data;
|
|
425
|
+
}
|
|
426
|
+
addPackageRemapAliases(files, attempt.packageRemapAliases, data, ownedPackageAliases, packageAliasConflicts, existingFiles);
|
|
368
427
|
resolvedFiles += 1;
|
|
369
428
|
break;
|
|
370
429
|
}
|
|
@@ -462,6 +521,7 @@ const MATERIAL_INPUT_SUFFIXES = [
|
|
|
462
521
|
"translation",
|
|
463
522
|
"rotation"
|
|
464
523
|
];
|
|
524
|
+
const MATERIAL_ASSET_ATTRIBUTE_NAMES = new Set(["info:mdl:sourceAsset"]);
|
|
465
525
|
const JOINT_TYPES = {
|
|
466
526
|
PhysicsFixedJoint: "fixed",
|
|
467
527
|
PhysicsRevoluteJoint: "revolute",
|
|
@@ -1034,8 +1094,7 @@ function collectShaderInputs(prim, time) {
|
|
|
1034
1094
|
try {
|
|
1035
1095
|
for (const attribute of attributes) {
|
|
1036
1096
|
const name = String(attribute.GetName());
|
|
1037
|
-
if (!name.includes("inputs:")) continue;
|
|
1038
|
-
if (!MATERIAL_INPUT_SUFFIXES.some((suffix) => name.endsWith(suffix))) continue;
|
|
1097
|
+
if (!(name.includes("inputs:") && MATERIAL_INPUT_SUFFIXES.some((suffix) => name.endsWith(suffix))) && !MATERIAL_ASSET_ATTRIBUTE_NAMES.has(name)) continue;
|
|
1039
1098
|
const value = attribute.Get(time);
|
|
1040
1099
|
const connections = attribute.GetConnections();
|
|
1041
1100
|
if (value !== null && value !== void 0) inputs[name] = normalizeValue(value);
|
|
@@ -2145,4 +2204,4 @@ var USDManipulationControls = class {
|
|
|
2145
2204
|
}
|
|
2146
2205
|
};
|
|
2147
2206
|
//#endregion
|
|
2148
|
-
export { USDLoader, USDManipulationControls, buildUSDObject, createUSDLoadedModel, extractUSDModelData };
|
|
2207
|
+
export { USDLoader, USDManipulationControls, autoResolveAssetFiles, autoResolveTextureFiles, buildUSDObject, createPackageTextureResolver, createTextureResolverFromEntries, createUSDLoadedModel, extractUSDModelData };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openusd-wasm/three-loader",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.2",
|
|
5
5
|
"description": "Three.js loader for OpenUSD assets backed by @openusd-wasm/pxr.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://github.com/openusd-wasm/openusd-pxr-wasm",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"tsdown": "^0.22.0",
|
|
36
36
|
"typescript": "^6.0.3",
|
|
37
37
|
"vitest": "^4.1.5",
|
|
38
|
-
"@openusd-wasm/pxr": "0.0.
|
|
38
|
+
"@openusd-wasm/pxr": "0.0.2"
|
|
39
39
|
},
|
|
40
40
|
"publishConfig": {
|
|
41
41
|
"access": "public"
|