技术经验分享:ASSIMP概述

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 技术经验分享:ASSIMP概述

阅读更多


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


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


Importer :


Cpp代码


//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();


//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 //代码效果参考:http://www.jhylw.com.cn/210633659.html

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代码


//把完整的方法的主要内容提取出来 const aiScene Importer::ReadFile( const char _pFile, unsigned int pFlags) { // 1. 释放掉旧的内容 //代码效果参考:http://www.jhylw.com.cn/470929351.html

if (pimpl->mScene){ FreeScene(); } // 2.找出可以读当前文件的插件,这里存在一个隐患,如果列表里面有多个满足此文件,第一个优先采纳。 BaseImporter imp = NULL; for( unsigned int a = 0; a mImporter.size(); a++){ if( pimpl->mImporter【a】->CanRead( pFile, pimpl->mIOHandler, false)) { imp = pimpl->mImporter【a】; break; } } //... 这里略过一堆蛋疼的代码,不知道编程的人怎么想的,我觉得上面就够了。 // 3.先更新Progress,然后再解析模型 pimpl->mProgressHandler->Update(); pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler); pimpl->mProgressHandler->Update(); // 这里为啥又要调一次?不懂 // 4. 这个地方还有一个后处理步骤 if( pimpl->mScene){ ScenePreprocessor pre(pimpl->mScene); pre.ProcessScene(); pimpl->mProgressHandler->Update(); ApplyPostProcessing(pFlags & (~aiProcess_ValidateDataStructure)); } pimpl->mPPShared->Clean(); return pimpl->mScene; }

//把完整的方法的主要内容提取出来


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 [/span> pimpl-

if( pimpl-

imp = pimpl-

break;


}


}


//... 这里略过一堆蛋疼的代码,不知道编程的人怎么想的,我觉得上面就够了。


// 3.先更新Progress,然后再解析模型


pimpl-

pimpl-

pimpl-

// 4. 这个地方还有一个后处理步骤


if( pimpl-

ScenePreprocessor pre(pimpl-

pre.ProcessScene();


pimpl-

ApplyPostProcessing(pFlags & (~aiProcess_ValidateDataStructure));


}


pimpl-

return pimpl-

// 2.找出可以读当前文件的插件,这里存在一个隐患,如果列表里面有多个满足此文件,第一个优先采纳。


BaseImporter imp = NULL;


for( unsigned int a = 0; a [/span> pimpl-

if( pimpl-

imp = pimpl-

break;


}


}


//... 这里略过一堆蛋疼的代码,不知道编程的人怎么想的,我觉得上面就够了。


// 3.先更新Progress,然后再解析模型


pimpl-

pimpl-

pimpl-

// 4. 这个地方还有一个后处理步骤


if( pimpl-

ScenePreprocessor pre(pimpl-

pre.ProcessScene();


pimpl-

ApplyPostProcessing(pFlags & (~aiProcess_ValidateDataStructure));


}


pimpl-

return pimpl-

}


浓缩版的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 )


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


[span class="hljs-name">a href="/blog/1756120" class="next" title="ASSIMP的数据结构"

相关文章
|
3月前
|
机器学习/深度学习 人工智能 Kubernetes
技术探索之旅:从基础到进阶的心得体会
本文记录了作者在技术领域的学习和实践过程中积累的经验与感悟。文章涵盖了从基础知识的学习、项目实践,到新技术的探索与应用,最终总结出几点对未来技术发展的思考。希望这些分享能够启发更多的技术爱好者,共同进步。
|
5月前
|
前端开发 API 数据库
探索后端开发之巅:从基础到高级实践
【8月更文挑战第29天】在技术的世界里,后端开发是一块基石,它支撑着无数应用的运行和数据的处理。本文将带你从零基础开始,逐步深入到后端开发的高级实践,包括语言选择、框架搭建、数据库设计、API开发以及性能优化等方面。我们将通过浅显易懂的语言和实际代码示例,帮助你构建起坚实的后端开发知识体系,让你能够自信地应对各种后端挑战。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供宝贵的学习资源和实践指导。
|
7月前
|
数据可视化 BI OLAP
技术经验分享:DundasBI简介
技术经验分享:DundasBI简介
53 0
|
7月前
|
存储 安全 物联网
技术经验分享:FIDO标准简介
技术经验分享:FIDO标准简介
|
7月前
|
C++ 开发者
技术经验分享:dumpbin的使用方法_dumpbin的基础使用
技术经验分享:dumpbin的使用方法_dumpbin的基础使用
386 0
|
7月前
|
存储 C# 索引
技术经验分享:C#入门详解(8)
技术经验分享:C#入门详解(8)
37 0
|
存储 数据可视化 Shell
一篇文章,带你了解CodeTour与入门指导
一篇文章,带你了解CodeTour与入门指导
358 0
|
消息中间件 运维 Kubernetes
分享实录 | 阿里巴巴测试环境管理实践概述
在软件研发过程中,“测试环境”是部署最频繁、也是开发者使用最频繁的一种运行环境,稳定而易用的测试环境能够极大提高开发者的工作效率和幸福感。为更好的将阿里巴巴在测试环境管理方面的实践和经验跟广大开发者分享,《云效说码》策划了《阿里巴巴Kubernetes测试环境开源工具箱》系列直播视频,由阿里巴巴技术专家林帆(金戟)和郑云龙(砧木) 来为大家讲述。
4672 1
分享实录 | 阿里巴巴测试环境管理实践概述
|
运维 Kubernetes Cloud Native
技术人如何成长?阿里的专家给出了这些建议 | 开发者必读(176期)
如何走出焦虑,在工作中快速成长?关于高效沟通和认知升级这些事,看看阿里的专家都怎么说~
1457 0
|
开发者 vr&ar 城市大脑
首次公开!技术人进阶必看的10位阿里大牛思维方式 | 开发者必读(066期)
最炫的技术新知、最热门的大咖公开课、最有趣的开发者活动、最实用的工具干货,就在《开发者必读》!
1371 0