感覺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如圖所示:
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: