ASSIMP概述

阅读更多

在3D渲染的时候,工作量比较大且比较麻烦的一件事就是建模,如果想降低这种麻烦就需要借用网络上已经存在的一些模型素材,至少这是非商用渲染程序常用手段(咱们自己写例子的时候经常这样做)。但是,由于网络中的模型格式众多,如果自己一一去解析代价也挺高的。ASSIMP作为一个开源项目,设计了一套可扩展的架构,为模型的导入导出提供了良好的支持。这里说的导入是把模型文件,解析成ASSIMP自身定义的一套模型,而导出即是把自身建立的模型结构导出为模型文件。

ASSIMP默认提供了网络上比较流行的多种模型文件格式的导入和导出,如果我们仍需要对一下特殊的文件格式做这些操作,可以自己扩展。

 

Importer :

Cpp代码   收藏代码
  1. //1.注册模型导入实现类,BaseImporter对应的是一种具体的格式的模型文件  
  2. aiReturn RegisterLoader(BaseImporter* pImp);  
  3. aiReturn UnregisterLoader(BaseImporter* pImp);  
  4.   
  5. //2.注册处理过程,BaseProcess对应一个加载后的处理过程,例如把所有的非三角形网格变成三角形网格之类的,功能很强大  
  6. aiReturn RegisterPPStep(BaseProcess* pImp);  
  7. aiReturn UnregisterPPStep(BaseProcess* pImp);  
  8.   
  9. //3.各种属性  
  10. void SetPropertyInteger(const char* szName, int iValue, bool*   bWasExisting = NULL);  
  11. void SetPropertyBool(const char* szName, bool value, bool* bWasExisting = NULL) {  
  12.         SetPropertyInteger(szName,value,bWasExisting);  
  13.     }  
  14. void SetPropertyFloat(const char* szName, float fValue, bool* bWasExisting = NULL);  
  15. void SetPropertyString(const char* szName, const std::string& sValue, bool* bWasExisting = NULL);  
  16. int GetPropertyInteger(const char* szName, int iErrorReturn = 0xffffffff) const;  
  17. bool GetPropertyBool(const char* szName, bool bErrorReturn = falseconst {  
  18.         return GetPropertyInteger(szName,bErrorReturn)!=0;  
  19.     }  
  20. float GetPropertyFloat(const char* szName, float fErrorReturn = 10e10f) const;  
  21. const std::string& GetPropertyString(const char* szName,const std::string& sErrorReturn = ""const;  
  22.   
  23. //4.IOSystem只有一个,这是ASSIMP封住好的读写文件的类,这功能不需要扩展。  
  24. void SetIOHandler( IOSystem* pIOHandler);  
  25. IOSystem* GetIOHandler() const;  
  26. bool IsDefaultIOHandler() const;  
  27.   
  28. //5.这个是意淫中的功能至少我的用的3.0版本里面,它还不是一个功能。  
  29. void SetProgressHandler ( ProgressHandler* pHandler );  
  30. ProgressHandler* GetProgressHandler() const;  
  31. bool IsDefaultProgressHandler() const;  
  32. bool ValidateFlags(unsigned int pFlags) const;  
  33.   
  34. //6.读文件最终获得一个aiScene对象  
  35. const aiScene* ReadFile(const char* pFile, unsigned int pFlags);  
  36. const aiScene* ReadFileFromMemory( const void* pBuffer,size_t pLength,unsigned int pFlags,const char* pHint = "");  
  37. const aiScene* ApplyPostProcessing(unsigned int pFlags);  
  38. const aiScene* ReadFile(const std::string& pFile, unsigned int pFlags);  
  39. void FreeScene( );  
  40. const char* GetErrorString() const;  
  41. const aiScene* GetScene() const;  
  42. aiScene* GetOrphanedScene();  
//1.注册模型导入实现类,BaseImporter对应的是一种具体的格式的模型文件
aiReturn RegisterLoader(BaseImporter* pImp);
aiReturn UnregisterLoader(BaseImporter* pImp);

//2.注册处理过程,BaseProcess对应一个加载后的处理过程,例如把所有的非三角形网格变成三角形网格之类的,功能很强大
aiReturn RegisterPPStep(BaseProcess* pImp);
aiReturn UnregisterPPStep(BaseProcess* pImp);

//3.各种属性
void SetPropertyInteger(const char* szName, int iValue, bool* bWasExisting = NULL);
void SetPropertyBool(const char* szName, bool value, bool* bWasExisting = NULL) {
SetPropertyInteger(szName,value,bWasExisting);
}
void SetPropertyFloat(const char* szName, float fValue, bool* bWasExisting = NULL);
void SetPropertyString(const char* szName, const std::string& sValue, bool* bWasExisting = NULL);
int GetPropertyInteger(const char* szName, int iErrorReturn = 0xffffffff) const;
bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const {
return GetPropertyInteger(szName,bErrorReturn)!=0;
}
float GetPropertyFloat(const char* szName, float fErrorReturn = 10e10f) const;
const std::string& GetPropertyString(const char* szName,const std::string& sErrorReturn = “”) const;

//4.IOSystem只有一个,这是ASSIMP封住好的读写文件的类,这功能不需要扩展。
void SetIOHandler( IOSystem* pIOHandler);
IOSystem* GetIOHandler() const;
bool IsDefaultIOHandler() const;

//5.这个是意淫中的功能至少我的用的3.0版本里面,它还不是一个功能。
void SetProgressHandler ( ProgressHandler* pHandler );
ProgressHandler* GetProgressHandler() const;
bool IsDefaultProgressHandler() const;
bool ValidateFlags(unsigned int pFlags) const;

//6.读文件最终获得一个aiScene对象
const aiScene* ReadFile(const char* pFile, unsigned int pFlags);
const aiScene* ReadFileFromMemory( const void* pBuffer,size_t pLength,unsigned int pFlags,const char* pHint = “”);
const aiScene* ApplyPostProcessing(unsigned int pFlags);
const aiScene* ReadFile(const std::string& pFile, unsigned int pFlags);
void FreeScene( );
const char* GetErrorString() const;
const aiScene* GetScene() const;
aiScene* GetOrphanedScene();

由于导入模型和导出模型是两个不相干的事情,所以在ASSIMP里面它们是没有任何联系的,Importer 作为导入模型的入口类,其管理的角色比较明显。以这种服务注册的模式,使代码的结构更松散。另外,上述对象都保存在ImporterPimpl里面而不是Importer 里面。

 

读取模型的过程:

Cpp代码   收藏代码
  1. //把完整的方法的主要内容提取出来  
  2. const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)  
  3. {  
  4.       // 1. 释放掉旧的内容  
  5.       if (pimpl->mScene){  
  6.              FreeScene();  
  7.        }  
  8.   
  9.       // 2.找出可以读当前文件的插件,这里存在一个隐患,如果列表里面有多个满足此文件,第一个优先采纳。  
  10.       BaseImporter* imp = NULL;  
  11.       for( unsigned int a = 0; a < pimpl->mImporter.size(); a++){  
  12.             if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, false)) {  
  13.         imp = pimpl->mImporter[a];  
  14.         break;  
  15.         }  
  16.        }  
  17.       //... 这里略过一堆蛋疼的代码,不知道编程的人怎么想的,我觉得上面就够了。  
  18.   
  19.       // 3.先更新Progress,然后再解析模型  
  20.       pimpl->mProgressHandler->Update();  
  21.       pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler);  
  22.       pimpl->mProgressHandler->Update();  // 这里为啥又要调一次?不懂  
  23.   
  24.       // 4. 这个地方还有一个后处理步骤  
  25.       if( pimpl->mScene){  
  26.         ScenePreprocessor pre(pimpl->mScene);  
  27.         pre.ProcessScene();  
  28.         pimpl->mProgressHandler->Update();  
  29.         ApplyPostProcessing(pFlags & (~aiProcess_ValidateDataStructure));  
  30.     }  
  31.     pimpl->mPPShared->Clean();  
  32.     return pimpl->mScene;  
  33. }  
