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 в браузере: композиция USD в WebAssembly, построенная на openusd (чистый Rust), с рендерингом через three.js. Читает .usd, .usda, .usdc и .usdz; загрузка выполняется в Web Worker.

npm install @huggingface/usd-web-viewer three

Использование

Готовый просмотрщик (рендерер, освещение, орбитальные элементы управления):

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

Или в собственную сцену 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

Физика и суставы

info также сообщает о том, что авторы сцены для симуляции (UsdPhysics) и её метки UsdSemantics, как они были созданы: ничего не оценивается. Массы указаны в килограммах, плотности в кг/м³, инерция в кг·м², пределы и положения шарниров в градусах или метрах; положения и матрицы находятся в пространстве сцены, как и сетки под 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

Позирование чисто кинематическое (без учёта столкновений и гравитации) и достаточно дёшево, чтобы выполняться на каждом кадре при перетаскивании ползунка или записи.

Параметры

loadUsd(url, options) и viewer.load(url, options) принимают:

ПараметрПо умолчанию
textures'preview''none', 'preview' (базовый цвет, небольшие карты данных, без карт нормалей) или 'full'
maxTextureSize1024Длина длинной стороны декодированных текстур, в пикселях
signalСигнал AbortSignal; загрузка отклоняется с ошибкой UsdLoadError с кодом aborted
onProgressВызывается с указанием этапа и общей fraction от 0 до 1
filesЗагружайте удалённые или добавленные файлы вместо сети (см. ниже)
wasmUrl, workerUrlрядом с пакетомОткуда загружаются WASM-бинарник и скрипт воркера
maxConcurrentFetches16Запросы, выполняемые одновременно
maxLayerBytes, maxLayers768 МБ, 1024Ограничения на загрузку слоёв
maxTextureBytes512 МБОграничение на загрузку текстур
maxTriangles, maxInstances20M, 100,000Что рисуется максимум

createViewer(container, options) принимает background (по умолчанию прозрачный), onContextLost и onContextRestored (вызываются при перезагрузке последней отображаемой модели).

Сбои представлены в виде UsdLoadError с code (aborted, fetch, compose, worker, webgl); всё, что не удалось отобразить корректно, перечислено в info.warnings. Для каждого параметра, ошибки и предупреждения определён тип.

Загрузка недоверенных файлов

  • Запросы отправляются так же, как запросы <model-viewer>: куки — только для собственного источника страницы (credentials: 'same-origin'), без пользовательских заголовков и без referrer.
  • Слои и текстуры загружаются только по http(s).
  • Разбор выполняется на Rust, скомпилированном в WebAssembly, в Web Worker.
  • Каждая загрузка ограничена: maxLayerBytes (768 МиБ), maxLayers (1024), maxTextureBytes (512 МиБ), maxTriangles (20 млн) и maxInstances (100 000); изображения размером до 16384 пикс. по стороне и 8192 x 8192 пикс. по площади; примитивы вложенностью до 256 уровней; записи .usdz размером до 512 МиБ каждая и 1 ГиБ суммарно, хранящиеся без сжатия.
  • Файлы с некорректным форматом приводят к ошибке загрузки UsdLoadError.

Локальные файлы

Чтобы отобразить файлы, перетасканные на страницу или выбранные с помощью <input type="file" webkitdirectory>, передайте их в параметре files, используя в качестве ключей их пути внутри пакета, и загрузите ключ корневого слоя. Относительные пути в файлах разрешаются относительно друг друга; для них ничего не запрашивается.

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

Сборщики

Рабочий процесс и WASM-бинарник находятся с помощью new URL(..., import.meta.url), что Vite, webpack и другие сборщики разрешают и выдают. При использовании dev-сервера Vite исключите пакет из предварительной сборки зависимостей:

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

Лицензия MIT. Лицензии Rust-пакетов, скомпилированных в WASM-бинарник, приведены в THIRD_PARTY_LICENSES.

Update on GitHub