萬盛學電腦網

 萬盛學電腦網 >> 圖文處理 >> 3DSMAX教程 >> 3ds max sdk導出插件編寫

3ds max sdk導出插件編寫

   感覺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:

copyright © 萬盛學電腦網 all rights reserved