您的位置:首页 > 其它

第一次编写3dMAX 导出插件

2011-06-13 13:24 351 查看
第一次编写max场景导出插件的经验分享(仅限第一次写max插件的兄弟姐妹)

这几天第一次开始写max插件比较兴奋,作为这方面的新手有些经验和同样是新手的兄弟姐妹们分享一下

1。插件就是一个dll虽然他的名字未必输出是dll也可能是dlo,dle..

2。既然是dll就一定有一个DllMain函数

如果你和我一样什么都不懂不用害怕,打开max6sdkmaxsdksamplesimpexp中的3dsexp.vcproj这个是3ds文件的导出插件,我们就可以从他开始学起。

这个插件的函数基本都在一个文件里就是3dsexp.cpp中,我们先从入口函数DllMain看起

int controlsInit = FALSE;

BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONGfdwReason,LPVOID lpvReserved)

{

hInstance = hinstDLL;

if ( !controlsInit )

{

controlsInit = TRUE;

InitCustomControls(hInstance);

InitCommonControls();

}

switch(fdwReason)

{

case DLL_PROCESS_ATTACH:

break;

case DLL_THREAD_ATTACH:

break;

case DLL_THREAD_DETACH:

break;

case DLL_PROCESS_DETACH:

break;

}

return(TRUE);

}

基本上在你写自己的export时这个函数照抄就可以了。。。。

2。类

class _3DSClassDesc:public ClassDesc

{

public:

int IsPublic() { return 1; }

void * Create(BOOL loading = FALSE) { return new _3DSExport; }

const TCHAR * ClassName() { return GetString(IDS_TH_3DSTUDIO); }

SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; }

Class_ID ClassID() { return Class_ID(0xd1d,0); }

const TCHAR* Category() { return GetString(IDS_TH_SCENEEXPORT); }

};

这个是插件类的描述符其中IsPublic表示插件是否被用户显式调用的

Create方法创建你用来做export的类这里是3DSExport;

classname随便定

SuperClassID是父类的ID对于场景导出来说一定是SCENE_EXPORT_CLASS_ID;

ClassId是本类的ID所有插件的ID都必须唯一你可以从max6sdkmaxsdkhelpgencid.exe获取

Category可以使用GetString(IDS_TH_SCENEEXPORT);

还有DLL的4个export方法必须我们自己实现

__declspec( dllexport ) const TCHAR * LibDescription() { return GetString(IDS_TH_3DSEXPORTDLL); }

__declspec( dllexport ) int LibNumberClasses() { return 1; }

__declspec( dllexport ) ClassDesc *LibClassDesc(int i)

{

switch(i)

{

case 0: return &_3DSDesc; break;

default: return 0; break;

}

}

// Return version so can detect obsolete DLLs

__declspec( dllexport ) ULONG LibVersion() { return VERSION_3DSMAX; }



// Let the plug-in register itself for deferred loading

__declspec( dllexport ) ULONG CanAutoDefer()

{

return 1;

}

LibDescription()是描述这个插件的一个字符串可以随便定

LibNumberClasses()用来说明该插件有几个类这里是1个

LibClassDesc()返回前面定义的类描述符

以上的DLLmain和ClassDesc的派生类以及4个export函数是必须的写完这2个以后我们可以进入正题



class _3DSExport : public SceneExport

从系统类SceneExport派生出的3DSExport类是我们用来导处场景到我们自己的文件格式的

class SceneEnumProc : public ITreeEnumProc

所有对节点的访问都是通过ITreeEnumProc的派生类(这里是SceneEnumProc )来完成的

ITreeEnumProc中有个重要函数就是callback( INode *node );

这个是MAX系统回调你的函数其中max会传给给你node参数这个就是max场景中的节点

使用IScene的int EnumTree( ITreeEnumProc *proc )函数带入我们自己的Enumproc类

例如IScene->EnumTree(SceneEnumProc )l就可以使max完成回调函数。

那么IScene从哪里传来的呢?

SceneExport类有个函数int DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options); // Export file

其中的ExpInterface有个成员theScene就是这个IScene了

这样我们只要在我们自己的SceneExport类(这里是_3DSExport )的DoExport中调用

ei->theScene->EnumTree(SceneEnumProc)

那么我们必须要访问max场景文件的所有节点以及他们包含的几何数据,怎么访问呢

很简单吧 接下来要做的就是在你自己的SceneEnumProc派生类中具体实现callback函数了比如对输入的节点进行转换成你的格式等等

有关调试 如果直接调试会使得3dmax崩溃貌似3dmax6有反调试。你只要先启动max然后在vc中用调试->附加到进程3dsmax就可以顺利设置断点调试了,如果你还不明白就把3ds的export调试一边就全懂了



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhengkangchen/archive/2011/05/16/6424776.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: