Huggingface.js documentation

@huggingface/usd-web-viewer

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

@huggingface/usd-web-viewer

OpenUSD en el navegador: composición de USD en WebAssembly, construido sobre openusd (Rust puro), renderizado con three.js. Lee .usd, .usda, .usdc y .usdz; las cargas se ejecutan en un Web Worker.

npm install @huggingface/usd-web-viewer three

Uso

Un visor listo para usar (renderizador, iluminación, controles de órbita):

import { createViewer } from '@huggingface/usd-web-viewer';

const viewer = createViewer(document.getElementById('viewer')); // a container element
const { info } = await viewer.load(
  'https://huggingface.co/datasets/Robotiq-Official/simready-assets/resolve/main/Robotiq_2F_85/simready_usd/Robotiq_2F_85.usda',
);

O en tu propia escena de three.js:

import { loadUsd } from '@huggingface/usd-web-viewer';

const { root, complete, dispose } = await loadUsd(url);
scene.add(root); // a THREE.Group, Y-up, in meters
await complete; // textures stream in after the geometry

Física y articulaciones

info also reports what the stage authors for simulation (UsdPhysics) and its UsdSemantics labels, as authored: nothing is estimated. Masses are in kilograms, densities in kg/m³, inertia in kg·m², joint limits and positions in degrees or meters; positions and matrices are in stage space, like the meshes under root.

const { info, joints, setJointPositions, resetJointPositions, getJointPositions, getWorldMatrix } = await viewer.load(url);

info.physics.bodies; // rigid bodies: mass, center of mass, inertia, colliders, bodies fixed to them
info.physics.colliders; // shape, approximation (convexHull, sdf, ...), physics material
info.physics.materials; // density, friction, restitution
info.physics.joints; // revolute, prismatic, spherical, distance, fixed and generic joints with their limits and drives
info.physics.articulationRoots; // where articulations (bodies solved together, like a robot) start
info.physics.frames; // Xforms under a body, often points with no mesh, like a gripper's tip
info.labels; // e.g. { path: '/RootNode', taxonomy: 'wikidata_class', values: ['cabinet'] }
info.variantSelections; // e.g. { prim: '/Robotiq_2F_85', set: 'Physics', selection: 'Physx_parallel_grip' }
info.dependencies; // every layer and texture the stage read, with its size

joints; // the joints setJointPositions can move, e.g. to build sliders
setJointPositions({ '/Robotiq_2F_85/Robotiq_2F_85/Joints/finger_joint': 40 }); // revolute and prismatic joints, any number at once; what hangs from them and mimic joints follow
getJointPositions(); // where every revolute and prismatic joint is now
getWorldMatrix('/SO101/gripper/gripper_frame_link'); // where a body, frame or mesh under a body is now and which way it faces, as a THREE.Matrix4 in the scene; null if it is none of those
resetJointPositions(); // back to the authored pose

El posicionamiento es puramente cinemático (sin colisiones ni gravedad) y lo suficientemente económico para cada cuadro de un arrastre de control deslizante o de una grabación.

Opciones

loadUsd(url, options) y viewer.load(url, options) aceptan:

OpciónPredeterminado
textures'preview''none', 'preview' (color base, mapas de datos pequeños, sin mapas normales) o 'full'
maxTextureSize1024Lado largo de las texturas decodificadas, en píxeles
signalUna AbortSignal; la carga se rechaza con un UsdLoadError de código aborted
onProgressLlamado con la etapa y una fraction global de 0 a 1
filesCargar archivos descartados o seleccionados en lugar de la red (ver más abajo)
wasmUrl, workerUrljunto al paqueteDesde dónde se sirven el binario WASM y el script del worker
maxConcurrentFetches16Solicitudes en curso simultáneamente
maxLayerBytes, maxLayers768 MiB, 1024Límites de descarga de capas
maxTextureBytes512 MiBLímite de descarga de texturas
maxTriangles, maxInstances20M, 100,000Lo que se dibuja como máximo

createViewer(container, options) acepta background (transparente por defecto), onContextLost y onContextRestored (se llaman con una recarga del último modelo mostrado).

Los fallos son UsdLoadError con un code (aborted, fetch, compose, worker, webgl); todo lo que no se pudo mostrar de forma fiel se enumera en info.warnings. Cada opción, error y advertencia tiene un tipo definido.

Carga de archivos no confiables

  • Las solicitudes se envían como las de <model-viewer>: solo se envían cookies al origen de la página (credentials: 'same-origin'), sin encabezados personalizados y sin referrer.
  • Las capas y texturas se obtienen solo a través de http(s).
  • El análisis se ejecuta en Rust compilado a WebAssembly, en un Web Worker.
  • Cada carga tiene un límite: maxLayerBytes (768 MiB), maxLayers (1024), maxTextureBytes (512 MiB), maxTriangles (20M) y maxInstances (100,000); imágenes de hasta 16384 px de lado y 8192 x 8192 px de área; prims anidados hasta 256 niveles de profundidad; entradas .usdz de hasta 512 MiB cada una y 1 GiB en total, almacenadas sin comprimir.
  • Los archivos malformados provocan un error de carga con UsdLoadError.

Archivos locales

Para mostrar los archivos soltados en la página o seleccionados con <input type="file" webkitdirectory>, páselos como files, con su clave según su ruta en el paquete, y carga la clave de la capa raíz. Las rutas relativas dentro de los archivos se resuelven entre sí; no se realiza ninguna solicitud para ellas.

const files = new Map([...input.files].map((file) => [file.webkitRelativePath || file.name, file]));
await viewer.load('chair/simready_usd/sm_chair.usd', { files });

Empaquetadores

El worker y el binario WASM se encuentran con new URL(..., import.meta.url), que Vite, webpack y otros bundlers resuelven y emiten. Con el servidor de desarrollo de Vite, excluya el paquete del pre-bundling de dependencias:

// vite.config.js
export default { optimizeDeps: { exclude: ['@huggingface/usd-web-viewer'] } };

Licencia MIT. Las licencias de los crates de Rust compilados en el binario WASM están en THIRD_PARTY_LICENSES.

Update on GitHub