您现在的位置: 万盛学电脑网 >> 软件知识 >> 图文处理 >> 3DSMAX教程 >> 正文

3ds max sdk导出插件编写

作者:佚名    责任编辑:admin    更新时间:2022-06-22

   感觉3ds Max SDK实在是博大精深,初学者入门还是很不方便,所以觉得以前发的心得应该得到补充,因而写了这样一个导出程序介绍,还是抱着学习的态度,不过还是希望能够对大家有所帮助。

  想想研究3D MAX 的SDK已经有了不短的时间,真正算起来也有两个月了吧,但是讲到收获,确实不大。作为一个3D MAX二次开发的学习者,我首先学习了导出插件的编写,网上有很多参考资料,写的都差不多,可是都是写到关键的地方或者说比较模糊的地方就说不清楚了,今天我就结合自己所做的工作来讲讲3D MAX导出插件的编写心得。

  环境配置:

  步骤1.首先你得有VS2005,3ds Max 9,如果有就好办了,否则想办法搞到手吧,在中国做到这点应该不难。至于其他相近版本的IDE和MAX,情况基本类似。

  步骤2.在3ds Max9 SDK"maxsdk"howto"3dsmaxPluginWizard中有个readme.txt,它会向你介绍如何配置3ds Max9 plugin的向导。

  步骤3.启动vs2005,新建Visual C++项目,如果在右侧的模板组中能够找到”3dsmaxPluginWizard”,并且选择后能够弹出欢迎界面,说面配置已经成功了。

  首先,需要做好如下的准备工作:

  1. 安装一个完整版本的3D MAX与Visual Stdio。

  我安装的是3D MAX 2009,最好是找一个完整的版本,因为完整的版本中有很多的学习资料与sdk供学习,很省事。3D MAX的二次开发对VS的要求是有一个对应关系的,在SDK文档中可以找到,3D MAX 2009对应的VS开发版本应该是VS 2005,确保电脑上已经安装了VS 2005。

  2.定制3D MAX plug-in向导。

  a.找到安装目录的3dsmaxPluginWizard文件夹(我的安装目录是C:Program FilesAutodesk3ds Max 9 SDKmaxsdkhowto3dsmaxPluginWizard

  ),

  b.打开此目录下的MaxPluginWizard.vsz 文件,编辑ABSOLUTE PATH参数为:

  Param="ABSOLUTE_PATH=C:Program FilesAutodesk3ds Max 9SDKmaxsdkhowto3dsmaxPluginWizard"

  c.将3dsmaxPluginWizard文件夹下的三个文件3dsmaxPluginWizard.ico、3dsmaxPluginWizard.vsdir、3dsmaxPluginWizard.vsz拷贝到VS 2005安装目录的 VC Projects 目录下,我电脑上的目录是C:Program FilesMicrosoft Visual Studio 8VCvcprojects。

  d.启动VS 2005,File-New Project,选择Visual C++就可以看到3ds max Plugin Wizard选项,说明定制成功。

  以上只是开发前的一些准备工作,都可以直接在3D MAX SDK的文档中直接找到,不过文档可都是英文的哦,要耐心的读下去。

  在以上准备工作做好以后,就可以开始开发一个插件了,由简单到复杂,先做一个简单的插件程序。插件程序的编写有两种方法,一是用插件向导,就是刚才上面所说的;另一种是通过手工创建一个插件项目,在这里暂时只讨论用插件向导来开发,比较便捷,手工开发以后在补上。

  1.第一步,生成一个插件程序的工程,具体如下:

  a. 打开File —>New Project —>选择3ds max Plugin Wizard,输入project名字,如 “MyExport”。

  b. 进入Welcome to the 3ds max Plugin Wizard 画面,选择plugin type如图所示:

