Skip to content

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 认证配置。

bash
pnpm add @tripo3d/assimp

快速开始 ​

1. 注册插件托管资源(按宿主二选一,都默认挂在 /_assimp/):

ts
// vite.config.ts
import { tripoAssimp } from '@tripo3d/assimp/vite';

export default defineConfig({
  plugins: [tripoAssimp()], // 默认把 worker / wasm 挂在 /_assimp/
});
ts
// 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. 调用转换:

ts
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目标格式
FBXAutodesk FBX
GLBglTF 2.0 binary
OBJWavefront OBJ
STLSTL
ThreeMF3MF

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
ts
// 导出给 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 — 上传模型实时转换、查看输出与耗时

基于 MIT 协议发布(内部使用)