Assimp库详解

发布时间:2023-05-22

一、Assimp加载模型

Assimp是一个开源的3D模型导入库,可以跨平台运行,支持40+的文件格式,可以将这些文件进行转换和导入。 Assimp库的一个重要功能就是能够导入并解析多种3D模型格式的文件,可读取的3D格式包括3ds、obj、dae、blend、fbx、md5、x、ase等常见3D模型格式。 下面是一个简单的程序片段,可以将一个obj文件加载到内存中:

#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{   
    // 初始化Assimp库  
    Assimp::Importer importer;
    // 读取模型数据到scene中  
    const aiScene* scene = importer.ReadFile("/path/to/model.obj",
        aiProcess_Triangulate |
        aiProcess_FlipUVs |
        aiProcess_GenNormals);
    // 打印模型的信息  
    cout << "Model Loaded" << endl;
    cout << "Number of meshes: " << scene->mNumMeshes << endl;
    // 释放场景缓存
    importer.reset();
    delete scene;
    return 0;
}

二、Assimp库

Assimp是一个纯C库,可在多个平台上使用,包括Windows、Linux和Mac OS X。Assimp库可以使用C11特性也可以在较旧的编译器上进行编译。Assimp可以处理包括.obj、.fbx、.3ds等常用3D模型格式,并且可以将这些模型转化成OpenGL或DirectX可用的数据形式。 Assimp库提供了丰富的API和结构体,这些数据结构可以用来读取和处理3D模型数据。例如,Assimp库提供了以下API接口:

  • aiImportFile:从文件系统读取模型数据。
  • aiImportFileFromMemory:从内存读取模型数据。
  • aiExportScene:将场景数据导出到文件或内存中。
  • aiGetMaterialTexture:获取存储在材质中的纹理列表。
  • aiGetBoneTransform:计算骨骼转换矩阵。

三、Assimp 物体平移

Assimp库提供的数据结构和函数可以用于处理3D物体的平移。下面是一个示例代码,可以将模型向右平移1个单位:

void TranslateObject(aiNode* node, aiVector3D translation)
{
    // 创建平移矩阵  
    aiMatrix4x4 transMat;
    aiMatrix4x4::Translation(translation, transMat);
    // 该节点场景变换矩阵乘以平移矩阵  
    node->mTransformation *= transMat;
    // 更新所有子节点的变换矩阵  
    for(unsigned int i=0; i < node->mNumChildren; ++i)
    {
        TranslateObject(node->mChildren[i], translation);
    }
}

四、Assimp中文

Assimp库是一个开源的3D模型导入库,全称为“Open Asset Import Library”。该库的中文名称为“开放资产导入库”。

五、Assimp下载

Assimp库可以从其官方网站(https://www.assimp.org/)下载。在该网站的下载页面中提供了各种不同平台和编译器版本的Assimp库,用户可以根据自己的需要选择适合自己的版本进行下载和使用。

六、Assimp内部结构

Assimp库内部包含了多个数据结构,这些数据结构用于存储和管理3D模型数据。Assimp的内部结构包括场景(aiScene)、节点(aiNode)、材质(aiMaterial)、网格(aiMesh)等。 通过这些数据结构,用户可以访问模型中的不同组件,例如节点和材质等,并获取它们的各种属性。这些属性包括位置、旋转、缩放、纹理等。

七、Assimp 物体多个副本如何控制

Assimp库提供了许多API和工具,可以用于对3D物体的副本进行控制。例如,用户可以使用Assimp库提供的场景树和节点等数据结构,以及相应的转换函数,对物体副本进行平移、旋转、缩放等处理。 以下是一个示例程序,该程序演示了如何使用Assimp库中的节点树数据结构,来创建多个副本,并分别对其中一个物体进行平移和缩放的操作:

// 复制节点  
void CopyNode(const aiScene* scene, aiNode* node, aiNode* parentNode)
{
    aiNode* newnode = new aiNode(node->mName);
    newnode->mTransformation = node->mTransformation;
    parentNode->addChildren(newnode);
    // 向新节点添加该节点的所有子节点  
    for(unsigned int i=0; i < node->mNumChildren; i++)
    {
        CopyNode(scene, node->mChildren[i], newnode);
    }
    // 向新节点添加该节点的所有网格  
    for(unsigned int i=0; i < node->mNumMeshes; i++)
    {
        unsigned int idx = node->mMeshes[i];
        newnode->addMesh(scene->mMeshes[idx]);
    }
}
// 生成物体副本  
void CreateObjectCopies(const aiScene* scene, aiNode* rootNode, int count)
{
    // 复制节点  
    for(int i=1; i < count; i++) 
    {
        aiNode* copyNode = new aiNode("copy_" + to_string(i));
        CopyNode(scene, rootNode, copyNode);
        rootNode->addChildren(copyNode);
    }
    // 该副本的变换矩阵  
    aiMatrix4x4 transformMat = aiMatrix4x4();
    transformMat.a1 = 2.0f;
    transformMat.b2 = 2.0f;
    transformMat.c3 = 2.0f;
    // 变换第2个副本  
    aiNode* childNode = rootNode->mChildren[1];
    childNode->mTransformation *= transformMat;
    // 变换第3个副本  
    childNode = rootNode->mChildren[2];
    transformMat.a1 = 3.0f;
    transformMat.b2 = 3.0f;
    transformMat.c3 = 3.0f;
    childNode->mTransformation *= transformMat;
}