3ds max sdk导出插件编写 三联

  c.这里显示各种插件类型,目前要做的是一个文件的导出插件,所以选择FileExport类型。

  d.下一步,再出现一个对话框

  不用去管这些Plugin Detail,会有默认路径的,。

  e.再下一步,设置一些路径,具体见图及注明。

  注明:

  Enter your MAXSDK path指的是3D MAX SDK的安装目录

  Enter your Plugin output path 指的是生成插件文件.dll存放的目录,可以自己设置

  Enter your 3dsmax.exe path指的是3D MAX的安装目录

  2.项目生成以后,在MyExport.cpp文件中找到Ext(int n)函数,改为return _T("MY3D"), "MY3D"是根据自己的要求来添加的;

  找到ShortDesc()函数,改为return _T ("MyExportPlugin");

  找到DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options)内添加:

  AllocConsole();

  _cprintf( "Export Beginn" );//记得#include

  3. 生成并调试你的插件,系统会执行3dsmax.exe以启动3ds Max,然后选择“文件”->”导出”,如果能看到"MyExportPlugin(*.My3D)"

  说明导出成功,然后定义一个导出文件的名称即可.这样一个空的导出插件就编写成功了!接下来请看: 3D MAX导出插件编写II

  Export利器:IGame

  古人云:君子生非异也,善假于物也

  数据导出是一个繁琐的工作,于是,有了IGame这个解脱程序员的东西:

  关于IGame

  IGame是Max提供给游戏开发的一个用于导入导出的接口。在Max的help里面这个东西叫做3ds Max Data Exchange Interface。有了这个接口,可以大大的简化导入导出工作的工作量。

  如果有经历过用MAX SDK导出关键帧动画以及骨骼动画,Skin,Modifier等等的经历的话,我想肯定会记忆深刻。IGame的作用就是把复杂的Max的概念简化,封装。

  建立IGame:

  IGameScene * m_pIgame= GetIGameInterface()

  坐标系:

  前面我提到的导出的文章都没有提这个问题,所有的坐标都是用的MAX本身的坐标系,及Z轴向上。在游戏中坐标系可能千奇百怪,IGame考虑到这点提供了指定坐标系的功能:

  IGameConversionManager * cm = GetConversionManager();

  cm->SetCoordSystem(IGameConversionManager::IGAME_D3D);

  m_pIgame->InitialiseIGame(true);

  其中IGAME_D3D就是指定的坐标系,同样也可以自定义坐标系:

  UserCoord WhackySystem = {

  1, //Right Handed

  1, //X axis goes right

  4, //Y Axis goes in

  3, //Z Axis goes down.

  0, //U Tex axis is left

  1, //V Tex axis is Down

  };

  IGameConversionManager * cm = GetConversionManager();

  cm->SetUserCoordSystem(WhackySystem);

  IGame要点:

  GetTopLevelNodeCount:获得顶级的Node数目,不包括Root。

  GetRootMaterialCount:获得所有的材质数目

  GetTopLevelNode(i):获得指定Node

  GetIGameObject():获得Node中包含的Object

  GetLocalTM():获得Node的矩阵

  IGameMesh ::GetVertex(i):获得顶点

  IGameMesh ::GetFace(i);获得面

  IGameMesh ::GetNormal(i):获得法线

  至于其他就依次类推了,从函数的命名,到概念的简化,无疑都比原始的MAXSDK进步了很多。有了IGame接口,大大减轻了程序员的负担,我相信没有哪个愿意把大把的时间花在数据的导入导出上。

  花了几十分钟简单的试用了一下IGame写了个小小的导出插件,只导出了顶点,面,材质,法线以及矩阵,感觉基本上没什么阻碍。不过IGame最大的功能还是用在骨骼动画,关键帧动画上面,仅仅只是简单的几何体导出并不能体现出IGame的功效。

  最后还是附上代码和工程吧。不得不提示一下,由于种种曲折的原因,我这个工程是在MAX8 SDK和 MAX8下 完成的,其间省略上千字曲折的经历,不过在MAX9下应该可以通过编译。编译完成后,记得在Max 中选择Export Selected而不是试用Export。

  3DS MAX PlugIn 材质和纹理 材质和纹理的信息都位于node 中

  材质的信息通过类Mtl获得

  纹理的信息位于node中的mesh 中的UVVert

  以下是获得材质的代码:

  //////////////////////////////////////////////////////////////////////////

  //material

  Mtl* nodematerial=node->GetMtl();

  if(nodematerial)

  {

  fprintf(m_fileStream, "%s mtl -- name: