assimp 介绍
assimp 是一个用来导入和处理 3D 模型数据的库。它支持多种格式的 3D 模型,比如 obj、fbx 和 glb 等等。
1. 编译
assimp 的仓库地址为 https://github.com/assimp/assimp。我们克隆后,使用 CMake 进行编译。
CMake 的设置如图 1 所示,我们设置源代码路径和编译结果路径。此外还在编译选项中,指定了安装路径(CMAKE_INSTALL_PREFIX)。
设置好后,依次点击 Configure、Generate 按钮。然后点击 Open Project 按钮,打开 Visual Studio 工程,编译 INSTALL 目标即可。
在之前指定的安装路径下,我们可以得到最终想要的产物:bin 目录下是动态链接库;include 目录下是头文件;lib 目录下是导入库。
- ├─bin
- ├─include
- │ └─assimp
- │ └─Compiler
- └─lib
- ├─cmake
- │ └─assimp-5.4
- └─pkgconfig
使用的话,以 Visual Studio 举例:在项目属性页的 VC++ 目录/包含目录 里指定头文件目录;在 VC++ 目录/库目录 里指定导入库目录;在 链接器/输入/附加依赖项 里指定具体的导入库名称。
动态链接库通常放在和执行文件相同的目录,我们可以在 生成事件/生成前事件/命令行 中书写复制命令。
- xcopy /Y /D "$(ProjectDir)assimp\bin\*" "$(OutDir)"
2. 使用
我们首先使用简单的小模型,来理解 assimp 内部的数据结构和处理逻辑。
如图 2 所示,我在 Maya 中创建了三个立方体。另外两个是复制得到的。同时,我设置了纹理图片。
注意看左侧大纲视图里面的结构。立方体 1 在根节点下;一个复制的立方体在一个 group 下;另一个复制的立方体在两级 group 下。
assimp 对模型的组织逻辑也是类似这种层级结构。assimp 中的 aiNode,可以简单对应 maya 中的 group;aiMesh 可以简单对应 maya 中的几何体信息集合。
我们再结合实际代码来理解一下。代码清单 1 是 assimp 最基础的解析流程。加载模型后,会得到一个根节点 aiNode。一个 aiNode 下,会有多个 aiNode 和 aiMesh。由此依次递归遍历。
代码清单 1 的输出如下,可以看到 mesh 的名字和 maya 中几何体的名字是对应的。
- Mesh: pCube1
- Vertices count: 24
- Mesh: pasted__pCube1
- Vertices count: 24
- Mesh: pasted__pasted__pCube1
- Vertices count: 24
如代码清单 2 所示,我们可以在 aiMesh 中获取到顶点数据。
从输出结果中,我们会注意到一个问题:三个立方体的顶点坐标都是一样的,但是在图 2 的视图中,三个立方体是有位置偏移的。
- Mesh: pCube1
- Vertices count: 24
- Vertex 1: (-0.5, -0.5, 0.5)
- Vertex 2: (0.5, -0.5, 0.5)
- Vertex 3: (0.5, 0.5, 0.5)
- Vertex 4: (-0.5, 0.5, 0.5)
- Vertex 5: (-0.5, 0.5, 0.5)
- Vertex 6: (0.5, 0.5, 0.5)
- Vertex 7: (0.5, 0.5, -0.5)
- Vertex 8: (-0.5, 0.5, -0.5)
- Vertex 9: (-0.5, 0.5, -0.5)
- Vertex 10: (0.5, 0.5, -0.5)
- Vertex 11: (0.5, -0.5, -0.5)
- Vertex 12: (-0.5, -0.5, -0.5)
- Vertex 13: (-0.5, -0.5, -0.5)
- Vertex 14: (0.5, -0.5, -0.5)
- Vertex 15: (0.5, -0.5, 0.5)
- Vertex 16: (-0.5, -0.5, 0.5)
- Vertex 17: (0.5, -0.5, 0.5)
- Vertex 18: (0.5, -0.5, -0.5)
- Vertex 19: (0.5, 0.5, -0.5)
- Vertex 20: (0.5, 0.5, 0.5)
- Vertex 21: (-0.5, -0.5, -0.5)
- Vertex 22: (-0.5, -0.5, 0.5)
- Vertex 23: (-0.5, 0.5, 0.5)
- Vertex 24: (-0.5, 0.5, -0.5)
- Mesh: pasted__pCube1
- Vertices count: 24
- Vertex 1: (-0.5, -0.5, 0.5)
- Vertex 2: (0.5, -0.5, 0.5)
- Vertex 3: (0.5, 0.5, 0.5)
- Vertex 4: (-0.5, 0.5, 0.5)
- Vertex 5: (-0.5, 0.5, 0.5)
- Vertex 6: (0.5, 0.5, 0.5)
- Vertex 7: (0.5, 0.5, -0.5)
- Vertex 8: (-0.5, 0.5, -0.5)
- Vertex 9: (-0.5, 0.5, -0.5)
- Vertex 10: (0.5, 0.5, -0.5)
- Vertex 11: (0.5, -0.5, -0.5)
- Vertex 12: (-0.5, -0.5, -0.5)
- Vertex 13: (-0.5, -0.5, -0.5)
- Vertex 14: (0.5, -0.5, -0.5)
- Vertex 15: (0.5, -0.5, 0.5)
- Vertex 16: (-0.5, -0.5, 0.5)
- Vertex 17: (0.5, -0.5, 0.5)
- Vertex 18: (0.5, -0.5, -0.5)
- Vertex 19: (0.5, 0.5, -0.5)
- Vertex 20: (0.5, 0.5, 0.5)
- Vertex 21: (-0.5, -0.5, -0.5)
- Vertex 22: (-0.5, -0.5, 0.5)
- Vertex 23: (-0.5, 0.5, 0.5)
- Vertex 24: (-0.5, 0.5, -0.5)
- Mesh: pasted__pasted__pCube1
- Vertices count: 24
- Vertex 1: (-0.5, -0.5, 0.5)
- Vertex 2: (0.5, -0.5, 0.5)
- Vertex 3: (0.5, 0.5, 0.5)
- Vertex 4: (-0.5, 0.5, 0.5)
- Vertex 5: (-0.5, 0.5, 0.5)
- Vertex 6: (0.5, 0.5, 0.5)
- Vertex 7: (0.5, 0.5, -0.5)
- Vertex 8: (-0.5, 0.5, -0.5)
- Vertex 9: (-0.5, 0.5, -0.5)
- Vertex 10: (0.5, 0.5, -0.5)
- Vertex 11: (0.5, -0.5, -0.5)
- Vertex 12: (-0.5, -0.5, -0.5)
- Vertex 13: (-0.5, -0.5, -0.5)
- Vertex 14: (0.5, -0.5, -0.5)
- Vertex 15: (0.5, -0.5, 0.5)
- Vertex 16: (-0.5, -0.5, 0.5)
- Vertex 17: (0.5, -0.5, 0.5)
- Vertex 18: (0.5, -0.5, -0.5)
- Vertex 19: (0.5, 0.5, -0.5)
- Vertex 20: (0.5, 0.5, 0.5)
- Vertex 21: (-0.5, -0.5, -0.5)
- Vertex 22: (-0.5, -0.5, 0.5)
- Vertex 23: (-0.5, 0.5, 0.5)
- Vertex 24: (-0.5, 0.5, -0.5)
这就引入了 aiNode 中变换矩阵的概念。和 maya 中 group 的概念类似。在 maya 中,选中 group 进行移动或旋转等操作,操作会作用于 group 中的所有物体。aiNode 中变换矩阵也需要作用于其下的所有子内容。
如代码清单 3 所示,我们增加 aiNode 的变换矩阵的打印。
可以试一下,顶点坐标作用上变换矩阵。结果可以在 Maya 的 transform 信息中进行核对。可以验证的确是这样的。
最后,如代码清单 4 所示,我们尝试在 aiMesh 中获取纹理信息。我们打印纹理图片的路径。
可以通过打印信息验证,的确是我在 Maya 中设置的图片名字。
- Diffuse Texture 1: ..\1.gif
在这篇文章中,我们了解了 assimp 的编译和使用。也对 assimp 的 aiNode、aiMesh 组织结构有了基本的理解。具体的模型读取细节,以及模型绘制实现,会在下一篇文章中进行讲解。