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 dans le navigateur : composition USD en WebAssembly, basée sur openusd (Rust pur), rendue avec three.js. Lit les fichiers .usd, .usda, .usdc et .usdz ; les chargements s’exécutent dans un Web Worker.

npm install @huggingface/usd-web-viewer three

Utilisation

Un visualiseur prêt à l'emploi (rendu, éclairage, contrôles d'orbite) :

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',
);

Ou dans votre propre scène 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

Physique et articulations

info signale également ce que les auteurs de la scène ont défini pour la simulation (UsdPhysics) et ses étiquettes UsdSemantics, telles qu’elles ont été créées : rien n’est estimé. Les masses sont en kilogrammes, les densités en kg/m³, les moments d’inertie en kg·m², les limites et positions des articulations en degrés ou en mètres ; les positions et les matrices sont dans l’espace de la scène, tout comme les maillages sous 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

Le positionnement est purement cinématique (sans collisions ni gravité) et suffisamment léger pour être appliqué à chaque image d'un glissement de curseur ou d'un enregistrement.

Options

loadUsd(url, options) et viewer.load(url, options) prennent :

OptionPar défaut
textures'preview''none', 'preview' (couleur de base, petites cartes de données, pas de cartes normales) ou 'full'
maxTextureSize1024Côté long des textures décodées, en pixels
signalUn AbortSignal ; le chargement est rejeté avec une UsdLoadError de code aborted
onProgressAppelé avec le stage et une fraction globale allant de 0 à 1
filesCharger les fichiers déposés ou sélectionnés au lieu du réseau (voir ci-dessous)
wasmUrl, workerUrlà côté du packageL'endroit où le binaire WASM et le script worker sont servis
maxConcurrentFetches16Demandes en cours simultanément
maxLayerBytes, maxLayers768 Mio, 1024Limites de téléchargement des couches
maxTextureBytes512 MioLimite de téléchargement de texture
maxTriangles, maxInstances20M, 100,000Ce qui est dessiné au maximum

createViewer(container, options) prend background (transparent par défaut), onContextLost et onContextRestored (appelés avec un rechargement du dernier modèle affiché).

Les échecs sont des UsdLoadError avec un code (aborted, fetch, compose, worker, webgl) ; tout ce qui n’a pas pu être affiché fidèlement est répertorié dans info.warnings. Chaque option, erreur et avertissement est typé.

Chargement de fichiers non fiables

  • Les requêtes sont envoyées comme celles de <model-viewer> : les cookies sont limités à l’origine de la page (credentials: 'same-origin'), sans en-têtes personnalisés ni référenceur.
  • Les calques et les textures sont récupérés uniquement via http(s).
  • L'analyse est exécutée en Rust compilé en WebAssembly, dans un Web Worker.
  • Chaque chargement est plafonné : maxLayerBytes (768 Mio), maxLayers (1024), maxTextureBytes (512 Mio), maxTriangles (20 M) et maxInstances (100 000) ; images d'une largeur maximale de 16384 px et d'une surface de 8192 x 8192 px ; primitives imbriquées jusqu'à 256 niveaux de profondeur ; entrées .usdz de 512 Mio chacune et 1 Gio au total, stockées sans compression.
  • Les fichiers malformés échouent au chargement avec une UsdLoadError.

Fichiers locaux

Pour afficher les fichiers déposés sur la page ou sélectionnés avec <input type="file" webkitdirectory>, passez-les en tant que files, indexés par leur chemin dans le package, et chargez la clé de la couche racine. Les chemins relatifs dans les fichiers sont résolus les uns par rapport aux autres ; rien n’est récupéré pour eux.

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

Bundlers

Le worker et le binaire WASM sont localisés à l’aide de new URL(..., import.meta.url), que Vite, webpack et d’autres bundlers résolvent et émettent. Avec le serveur de développement Vite, excluez le package du pré-bundling des dépendances :

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

Sous licence MIT. Les licences des crates Rust compilés dans le binaire WASM se trouvent dans THIRD_PARTY_LICENSES.

Update on GitHub