好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

3ds Max插件制作方法.doc

3页
  • 卖家[上传人]:夏**
  • 文档编号:538105431
  • 上传时间:2023-10-05
  • 文档格式:DOC
  • 文档大小:38KB
  • / 3 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 深圳国家音乐创意产业基地数字动漫学校3ds Max插件制作方法3DS Max 插件制作的学习方法要从3ds Max中导出场景信息,大概有两种方式:1.利用3ds Max的sdk制作插件2.利用3ds Max的Max Script编写场景输出脚本两种方式各有优劣,这里仅叙述我用了数天研究3ds Max SDK并制作插件的学习心得   1.前期环境配置工作   首先肯定要安装带SDK的3ds Max,我安装的是3ds Max7安装后在maxsdk\help下有个sdkapwz.zip,把这个文件解压到VS 6.0或VS 2003的application wizard路径下,启动VS就会有3ds Max plug-in的应用程序向导来生成插件程序的框架   2.制作插件需要了解的几个基本概念   2.1 我所了解的插件原理是:3ds Max会公布一些接口,插件制作者需要做的是实现这些接口例如利用向导生成一个用于场景导出的插件就会发现在生成的程序中有一个类继承于class SceneExport,而 SDK 中关于这个接口的描述是:   This is a base class for creating file export plug-ins. The plug-in implements methods of this class to describe the properties of the export plug-in and a method that handles the actual export process.   再看下面的函数说明,可以看到函数是虚函数的方式声明的,所以必须要将其所有的函数进行实现。

        2.2 3ds Max是怎样识别插件的接口?还是以上面的场景到处插件为例,程序中还会生成一个继承于 ClassDesc2的类,这个类会实现一些关于类的ID,层次信息处理的函数估计系统就是根据这个识别处我的插件的接口,没有具体去研究,只了解个大概   2.3 如何调试所编写的插件,SDK中有说明,我这里简单说一下,将工程属性设置为Hybrid(默认是Debug),并且把输出dle文件的路径设为3ds Max的plug-in的路径,再把调试的可执行程序设为3ds Max.exe,这样 调试的时候就会启动3ds Max主程序,其他诸如设置断点,单步等调试手段和普通程序的调试方法一样   3.通过一个例子学习插件编程   这部分还真不好写,涉及到一些代码,代码中又有很多API需要讲解,API中又有很多基本知识需要说明,唉,硬着头皮来吧   还是以那个场景导出类为例,可以看到,SceneExport中有个非常重要的函数需要实现: virtual int DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts=FALSE, DWORD options=0) = 0;   先看看参数:   name 表示要导出的文件名。

        ei 用来枚举场景,需要注意的是:由于这个函数是由系统调用的,所以这个参数是系统传递的,不 用去思考怎么实现ExpInterface这个接口   i 提供一个用来调用3ds Max方法的指针,可以把它视作一个指向3ds Max的指针同样,这个指针 也是由系统传递的   剩下两个参数暂不关心   现在来研究ei和i两个参数:   class ExpInterface仅包含一个成员:IScene *theScene这样的类设计的简直是“无耻”再去研究IScene吧IScene中有一个很重要的函数: virtual int EnumTree( ITreeEnumProc *proc )=0;   根据SDK的说明,该函数的功能是:用来枚举场景中的每个INode因此需要一个ItreeEnumProc*作为参数,由于是自己调用整个函数,因而必须自己实现ItreeEnumProc接口,还好这个接口不是很复杂,把这个回调函数实现就可以了: virtual int callback( INode *node )=0;   因为是回调函数,所以node也是系统传递进来的,为了证明这一点,我们可以编程实验一下: class MyEnumProc: public ITreeEnumProc ...{ public: int callback( INode *node ) ...{ int a = 0; //在这里设置断点 return a; } }   在MyExport中添加这一个成员变量: MyEnumProc MyProc; int MyExport::DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options) ...{ /**//*在函数中添加这行代码*/ ei->theScene->EnumTree(&this->MyProc ); if(!suppressPrompts) DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_PANEL), GetActiveWindow(), MY5OptionsDlgProc, (LPARAM)this); return FALSE; }   调试这个例子,在场景中绘制三个立方体,可以看到系统会调用callback三次,这说明一个物体就是一个Node。

      那么怎么来导出一个Node几何信息呢?看下面这个代码 public: int callback( INode *node ) ...{ Object *lobj; lobj = node->GetObjectRef(); if (lobj->SuperClassID()== GEOMOBJECT_CLASS_ID) ...{ GeomObject* gobj = (GeomObject*)lobj; Class_ID triID = Class_ID(TRIOBJ_CLASS_ID,0); Class_ID boxID = Class_ID(BOXOBJ_CLASS_ID,0); if (lobj->ClassID()==boxID) ...{ if (lobj->CanConvertToType(triID)) ...{ TriObject *triobj = (TriObject *)lobj->ConvertToType (0,triID); Mesh mesh = triobj->mesh; int numVerts = mesh.getNumVerts(); } IParamArray* array = lobj->GetParamBlock(); float length = 0.0f; float height = 0.0f; float width = 0.0f; array->GetValue( lobj->GetParamBlockIndex(BOXOBJ_LENGTH), 0, length, FOREVER); array->GetValue( lobj->GetParamBlockIndex(BOXOBJ_HEIGHT), 0, height, FOREVER); array->GetValue( lobj->GetParamBlockIndex(BOXOBJ_WIDTH), 0, width, FOREVER); } }   首先node->GetObjectRef()会返回这个节点的物体引用。

      关于ObjectRef有一套几何流水线的说明,这里实在是没功夫写了接着首先判断这物体的SuperClassID是否为GEOMOBJECT_CLAS- S_ID,如果是,则再看它是否能转换为TriObject,即由三角形组成的物体,至于为什么要这样转,我只能说只有这个类可以返回一个Mesh,而通过Mesh能够获得诸如顶点,法线,面等一般3D程序所需要的几何信息(这里只获取了该Mesh的面的个数)当然,对于一个Box,我们可能只想获得它的长宽高,所以,代码中又提供了另一个方法来返回其几何信息   虽然只实现了这么短的代码,但却花了数天的时间,主要对3ds Max的结构不熟悉,加上SDK写得真叫一个乱,还好总算有些进展,正所谓万事开头难下一步将研究如何导出场景的光照,物体的纹理贴图等信息。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.