//把完整的方法的主要内容提取出来
const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
{
      // 1. 释放掉旧的内容
      if (pimpl->mScene){
             FreeScene();
       }
  // 2.找出可以读当前文件的插件,这里存在一个隐患,如果列表里面有多个满足此文件,第一个优先采纳。
  BaseImporter* imp = NULL;
  for( unsigned int a = 0; a &lt; pimpl-&gt;mImporter.size(); a++){
        if( pimpl-&gt;mImporter[a]-&gt;CanRead( pFile, pimpl-&gt;mIOHandler, false)) {
	imp = pimpl-&gt;mImporter[a];
	break;
    }
   }
  //... 这里略过一堆蛋疼的代码,不知道编程的人怎么想的,我觉得上面就够了。

  // 3.先更新Progress,然后再解析模型
  pimpl-&gt;mProgressHandler-&gt;Update();
  pimpl-&gt;mScene = imp-&gt;ReadFile( this, pFile, pimpl-&gt;mIOHandler);
  pimpl-&gt;mProgressHandler-&gt;Update();  // 这里为啥又要调一次?不懂

  // 4. 这个地方还有一个后处理步骤
  if( pimpl-&gt;mScene){
	ScenePreprocessor pre(pimpl-&gt;mScene);
	pre.ProcessScene();
	pimpl-&gt;mProgressHandler-&gt;Update();
	ApplyPostProcessing(pFlags &amp; (~aiProcess_ValidateDataStructure));
}
pimpl-&gt;mPPShared-&gt;Clean();
return pimpl-&gt;mScene;

}

