游戏开发论坛

 找回密码
 立即注册
搜索
查看: 13064|回复: 17

第一次编写max场景导出插件的经验分享(仅限第一次写max

[复制链接]

9

主题

53

帖子

87

积分

注册会员

Rank: 2

积分
87
发表于 2008-4-24 00:19:00 | 显示全部楼层 |阅读模式
这几天第一次开始写max插件比较兴奋,作为这方面的新手有些经验和同样是新手的兄弟姐妹们分享一下
1。插件就是一个dll虽然他的名字未必输出是dll也可能是dlo,dle..
2。既然是dll就一定有一个DllMain函数
如果你和我一样什么都不懂不用害怕,打开max6sdk\maxsdk\samples\impexp中的3dsexp.vcproj这个是3ds文件的导出插件,我们就可以从他开始学起。
这个插件的函数基本都在一个文件里就是3dsexp.cpp中,我们先从入口函数DllMain看起
int controlsInit = FALSE;
BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,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都必须唯一你可以从max6sdk\maxsdk\help\gencid.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类是我们用来导处场景到我们自己的文件格式的
那么我们必须要访问max场景文件的所有节点以及他们包含的几何数据,怎么访问呢
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)

很简单吧 接下来要做的就是在你自己的SceneEnumProc派生类中具体实现callback函数了比如对输入的节点进行转换成你的格式等等
    有关调试 如果直接调试会使得3dmax崩溃貌似3dmax6有反调试。你只要先启动max然后在vc中用调试->附加到进程3dsmax就可以顺利设置断点调试了,如果你还不明白就把3ds的export调试一边就全懂了

1

主题

57

帖子

59

积分

注册会员

Rank: 2

积分
59
QQ
发表于 2008-4-24 10:31:00 | 显示全部楼层

Re:第一次编写max场景导出插件的经验分享(仅限第一次写

    首先对你跟大家分享经验的做法表示肯定.
    其次提个醒,max的插件经常出现版本不兼容的情况,现在的美工们都用max9或以上的版本了,而max的sdk更新速度赶不上,而且如果max出个新版本就要换个新sdk的话,那简直让人疯掉.还是用maxscript来进行导出导入为好,毕竟max对它的脚本的兼容性很好,我以前max7上写的脚本现在在max2009上用都没问题,试问用max7sdk开发的插件可以做到这样吗?
    最后就是要建议大家,是时候转向学习xsi的插件开发了.因为现在的xsi越来越受美工们的青睐(我公司的美工现在都用的xsi建模),而且xsi直接导出.x之类的现成格式的文件出问题少(你想想,微软的软件会导出有问题的.x文件吗),再加上xsi的插件开发支持超多.现在我见了max相关的都想吐

2

主题

61

帖子

61

积分

注册会员

Rank: 2

积分
61
发表于 2008-4-24 11:50:00 | 显示全部楼层

Re:第一次编写max场景导出插件的经验分享(仅限第一次写

顶下

9

主题

53

帖子

87

积分

注册会员

Rank: 2

积分
87
 楼主| 发表于 2008-4-24 12:07:00 | 显示全部楼层

Re:第一次编写max场景导出插件的经验分享(仅限第一次写

是曾经想过用脚本~但是脚本语言还要学比较麻烦所以后来还是觉定用Sdk了~~

1

主题

57

帖子

59

积分

注册会员

Rank: 2

积分
59
QQ
发表于 2008-4-24 12:12:00 | 显示全部楼层

Re:第一次编写max场景导出插件的经验分享(仅限第一次写

不烦不烦,磨刀不误砍人工.
另外xsi的脚本是用vbscript和javascript的,所以推存xsi

3

主题

13

帖子

19

积分

新手上路

Rank: 1

积分
19
发表于 2008-4-24 15:46:00 | 显示全部楼层

Re:第一次编写max场景导出插件的经验分享(仅限第一次写

谢谢分享.

1

主题

4

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2008-4-24 16:29:00 | 显示全部楼层

Re:第一次编写max场景导出插件的经验分享(仅限第一次写

听起来楼上的像是xsi的推销员。。。。

0

主题

14

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2008-7-3 19:45:00 | 显示全部楼层

Re:第一次编写max场景导出插件的经验分享(仅限第一次写

还是脚本比较好,方便调试,使用的话文档里有写
我当前的项目就是用maxscript的

35

主题

1735

帖子

1739

积分

金牌会员

Rank: 6Rank: 6

积分
1739
QQ
发表于 2008-7-4 08:10:00 | 显示全部楼层

Re:第一次编写max场景导出插件的经验分享(仅限第一次写

对,脚本方便,而且也有资料,书店里有卖的,挺厚的一本,就是有点贵,好像100元左右,当时没舍得买,现在后悔了。唉,只好用SDK了,唉。。。

0

主题

769

帖子

1052

积分

金牌会员

Rank: 6Rank: 6

积分
1052
发表于 2008-7-4 23:17:00 | 显示全部楼层

Re:第一次编写max场景导出插件的经验分享(仅限第一次写

终于找到有人也想做插件了,最近正在看这方面的.MAX SDK感觉要用还是用MAX9的SDK比较好
因为MAX7的不兼容VS2005,除非自己去改.MAX 8的我没用过,因为7的被郁闷到直接跳到MAX9了.MAX9写得比7的好多了.至少不会有很明显的老掉牙代码:
for(int i = 0;....)
{
    ....
}

for(i = 0;.....)
{
   .....
}
那是狂郁闷的东西
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-21 22:13

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表