Assimp
@tripo3d/assimp· 基于自维护 assimp(WebAssembly)的 3D 模型格式转换 SDK,在浏览器 Worker 中把 GLB/FBX 转换为目标格式,开箱即用。
特性
全局单例
createAssimpConverter().convert() 一行调用,全 app 共享一个转换器,内部自管 Worker、wasm 加载、内存与超时
Worker 内执行
转换在 worker 线程进行,不阻塞主线程;wasm 仅加载一次并复用
大文件不进 bundle
glue / wasm / worker 由 vite 插件或 nuxt module 作为独立静态资源托管,业务 JS bundle 体积不受影响
类型安全
AssimpFormat 枚举 + 完整 TS 类型,与业务格式枚举解耦、可跨项目复用
元数据透传
支持根/子节点变换、删除、PBR 材质因子、taskId 品牌标识、DCC 朝向重定向
约定默认路径
资源默认挂载在 /_assimp/,与 SDK 默认 baseUrl 天然一致;注册 vite 插件或 nuxt module 即用,无需手传
安装
请先完成 GitHub Packages 认证配置。
pnpm add @tripo3d/assimp快速开始
1. 注册插件托管资源(按宿主二选一,都默认挂在 /_assimp/):
// vite.config.ts
import { tripoAssimp } from '@tripo3d/assimp/vite';
export default defineConfig({
plugins: [tripoAssimp()], // 默认把 worker / wasm 挂在 /_assimp/
});// nuxt.config.ts —— Nuxt 下用 module 替代 vite 插件(经 Nitro publicAssets 托管,dev 与部署一致生效)
export default defineNuxtConfig({
modules: ['@tripo3d/assimp/nuxt'],
});Nuxt 只需 module,不要再叠加 vite 插件:module 已同时覆盖 dev 与生产(
.output)。vite 插件那套「emit 到 outDir 根当站点根」在 Nuxt 下会落到/_nuxt/而非站点根,导致运行时/_assimp/404。
2. 调用转换:
import { AssimpFormat, createAssimpConverter } from '@tripo3d/assimp';
// 全局单例,默认 baseUrl '/_assimp/' 与插件挂载点一致,无需传参
const converter = createAssimpConverter();
// glbData: ArrayBuffer(GLB 或 FBX 二进制,自动按魔数嗅探输入格式)
const { files } = await converter.convert(glbData, {
format: AssimpFormat.FBX,
projectName: 'my-model',
});
// files: Array<{ name: string; data: Uint8Array }>
const blob = new Blob([files[0].data.buffer as ArrayBuffer]);支持的格式
AssimpFormat | 目标格式 |
|---|---|
FBX | Autodesk FBX |
GLB | glTF 2.0 binary |
OBJ | Wavefront OBJ |
STL | STL |
ThreeMF | 3MF |
USDZ 不在前端支持范围:其 tinyusdz 导出体积占 wasm ~70%,且前端产物过大/兼容性差,USDZ 由后端导出。
导出朝向(export_orientation)
通过 metadata.forward_axis 指定模型「正面」在目标坐标系里应指向的有符号轴,语义与服务端 export_orientation 一致(+x 为 canonical)。SDK 按目标格式的坐标约定折算,使各格式进 DCC/查看器时与后端 Blender 导出朝向一致。
单轴即生效。up_axis 已弃用(传入被忽略)。作用于全部导出格式。
不传≠ 显式'+x':不传forward_axis即完全不做朝向对齐(Y-up 组保持模型原始 Y-up 姿态);显式传值(含'+x')会叠加绕竖直轴 180° 基准校正以对齐服务端 canonical,故'+x'相对「不传」差 180° 偏航。
| 目标朝向 | forward_axis |
|---|---|
| Blender / 3ds Max(正面朝 -Y) | -y |
| 服务端 canonical 姿态 | +x |
// 导出给 Blender:正面朝 -Y(进 Blender 默认导入即 Z-up、面朝 -Y)
const { files } = await converter.convert(glbData, {
format: AssimpFormat.FBX,
projectName: 'my-model',
metadata: { forward_axis: '-y' },
});按输出格式坐标约定分组处理:Y-up 组(glTF/GLB/OBJ/FBX) 保持 Y-up、仅绕竖直轴偏航,交消费端(Blender/DCC 导入器)做 Y-up→自身 up 转换;Z-up 组(STL/3MF) 几何烘成 Z-up。朝向与节点层级一并烘进顶点、节点归一。
触底居中(
pivot_to_center_bottom)默认开启;触底轴按格式分组自动选择(Y-up 组沿 Y、Z-up 组沿 Z)。
资源与打包
glue / wasm / worker 是独立静态资源(不打进 JS bundle),运行时由 @tripo3d/assimp 的 vite 插件(纯 Vite/SPA)或 nuxt module(Nuxt)以 baseURL(默认 /_assimp/)托管,worker 与 wasm 在运行时经 fetch 从站点根加载。
自定义挂载点
默认 /_assimp/ 已能开箱即用。若要改路径,须两边同时改并保持一致:
- Vite:
tripoAssimp({ baseURL: '/x/' })+createAssimpConverter({ baseUrl: '/x/' }) - Nuxt:
['@tripo3d/assimp/nuxt', { baseURL: '/x/' }]+createAssimpConverter({ baseUrl: '/x/' })
Nuxt 不要与 vite 插件叠加
Nuxt 项目只用 nuxt module。它经 Nitro publicAssets 同时覆盖 dev 与生产(.output);vite 插件在 Nuxt 的 client 构建里 emit 的资源会落到 /_nuxt/ 而非站点根,SDK 请求的 /_assimp/ 因此 404。
仅浏览器 / Worker 环境
导入与 createAssimpConverter() 在服务端安全(不会让 SSR 渲染崩溃);但 convert() 依赖 Worker,在服务端调用会返回 rejected Promise(需 try/catch 或仅在客户端触发),不要依赖它在服务端完成。
下一步
- API Reference — 完整 API 文档(自动生成)
- Playground — 上传模型实时转换、查看输出与耗时