浓缩版的ReadFile方法,描述了整个解析过程,细节不再关注,这个插件主要强调的是用而不是修改。

 

支持的数据格式:

Assimp(Open Asset Import Library)是一个支持读取多种模型资源的开源库,当前最新的版本是3.0版,支持读取以下类型的3D模型:

  • Collada ( .dae )
  • Blender 3D ( .blend )
  • 3ds Max 3DS ( .3ds )
  • 3ds Max ASE ( .ase )
  • Wavefront Object ( .obj )
  • Industry Foundation Classes (IFC/Step) ( .ifc )
  • XGL ( .xgl,.zgl )
  • Stanford Polygon Library ( .ply )
  • *AutoCAD DXF ( .dxf )
  • LightWave ( .lwo )
  • LightWave Scene ( .lws )
  • Modo ( .lxo )
  • Stereolithography ( .stl )
  • DirectX X ( .x )
  • AC3D ( .ac )
  • Milkshape 3D ( .ms3d )
  • * TrueSpace ( .cob,.scn )Biovision BVH ( .bvh )
  • * CharacterStudio Motion ( .csm )Ogre XML ( .xml )
  • Irrlicht Mesh ( .irrmesh )
  • * Irrlicht Scene ( .irr )
  • Quake I ( .mdl )
  • Quake II ( .md2 )
  • Quake III Mesh ( .md3 )
  • Quake III Map/BSP ( .pk3 )
  • * Return to Castle Wolfenstein ( .mdc )
  • Doom 3 ( .md5* )
  • *Valve Model ( .smd,.vta )
  • *Starcraft II M3 ( .m3 )
  • *Unreal ( .3d )BlitzBasic 3D ( .b3d )
  • Quick3D ( .q3d,.q3s )
  • Neutral File Format ( .nff )
  • Sense8 WorldToolKit ( .nff )
  • Object File Format ( .off )
  • PovRAY Raw ( .raw )
  • Terragen Terrain ( .ter )
  • 3D GameStudio (3DGS) ( .mdl )
  • 3D GameStudio (3DGS) Terrain ( .hmp )
  • Izware Nendo ( .ndo )

支持以下格式的导出:

  • Collada ( .dae )
  • Wavefront Object ( .obj )
  • Stereolithography ( .stl )
  • Stanford Polygon Library ( .ply )

此外还支持对导入的模型做一些常用的处理,如把四边形转换为三角形、计算切线和副法线、将大模型分割为小模型等。

  <a href="/blog/1756120" class="next" title="ASSIMP的数据结构">ASSIMP的数据结构</a>   
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NDK是指Android平台上的原生开发工具包(Native Development Kit),用于开发C和C++的原生代码。而Assimp(Open Asset Import Library)是一个跨平台的开源模型导入库,用于解析和处理各种三维模型文件格式。 在Android应用开发中,NDK Assimp可以结合使用。通过NDK将Assimp库编译成Android平台的原生库,可以在应用中使用Assimp功能,如模型导入、材质处理、动画播放等。 NDK Assimp的使用步骤大致如下: 1. 下载和配置NDK:从官网下载安装最新版本的NDK,并配置NDK环境变量。 2. 下载Assimp源代码:从Assimp官网下载最新版本的源代码,并解压。 3. 编写Android.mk文件:在Assimp源码目录下,创建Android.mk文件,用于编译Assimp库。Android.mk文件中需要设置C/C++源文件的路径和编译选项。 4. 使用ndk-build编译:在命令行中进入Assimp源码目录,并执行ndk-build命令,将Assimp源代码编译成Android平台的动态链接库(.so文件)。 5. 将库文件添加到Android项目中:将编译生成的.so文件复制到Android项目的jniLibs目录下,以便在应用中使用Assimp库。 6. 在应用代码中使用Assimp:在Java代码中通过JNI调用Assimp的C/C++接口,实现模型导入和其他功能。 通过以上步骤,就可以在Android应用中使用NDK Assimp库,实现三维模型相关的功能。NDK Assimp可以方便地实现模型的加载和处理,为开发者提供了更多的自由度和灵活性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值