GMaxMtlDlg.cpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Max2W3d *
  23. * *
  24. * $Archive:: /Commando/Code/Tools/max2w3d/GMaxMtlDlg.cpp $*
  25. * *
  26. * Author:: Moumine Ballo *
  27. * *
  28. * $Modtime:: 4/05/02 11:10a $*
  29. * *
  30. * $Revision:: 11 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #if defined W3D_GMAXDEV
  36. #include <Max.h>
  37. #include <gport.h>
  38. #include <hsv.h>
  39. #include <bmmlib.h>
  40. #include "GMaxMtlDlg.h"
  41. #include "GameMtl.h"
  42. #include "GameMtlPassDlg.h"
  43. #include "dllmain.h"
  44. #include "resource.h"
  45. #include "w3d_file.h"
  46. #include "prsht.h"
  47. #include "gameMtlForm.h"
  48. extern GMaxMtlDlg * GMaxMaterialDialog;
  49. #include <pshpack1.h>
  50. typedef struct DLGTEMPLATEEX{
  51. WORD dlgVer;
  52. WORD signature;
  53. DWORD helpID;
  54. DWORD exStyle;
  55. DWORD style;
  56. WORD cDlgItems;
  57. short x;
  58. short y;
  59. short cx;
  60. short cy;
  61. } DLGTEMPLATEEX, *LPDLGTEMPLATEEX;
  62. #include <poppack.h>
  63. //============================================================================================
  64. #define WM_USER_UPDATE_MULTIMTL (WM_USER+141)
  65. static BOOL CALLBACK DisplacementMapDlgProc(HWND hwndDlg, UINT msg, WPARAM wPara,LPARAM lParam);
  66. static BOOL CALLBACK SurfaceTypePanelDlgProc(HWND hwndDlg, UINT msg, WPARAM wPara,LPARAM lParam);
  67. static BOOL CALLBACK PassCountPanelDlgProc(HWND hwndDlg, UINT msg, WPARAM wPara,LPARAM lParam);
  68. static BOOL CALLBACK PassCountDialogDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam,LPARAM lParam);
  69. static _Num_Of_NoNames(0); //Tracks the number addded to new material name
  70. GameMtl* ConvertStdMtl(Mtl* stdmtl);
  71. bool _UsingLargeFonts(false);
  72. // GMaxMtlDlg::GMaxMtlDlg -- constructor *
  73. //============================================================================================
  74. GMaxMtlDlg::GMaxMtlDlg(HWND hwMtlEdit, IMtlParams *imp, GameMtl *m)
  75. {
  76. Ip = GetCOREInterface();
  77. HwndEdit = hwMtlEdit;
  78. HwndPassCount = NULL;
  79. HwndSurfaceType = NULL;
  80. HwndDisplacementMap = NULL;
  81. HpalOld = NULL;
  82. Game_multi_mtl = NULL;
  83. if(imp){
  84. Game_multi_mtl = ((FakeIMtlParams*)imp)->Multi_mtl_list;
  85. }
  86. HGetMtlBmp = NULL;
  87. HBrowseMtlBmp = NULL;
  88. HAssignMtlBmp = NULL;
  89. HDeleteMtlBmp = NULL;
  90. HNewMtlBmp = NULL;
  91. HPreviousSiblingBmp = NULL;
  92. HNextSiblingBmp = NULL;
  93. DontShowMtlType = false;
  94. DontShowDeleteAll = false;
  95. fpMatNav.SetIFPMatNavCallback( this );
  96. for (int i=0; i<MAX_PASSES; i++) {
  97. PassDialog[i] = NULL;
  98. }
  99. TheMtl = m;
  100. IParams = imp;
  101. IsActive = 0;
  102. Build_Dialog(hwMtlEdit);
  103. }
  104. // GMaxMtlDlg::~GMaxMtlDlg -- destructor!
  105. //============================================================================================
  106. GMaxMtlDlg::~GMaxMtlDlg() {
  107. for (int i=0; i<MAX_PASSES; i++) {
  108. if (PassDialog[i]) {
  109. delete PassDialog[i];
  110. PassDialog[i] = NULL;
  111. }
  112. }
  113. TheMtl->SetParamDlg(NULL);
  114. }
  115. // GMaxMtlDlg::ClassID -- Returns the ClassID of GameMtl
  116. //============================================================================================
  117. Class_ID GMaxMtlDlg::ClassID(){
  118. return GameMaterialClassID;
  119. }
  120. // GMaxMtlDlg::SetThing -- Sets the material to be edited
  121. //============================================================================================
  122. void GMaxMtlDlg::SetThing(ReferenceTarget *m)
  123. {
  124. assert (m);
  125. assert (m->SuperClassID()==MATERIAL_CLASS_ID);
  126. assert ((m->ClassID()==GameMaterialClassID) || (m->ClassID()==PS2GameMaterialClassID));
  127. assert (TheMtl);
  128. int pass;
  129. // destroy our old pass dialogs
  130. for (pass=0; pass<TheMtl->Get_Pass_Count();pass++) {
  131. delete PassDialog[pass];
  132. PassDialog[pass] = NULL;
  133. }
  134. // install the new material
  135. TheMtl->SetParamDlg(NULL);
  136. TheMtl = (GameMtl *)m;
  137. TheMtl->SetParamDlg(this);
  138. // build a new set of pass dialogs
  139. for (pass=0; pass<TheMtl->Get_Pass_Count(); pass++) {
  140. PassDialog[pass] = new GameMtlPassDlg(HwndEdit, IParams, TheMtl, pass);
  141. }
  142. // refresh the contents of the dialogs
  143. ReloadDialog();
  144. }
  145. // GMaxMtlDlg::SetTime -- Sets the time value, updates the material and the dialog
  146. //============================================================================================
  147. void GMaxMtlDlg::SetTime(TimeValue t)
  148. {
  149. if (t!=CurTime) {
  150. CurTime = t;
  151. // TheMtl->Update(Ip->GetTime(),Valid);
  152. ReloadDialog();
  153. }
  154. }
  155. // GMaxMtlDlg::ReloadDialog -- Updates the values in all of the dialog's controls
  156. //============================================================================================
  157. void GMaxMtlDlg::ReloadDialog()
  158. {
  159. //Init the pass count panel
  160. assert(TheMtl && HwndPassCount && HwndSurfaceType);
  161. // Init the surface count panel
  162. ::SendMessage (HwndSurfaceType, WM_USER+101, 0, 0L);
  163. #ifdef WANT_DISPLACEMENT_MAPS
  164. ::SendMessage (HwndDisplacementMap, WM_USER+101, 0, 0L);
  165. #endif //WANT_DISPLACEMENT_MAPS
  166. // Init the pass count panel
  167. char a[10];
  168. sprintf(a, "%d", TheMtl->Get_Pass_Count());
  169. SetWindowText(GetDlgItem(HwndPassCount, IDC_GAMEMTL_PASSCOUNT_STATIC), a);
  170. //Init each pass panel
  171. for(int i = 0; i < TheMtl->Get_Pass_Count(); i++){
  172. PassDialog[i]->ReloadDialog();
  173. }
  174. }
  175. // GMaxMtlDlg::ActivateDlg -- Activates and deactivates the dialog
  176. //============================================================================================
  177. void GMaxMtlDlg::ActivateDlg(BOOL onoff){
  178. for(int i = 0; i < TheMtl->Get_Pass_Count(); i++){
  179. assert(PassDialog[i]);
  180. PassDialog[i]->ActivateDlg(onoff);
  181. }
  182. }
  183. // GMaxMtlDlg::Invalidate -- causes the dialog to be redrawn
  184. //============================================================================================
  185. void GMaxMtlDlg::Invalidate(){
  186. InvalidateRect(HwndSurfaceType,NULL,0);
  187. #ifdef WANT_DISPLACEMENT_MAPS
  188. InvalidateRect(HwndDisplacementMap,NULL,0);
  189. #endif //WANT_DISPLACEMENT_MAPS
  190. InvalidateRect(HwndPassCount,NULL,0);
  191. }
  192. BOOL GMaxMtlDlg::DisplacementMapProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){
  193. switch (message){
  194. case WM_INITDIALOG:
  195. case WM_USER + 101:{
  196. SetDlgItemInt (hDlg, IDC_AMOUNT_EDIT, TheMtl->Get_Displacement_Amount () * 100, TRUE);
  197. SetupIntSpinner(hDlg, IDC_AMOUNT_SPIN, IDC_AMOUNT_EDIT, -999, 999, TheMtl->Get_Displacement_Amount () * 100);
  198. Texmap *map = TheMtl->Get_Displacement_Map ();
  199. if (map != NULL) {
  200. SetDlgItemText (hDlg, IDC_TEXTURE_BUTTON, map->GetFullName ());
  201. }
  202. break;
  203. }
  204. case CC_SPINNER_CHANGE:{
  205. ISpinnerControl *control = (ISpinnerControl *)lParam;
  206. TheMtl->Set_Displacement_Amount (((float)control->GetIVal ()) / 100.0F);
  207. break;
  208. }
  209. case WM_COMMAND:
  210. switch(LOWORD(wParam)){
  211. case IDC_TEXTURE_BUTTON:
  212. if(HIWORD(wParam) == BN_CLICKED){
  213. PostMessage(HwndEdit, WM_TEXMAP_BUTTON, TheMtl->Get_Displacement_Map_Index (), (LPARAM)TheMtl);
  214. }
  215. break;
  216. }
  217. }
  218. return FALSE;
  219. }
  220. //============================================================================================
  221. BOOL GMaxMtlDlg::SurfaceTypeProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){
  222. switch (message){
  223. case WM_INITDIALOG:{
  224. // Fill the combobox with the names of the different surface types
  225. for (int index = 0; index < SURFACE_TYPE_MAX; index ++){
  226. ::SendDlgItemMessage ( hDlg,IDC_SURFACE_TYPE_COMBO,CB_ADDSTRING,0,(LPARAM)SURFACE_TYPE_STRINGS[index]);
  227. }
  228. // Limit the range of the static sort level spinner to 0 - MAX_SORT_LEVEL.
  229. int sort_level = TheMtl->Get_Sort_Level();
  230. SetupIntSpinner(hDlg, IDC_SORT_LEVEL_SPIN, IDC_SORT_LEVEL, 0, MAX_SORT_LEVEL, sort_level);
  231. // Check the checkbox if sort_level is not SORT_LEVEL_NONE.
  232. ::SendDlgItemMessage(hDlg, IDC_ENABLE_SORT_LEVEL, BM_SETCHECK,
  233. sort_level == SORT_LEVEL_NONE ? BST_UNCHECKED : BST_CHECKED, 0);
  234. LoadButtonBitmaps(hDlg);
  235. //Show Hide the sub mat controls
  236. ShowHideControls();
  237. TSTR name_str = TheMtl->GetName();
  238. //SetDlgItemText(hDlg, IDC_MTLNAME, dbg_txt);//name_str.data());
  239. ICustEdit* pEdit = GetICustEdit(GetDlgItem(HwndSurfaceType, IDC_MTLNAME));
  240. pEdit->SetText(name_str.data());
  241. ReleaseICustEdit(pEdit);
  242. //Multi mat name
  243. if(Game_multi_mtl != NULL){
  244. ICustEdit* pEdit = GetICustEdit(GetDlgItem(hDlg, IDC_MULTIMTLNAME));
  245. pEdit->GetText(name_str.data(), MAX_PATH);
  246. ReleaseICustEdit(pEdit);
  247. Game_multi_mtl->SetName(name_str);
  248. }
  249. }
  250. case WM_USER + 101:{
  251. // Select the current surface type
  252. ::SendDlgItemMessage ( hDlg,IDC_SURFACE_TYPE_COMBO,CB_SETCURSEL,(WPARAM)TheMtl->Get_Surface_Type (), 0L);
  253. // Set the correct sort level
  254. int sort_level = TheMtl->Get_Sort_Level();
  255. ISpinnerControl *spinner = GetISpinner(::GetDlgItem(hDlg, IDC_SORT_LEVEL_SPIN));
  256. assert(spinner);
  257. spinner->SetValue(sort_level, FALSE);
  258. ::SendDlgItemMessage(hDlg, IDC_ENABLE_SORT_LEVEL, BM_SETCHECK,
  259. sort_level == SORT_LEVEL_NONE ? BST_UNCHECKED : BST_CHECKED, 0);
  260. break;
  261. }
  262. case WM_USER_UPDATE_MULTIMTL:{
  263. //Show Hide the sub mat controls
  264. ShowHideControls();
  265. break;
  266. }
  267. case WM_USER+140:{
  268. ShowWindow(HwndEdit, SW_HIDE);
  269. return TRUE;
  270. }
  271. case WM_NOTIFY:{
  272. NMHDR * header = (NMHDR *)lParam;
  273. switch(header->code) {
  274. case PSN_SETACTIVE:{
  275. SetCurrentPage(0);
  276. return TRUE;
  277. }
  278. case PSN_RESET:{
  279. SetWindowLong(hDlg,DWL_MSGRESULT,FALSE);
  280. ::SendMessage(hDlg, WM_USER+140,0,0);
  281. return TRUE;
  282. }
  283. }
  284. break;
  285. }
  286. case WM_COMMAND:{
  287. switch(LOWORD(wParam)){
  288. case IDC_SURFACE_TYPE_COMBO:{
  289. if(HIWORD(wParam) == CBN_SELCHANGE){
  290. unsigned int type = ::SendDlgItemMessage (hDlg, IDC_SURFACE_TYPE_COMBO, CB_GETCURSEL, 0, 0L);
  291. TheMtl->Set_Surface_Type (type);
  292. }
  293. break;
  294. }
  295. case IDC_ENABLE_SORT_LEVEL:{
  296. if (HIWORD(wParam) == BN_CLICKED){
  297. // If the 'enable' checkbox was unchecked, set the sort level to NONE.
  298. int state = ::IsDlgButtonChecked(hDlg, IDC_ENABLE_SORT_LEVEL);
  299. ISpinnerControl *spinner = GetISpinner(::GetDlgItem(hDlg, IDC_SORT_LEVEL_SPIN));
  300. assert(spinner);
  301. if (state == BST_UNCHECKED){
  302. spinner->SetValue(SORT_LEVEL_NONE, FALSE);
  303. TheMtl->Set_Sort_Level(SORT_LEVEL_NONE);
  304. }else{
  305. if(state == BST_CHECKED){
  306. // Sort level was enabled, so set it's level to 1 if it was NONE before.
  307. if (spinner->GetIVal() == SORT_LEVEL_NONE){
  308. spinner->SetValue(1, FALSE);
  309. TheMtl->Set_Sort_Level(1);
  310. }
  311. }
  312. }
  313. }
  314. break;
  315. }
  316. case IDC_SETPASSCOUNT:{
  317. if(HIWORD(wParam) == BN_CLICKED){
  318. Set_Pass_Count_Dialog();
  319. }
  320. break;
  321. }
  322. case IDC_ASSIGN:{
  323. ApplyToSelection(TheMtl);
  324. break;
  325. }
  326. case IDC_NEWMTL:{
  327. DoNewMaterial();
  328. break;
  329. }
  330. case IDC_MTLNAME:{
  331. if(HIWORD(wParam) == EN_CHANGE){
  332. TSTR name_str;
  333. char str[MAX_PATH];
  334. ICustEdit* pEdit = GetICustEdit(GetDlgItem(hDlg, IDC_MTLNAME));
  335. pEdit->GetText(str, MAX_PATH);
  336. ReleaseICustEdit(pEdit);
  337. name_str = str;
  338. TheMtl->SetName(name_str);
  339. }
  340. break;
  341. }
  342. case IDC_MULTIMTLNAME:{
  343. if(HIWORD(wParam) == EN_CHANGE){
  344. TSTR name_str;
  345. char str[MAX_PATH];
  346. ICustEdit* pEdit = GetICustEdit(GetDlgItem(hDlg, IDC_MULTIMTLNAME));
  347. pEdit->GetText(str, MAX_PATH);
  348. ReleaseICustEdit(pEdit);
  349. name_str = str;
  350. Game_multi_mtl->SetName(name_str);
  351. }
  352. break;
  353. }
  354. case IDC_NAVIGATOR:{
  355. DoMaterialNavigator();
  356. break;
  357. }
  358. case IDC_GETMTL:{
  359. DoGetMaterial();
  360. break;
  361. }
  362. case IDC_DELETEMTL:{
  363. DeleteMtl();
  364. break;
  365. }
  366. case IDC_DELETEALL:{
  367. DeleteAllSceneMtl();
  368. break;
  369. }
  370. case IDC_SUBMTL_NUM:{
  371. if(HIWORD(wParam) == EN_CHANGE){
  372. if(HwndPassCount != NULL){ //Only after initializations
  373. // (gth) MATERIAL BEING CHANGED, user edited the current submtl index
  374. ICustEdit* pEdit = GetICustEdit(GetDlgItem(HwndSurfaceType, IDC_SUBMTL_NUM));
  375. Current_Submtl_Index = pEdit->GetInt()-1 ;
  376. ReleaseICustEdit(pEdit);
  377. Mtl * new_mtl = Game_multi_mtl->GetSubMtl(Current_Submtl_Index);
  378. if(NULL != new_mtl && new_mtl != TheMtl && new_mtl->ClassID() == GameMaterialClassID) {
  379. Reinitialize((GameMtl*)new_mtl, false);
  380. }
  381. }
  382. }
  383. break;
  384. }
  385. case IDC_NEXTSIBLING:{
  386. NextSibling();
  387. break;
  388. }
  389. case IDC_PREVIOUSSIBLING:{
  390. PreviousSibling();
  391. break;
  392. }
  393. }
  394. break;
  395. }
  396. case CC_SPINNER_CHANGE:{
  397. ISpinnerControl *spinner = (ISpinnerControl*)lParam;
  398. switch(LOWORD(wParam)){
  399. case IDC_SORT_LEVEL_SPIN:{
  400. // Check the 'enabled' checkbox if sort level != SORT_LEVEL_NONE, uncheck it otherwise.
  401. ::SendDlgItemMessage(hDlg, IDC_ENABLE_SORT_LEVEL, BM_SETCHECK,
  402. spinner->GetIVal() == SORT_LEVEL_NONE ? BST_UNCHECKED : BST_CHECKED, 0);
  403. TheMtl->Set_Sort_Level(spinner->GetIVal());
  404. break;
  405. }
  406. }
  407. break;
  408. }
  409. }
  410. return FALSE;
  411. }
  412. //============================================================================================
  413. BOOL GMaxMtlDlg::PassCountProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){
  414. switch (message){
  415. case WM_INITDIALOG:
  416. break;
  417. case WM_COMMAND:{
  418. switch(LOWORD(wParam)){
  419. case IDC_SETPASSCOUNT:{
  420. if(HIWORD(wParam) == BN_CLICKED){
  421. Set_Pass_Count_Dialog();
  422. }
  423. break;
  424. }
  425. }
  426. break;
  427. }
  428. }
  429. return FALSE;
  430. }
  431. //============================================================================================
  432. static BOOL CALLBACK DisplacementMapDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam,LPARAM lParam){
  433. GMaxMtlDlg * theDlg;
  434. if (msg == WM_INITDIALOG) {
  435. lParam = ((PROPSHEETPAGE*)lParam)->lParam;
  436. theDlg = (GMaxMtlDlg*)lParam;
  437. theDlg->HwndDisplacementMap = hwndDlg;
  438. SetWindowLong(hwndDlg, GWL_USERDATA,(LPARAM)theDlg);
  439. } else {
  440. if ((theDlg = (GMaxMtlDlg *)GetWindowLong(hwndDlg, GWL_USERDATA) ) == NULL) {
  441. return FALSE;
  442. }
  443. }
  444. theDlg->IsActive = 1;
  445. BOOL res = theDlg->DisplacementMapProc(hwndDlg,msg,wParam,lParam);
  446. theDlg->IsActive = 0;
  447. return res;
  448. }
  449. //============================================================================================
  450. static BOOL CALLBACK SurfaceTypePanelDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam,LPARAM lParam){
  451. GMaxMtlDlg * theDlg;
  452. if (msg == WM_INITDIALOG) {
  453. lParam = ((PROPSHEETPAGE*)lParam)->lParam;
  454. theDlg = (GMaxMtlDlg*)lParam;
  455. theDlg->HwndSurfaceType = hwndDlg;
  456. SetWindowLong(hwndDlg, GWL_USERDATA,(LPARAM)theDlg);
  457. // Set HwndPassCount to HwndSurfaceType
  458. theDlg->HwndPassCount = theDlg->HwndSurfaceType;
  459. PropSheet_Changed(GetParent(hwndDlg), hwndDlg); //Enable the "Apply" at all time
  460. } else {
  461. if ((theDlg = (GMaxMtlDlg *)GetWindowLong(hwndDlg, GWL_USERDATA) ) == NULL) {
  462. return FALSE;
  463. }
  464. }
  465. theDlg->IsActive = 1;
  466. BOOL res = theDlg->SurfaceTypeProc(hwndDlg,msg,wParam,lParam);
  467. theDlg->IsActive = 0;
  468. return res;
  469. }
  470. //============================================================================================
  471. static BOOL CALLBACK PassCountPanelDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam,LPARAM lParam){
  472. GMaxMtlDlg * theDlg = (GMaxMtlDlg *)GetWindowLong(hwndDlg, GWL_USERDATA);
  473. switch(msg){
  474. case WM_INITDIALOG: {
  475. lParam = ((PROPSHEETPAGE*)lParam)->lParam;
  476. theDlg = (GMaxMtlDlg*)lParam;
  477. theDlg->HwndPassCount = hwndDlg;
  478. SetWindowLong(hwndDlg, GWL_USERDATA,(LPARAM)theDlg);
  479. return FALSE;
  480. }
  481. }
  482. if ((theDlg = (GMaxMtlDlg *)GetWindowLong(hwndDlg, GWL_USERDATA) ) == NULL) {
  483. return FALSE;
  484. }
  485. theDlg->IsActive = 1;
  486. BOOL res = theDlg->PassCountProc(hwndDlg,msg,wParam,lParam);
  487. theDlg->IsActive = 0;
  488. return res;
  489. }
  490. //============================================================================================
  491. void GMaxMtlDlg::Set_Pass_Count_Dialog(void){
  492. int res = DialogBoxParam(
  493. AppInstance,
  494. MAKEINTRESOURCE(IDD_GAMEMTL_PASS_COUNT_DIALOG),
  495. HwndPassCount,
  496. PassCountDialogDlgProc,
  497. (LPARAM)TheMtl->Get_Pass_Count());
  498. if (res>=0){
  499. if(res<=0){
  500. res = 1;
  501. }
  502. if(res>4){
  503. res = 4;
  504. }
  505. char a[10];
  506. sprintf(a, "%d", res);
  507. SetWindowText(GetDlgItem(HwndPassCount, IDC_GAMEMTL_PASSCOUNT_STATIC), a);
  508. if(TheMtl->Get_Pass_Count() != res){
  509. int npass(TheMtl->Get_Pass_Count());
  510. if(res > npass){ //Add pages
  511. for(int i = npass; i < res; i++){
  512. PassDialog[i] = new GameMtlPassDlg(HwndEdit, IParams, TheMtl, i);
  513. }
  514. }else{//Remove pages
  515. for(int i = npass; i > res; i--){
  516. PropSheet_RemovePage(HwndEdit, i,NULL);
  517. PassDialog[i] = NULL;//new GameMtlPassDlg(HwndEdit, IParams, TheMtl, i-1);
  518. }
  519. }
  520. TheMtl->Set_Pass_Count(res);
  521. }
  522. }
  523. }
  524. //============================================================================================
  525. static BOOL CALLBACK PassCountDialogDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam,LPARAM lParam){
  526. switch (msg){
  527. case WM_INITDIALOG:{
  528. ISpinnerControl *spin = SetupIntSpinner(hwndDlg,IDC_PASSCOUNT_SPIN, IDC_PASSCOUNT_EDIT,1,4,(int)lParam);
  529. ReleaseISpinner(spin);
  530. CenterWindow(hwndDlg,GetParent(hwndDlg));
  531. break;
  532. }
  533. case WM_COMMAND:
  534. switch (LOWORD(wParam)){
  535. case IDOK:{
  536. ISpinnerControl *spin = GetISpinner(GetDlgItem(hwndDlg,IDC_PASSCOUNT_SPIN));
  537. EndDialog(hwndDlg,spin->GetIVal());
  538. ReleaseISpinner(spin);
  539. break;
  540. }
  541. case IDCANCEL:{
  542. EndDialog(hwndDlg,-1);
  543. break;
  544. }
  545. break;
  546. }
  547. default:
  548. return FALSE;
  549. }
  550. return TRUE;
  551. }
  552. /***********************************************************************************************
  553. * GMaxMtlDlg::Build_Dialog -- Adds the dialog to the material editor *
  554. * *
  555. * INPUT: *
  556. * *
  557. * OUTPUT: *
  558. * *
  559. * WARNINGS: *
  560. * *
  561. * HISTORY: *
  562. * 06/26/1997 GH : Created. *
  563. *=============================================================================================*/
  564. void GMaxMtlDlg::Build_Dialog(HWND hParent)// = NULL
  565. {
  566. //Need to initialize this global here
  567. if(GMaxMaterialDialog == NULL){
  568. GMaxMaterialDialog = this;
  569. }
  570. Make_PropertySheet(hParent);
  571. ReloadDialog();
  572. }
  573. //================================================
  574. int CALLBACK GameMtl_PropSheetProc( HWND hDlg, UINT msg, LPARAM lParam){
  575. switch(msg){
  576. case PSCB_INITIALIZED:{
  577. ShowWindow(GetDlgItem(hDlg,IDCANCEL), SW_HIDE);
  578. ShowWindow(GetDlgItem(hDlg,IDOK), SW_HIDE);
  579. return TRUE;
  580. }
  581. case PSCB_PRECREATE:{
  582. if (((LPDLGTEMPLATEEX)lParam)->signature == 0xFFFF){
  583. ((LPDLGTEMPLATEEX)lParam)->style &= ~DS_CONTEXTHELP;
  584. }
  585. else {
  586. ((LPDLGTEMPLATE)lParam)->style &= ~DS_CONTEXTHELP;
  587. }
  588. return TRUE;
  589. }
  590. }
  591. return FALSE;
  592. }
  593. //================================================
  594. void GMaxMtlDlg::Make_PropertySheet(HWND hParent){
  595. PROPSHEETPAGE ps_Pages[3];
  596. int pos(0);
  597. NONCLIENTMETRICS nc_metrics;
  598. nc_metrics.cbSize = sizeof(NONCLIENTMETRICS);
  599. //nc_metrics.lfMessageFont.lfHeight = -1;
  600. SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS),&nc_metrics,0);
  601. _UsingLargeFonts = (ABS(nc_metrics.lfMessageFont.lfHeight) > 12);
  602. //Surface type
  603. ps_Pages[pos].dwSize = sizeof(PROPSHEETPAGE);
  604. ps_Pages[pos].dwFlags = PSP_USEICONID | PSP_USETITLE ;
  605. ps_Pages[pos].hInstance = AppInstance;
  606. if(_UsingLargeFonts){
  607. ps_Pages[pos].pszTemplate = MAKEINTRESOURCE(IDD_GMAXMTL_SURFACE_TYPE);
  608. }else{
  609. ps_Pages[pos].pszTemplate = MAKEINTRESOURCE(IDD_GMAXMTL_SURFACE_TYPE_SMALL);
  610. }
  611. ps_Pages[pos].pszIcon = MAKEINTRESOURCE(IDI_ICONW3D);
  612. ps_Pages[pos].pfnDlgProc = SurfaceTypePanelDlgProc;
  613. ps_Pages[pos].pszTitle = MAKEINTRESOURCE(IDS_GMAXSURFACE_TYPE);
  614. ps_Pages[pos].lParam = (LPARAM)this;
  615. ps_Pages[pos].pfnCallback = NULL;
  616. pos++;
  617. #ifdef WANT_DISPLACEMENT_MAPS
  618. //Displacement type
  619. ps_Pages[pos].dwSize = sizeof(PROPSHEETPAGE);
  620. ps_Pages[pos].dwFlags = PSP_USEICONID | PSP_USETITLE;
  621. ps_Pages[pos].hInstance = AppInstance;
  622. ps_Pages[pos].pszTemplate = MAKEINTRESOURCE(IDD_GMAXMTL_DISPLACEMENT_MAP);
  623. ps_Pages[pos].pszIcon = MAKEINTRESOURCE(IDI_ICONW3D);
  624. ps_Pages[pos].pfnDlgProc = DisplacementMapDlgProc;
  625. ps_Pages[pos].pszTitle = MAKEINTRESOURCE(IDS_DISPLACEMENT_MAP);
  626. ps_Pages[pos].lParam = (LPARAM)this;
  627. ps_Pages[pos].pfnCallback = NULL;
  628. pos++;
  629. #endif //WANT_DISPLACEMENT_MAPS
  630. //Create the PropSheet
  631. PROPSHEETHEADER ps_Header;
  632. memset(&ps_Header, 0, sizeof(ps_Header));
  633. ps_Header.dwSize = sizeof(PROPSHEETHEADER);
  634. ps_Header.dwFlags = PSH_PROPSHEETPAGE | PSH_MODELESS | PSH_USECALLBACK | PSH_USEICONID | PSH_NOAPPLYNOW;// ;
  635. ps_Header.hwndParent = hParent;//GetCOREInterface()->GetMAXHWnd();
  636. ps_Header.hInstance = AppInstance;
  637. ps_Header.pszIcon = MAKEINTRESOURCE(IDI_ICONW3D);
  638. ps_Header.pszCaption = MAKEINTRESOURCE(IDS_W3DMATEDITOR);
  639. ps_Header.nPages = pos ;
  640. ps_Header.nStartPage = 0;
  641. ps_Header.ppsp = (LPCPROPSHEETPAGE) &ps_Pages;
  642. ps_Header.pfnCallback = GameMtl_PropSheetProc;
  643. HwndEdit = (HWND)PropertySheet(&ps_Header);
  644. //Crop out the area for "OK" "Apply"...
  645. RECT wind_rect;
  646. GetWindowRect(HwndEdit, &wind_rect);
  647. MoveWindow(HwndEdit, wind_rect.left, wind_rect.top,wind_rect.right - wind_rect.left,
  648. wind_rect.bottom - wind_rect.top -40, TRUE);
  649. // Position beneath the toolbar and slightly to the right
  650. SlideWindow(HwndEdit, 50,150);
  651. PropSheet_SetCurSel(HwndEdit,NULL, pos -1);//Force WM_INITDLG for the page
  652. HWND hwnd = PropSheet_IndexToHwnd(HwndEdit, 1);
  653. PropSheet_Changed(HwndEdit, hwnd); //Enable the "Apply" at all time
  654. for (int i=0; i<TheMtl->Get_Pass_Count(); i++) {
  655. PassDialog[i] = new GameMtlPassDlg(HwndEdit, IParams, TheMtl, i);
  656. PropSheet_SetCurSel(HwndEdit,NULL, i+pos);//Force WM_INITDLG for the page
  657. }
  658. PropSheet_SetCurSel(HwndEdit,NULL, 0);
  659. }
  660. //================================================
  661. static BOOL CALLBACK GmaxMaterialDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam,LPARAM lParam){
  662. return FALSE;
  663. }
  664. //================================================
  665. void GMaxMtlDlg::Reinitialize(GameMtl* new_mtl, bool update_multimtl){// = false
  666. //Delete pages
  667. int npages(0);
  668. if(TheMtl){
  669. npages = TheMtl->Get_Pass_Count();
  670. }
  671. //save
  672. int cur_page = CurrentPage;
  673. for (int i(npages); i > 0; i--) {
  674. PropSheet_RemovePage(HwndEdit, i,NULL);
  675. delete PassDialog[i];
  676. PassDialog[i] = NULL;
  677. }
  678. //Let know that ht material is no longer in the dialog
  679. if(TheMtl){
  680. TheMtl->SetParamDlg(NULL);
  681. }
  682. //Add new pages
  683. new_mtl->SetParamDlg(this);
  684. TheMtl = new_mtl;
  685. npages = TheMtl->Get_Pass_Count();
  686. for(i=0; i < npages; i++) {
  687. PassDialog[i] = new GameMtlPassDlg(HwndEdit, IParams, TheMtl, i);
  688. PropSheet_SetCurSel(HwndEdit,NULL, i+1);//Force WM_INITDLG for the page
  689. }
  690. //Make sure cur_page is not out of range for a new material
  691. if(cur_page > npages){
  692. cur_page = npages;
  693. }
  694. //====HwndSurfaceType Spinner
  695. int sort_level = TheMtl->Get_Sort_Level();
  696. SetupIntSpinner(HwndSurfaceType, IDC_SORT_LEVEL_SPIN, IDC_SORT_LEVEL, 0, MAX_SORT_LEVEL, sort_level);
  697. // Check the checkbox if sort_level is not SORT_LEVEL_NONE.
  698. ::SendDlgItemMessage(HwndSurfaceType, IDC_ENABLE_SORT_LEVEL, BM_SETCHECK,
  699. sort_level == SORT_LEVEL_NONE ? BST_UNCHECKED : BST_CHECKED, 0);
  700. //Surfface type combo
  701. ::SendDlgItemMessage (HwndSurfaceType,IDC_SURFACE_TYPE_COMBO,CB_SETCURSEL,(WPARAM)TheMtl->Get_Surface_Type (),0L);
  702. //==== ShowHide multimaterial stuff
  703. if(update_multimtl){
  704. ::SendMessage(HwndSurfaceType, WM_USER_UPDATE_MULTIMTL, 0, 0);
  705. }
  706. //Update name field
  707. TSTR name_str = TheMtl->GetName();
  708. char* dbg_txt = name_str.data();
  709. ICustEdit* pEdit = GetICustEdit(GetDlgItem(HwndSurfaceType, IDC_MTLNAME));
  710. pEdit->SetText(dbg_txt);
  711. ReleaseICustEdit(pEdit);
  712. //Multi
  713. if(Game_multi_mtl != NULL){
  714. name_str = Game_multi_mtl->GetName();
  715. pEdit = GetICustEdit(GetDlgItem(HwndSurfaceType, IDC_MULTIMTLNAME));
  716. pEdit->SetText(name_str.data());
  717. ReleaseICustEdit(pEdit); //==== HwndPassCount
  718. }
  719. char a[10];
  720. sprintf(a, "%d", TheMtl->Get_Pass_Count());
  721. SetWindowText(GetDlgItem(HwndSurfaceType, IDC_GAMEMTL_PASSCOUNT_STATIC), a);
  722. PropSheet_SetCurSel(HwndEdit,NULL, cur_page);//Force WM_INITDLG for the page
  723. ReloadDialog();
  724. }
  725. //============================================================================================
  726. void GMaxMtlDlg::Reset(GameMtl* new_mtl){
  727. Reinitialize(new_mtl);
  728. ShowWindow(HwndEdit, SW_SHOW);
  729. }
  730. //============================================================================================
  731. //Adds a tooltip to a control
  732. void GMaxMtlDlg::AddToolTip(HWND hControl, UINT strID){
  733. char str[MAX_PATH];
  734. TOOLINFO ti;
  735. ti.cbSize = sizeof(TOOLINFO);
  736. ti.uFlags = TTF_SUBCLASS ;
  737. ti.hwnd = hControl;
  738. ti.uId = 0;
  739. ti.hinst = AppInstance;
  740. LoadString(AppInstance, strID,str , MAX_PATH);
  741. ti.lpszText = str;
  742. GetClientRect(hControl, &ti.rect);
  743. HWND hwndTT = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
  744. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, hControl,NULL ,AppInstance, NULL );
  745. SetWindowPos(hwndTT, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  746. int res = SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
  747. }
  748. //============================================================================================
  749. void GMaxMtlDlg::LoadButtonBitmaps(HWND hDlg){
  750. //Get
  751. if(NULL == HGetMtlBmp){
  752. HGetMtlBmp = LoadBitmap(AppInstance, MAKEINTRESOURCE(IDB_GETMTL));
  753. }
  754. if(NULL != HGetMtlBmp){
  755. SendDlgItemMessage(hDlg,IDC_GETMTL, BM_SETIMAGE,(WPARAM) IMAGE_BITMAP, (LPARAM)HGetMtlBmp);
  756. AddToolTip(GetDlgItem(hDlg,IDC_GETMTL), IDS_GETMTL);
  757. }
  758. //Browse
  759. if(NULL == HBrowseMtlBmp){
  760. HBrowseMtlBmp = LoadBitmap(AppInstance, MAKEINTRESOURCE(IDB_BROWSE));
  761. }
  762. if(NULL != HBrowseMtlBmp){
  763. SendDlgItemMessage(hDlg,IDC_NAVIGATOR, BM_SETIMAGE,(WPARAM) IMAGE_BITMAP, (LPARAM)HBrowseMtlBmp);
  764. AddToolTip(GetDlgItem(hDlg,IDC_NAVIGATOR), IDS_NAVIGATOR);
  765. }
  766. //Assign
  767. if(NULL == HAssignMtlBmp){
  768. HAssignMtlBmp = LoadBitmap(AppInstance, MAKEINTRESOURCE(IDB_ASSIGN));
  769. }
  770. if(NULL != HAssignMtlBmp){
  771. SendDlgItemMessage(hDlg,IDC_ASSIGN, BM_SETIMAGE,(WPARAM) IMAGE_BITMAP, (LPARAM)HAssignMtlBmp);
  772. AddToolTip(GetDlgItem(hDlg,IDC_ASSIGN), IDS_ASSIGNMTL);
  773. }
  774. //Delete
  775. if(NULL == HDeleteMtlBmp){
  776. HDeleteMtlBmp = LoadBitmap(AppInstance, MAKEINTRESOURCE(IDB_DELETEMTL));
  777. }
  778. if(NULL != HDeleteMtlBmp){
  779. SendDlgItemMessage(hDlg,IDC_DELETEMTL, BM_SETIMAGE,(WPARAM) IMAGE_BITMAP, (LPARAM)HDeleteMtlBmp);
  780. AddToolTip(GetDlgItem(hDlg,IDC_DELETEMTL), IDS_DELETEMTL);
  781. }
  782. //New
  783. if(NULL == HNewMtlBmp){
  784. HNewMtlBmp = LoadBitmap(AppInstance, MAKEINTRESOURCE(IDB_NEWMTL));
  785. }
  786. if(NULL != HNewMtlBmp){
  787. SendDlgItemMessage(hDlg,IDC_NEWMTL, BM_SETIMAGE,(WPARAM) IMAGE_BITMAP, (LPARAM)HNewMtlBmp);
  788. AddToolTip(GetDlgItem(hDlg,IDC_NEWMTL), IDS_NEWMTL);
  789. }
  790. //Next Siblling
  791. if(NULL == HNextSiblingBmp){
  792. HNextSiblingBmp = LoadBitmap(AppInstance, MAKEINTRESOURCE(IDB_NEXTSIBLING));
  793. }
  794. if(NULL != HNextSiblingBmp){
  795. SendDlgItemMessage(hDlg,IDC_NEXTSIBLING, BM_SETIMAGE,(WPARAM) IMAGE_BITMAP, (LPARAM)HNextSiblingBmp);
  796. AddToolTip(GetDlgItem(hDlg,IDC_NEXTSIBLING), IDS_NEXTSIBLING);
  797. }
  798. //Previous Siblling
  799. if(NULL == HPreviousSiblingBmp){
  800. HPreviousSiblingBmp = LoadBitmap(AppInstance, MAKEINTRESOURCE(IDB_PREVIOUSSIBLING));
  801. }
  802. if(NULL != HPreviousSiblingBmp){
  803. SendDlgItemMessage(hDlg,IDC_PREVIOUSSIBLING, BM_SETIMAGE,(WPARAM) IMAGE_BITMAP, (LPARAM)HPreviousSiblingBmp);
  804. AddToolTip(GetDlgItem(hDlg,IDC_PREVIOUSSIBLING), IDS_PREVIOUSSIBLING);
  805. }
  806. /*
  807. //havoc Siblling
  808. if(NULL == HHavocBmp){
  809. HHavocBmp = LoadBitmap(AppInstance, MAKEINTRESOURCE(IDB_HAVOC));
  810. }
  811. if(NULL != HHavocBmp){
  812. SendDlgItemMessage(hDlg,IDC_HAVOC, BM_SETIMAGE,(WPARAM) IMAGE_BITMAP, (LPARAM)HHavocBmp);
  813. }
  814. //Banner Siblling
  815. if(NULL == HBannerBmp){
  816. HBannerBmp = LoadBitmap(AppInstance, MAKEINTRESOURCE(IDB_BANNER));
  817. }
  818. if(NULL != HHavocBmp){
  819. SendDlgItemMessage(hDlg,IDC_BANNER, BM_SETIMAGE,(WPARAM) IMAGE_BITMAP, (LPARAM)HBannerBmp);
  820. }
  821. */
  822. }
  823. //============================================================================================
  824. //Bring up the navigator
  825. void GMaxMtlDlg::DoMaterialNavigator(){
  826. Ip->ExecuteMAXCommand( MAXCOM_TOOLS_MTLMAPBROWSER );
  827. }
  828. //============================================================================================
  829. void GMaxMtlDlg::DoNewMaterial(){
  830. GameMtl *new_mtl = CreateNewGameMtl();
  831. Game_multi_mtl = NULL;
  832. Reinitialize(new_mtl);
  833. }
  834. //============================================================================================
  835. void GMaxMtlDlg::DoGetMaterial(){
  836. GameMtl* new_mtl = GetMtlFromSelection();
  837. if(NULL != new_mtl){// && new_mtl != TheMtl){
  838. Reinitialize(new_mtl);
  839. }
  840. }
  841. //============================================================================================
  842. void GMaxMtlDlg::ApplyToSelection(GameMtl* mtl){
  843. theHold.Begin ();
  844. int selcount = Ip->GetSelNodeCount();
  845. for(int i(0); i < selcount; i++){
  846. INode* node = Ip->GetSelNode(i);
  847. //if(node->NumMtls() < 2){ //?
  848. if(NULL == Game_multi_mtl){
  849. node->SetMtl(mtl);
  850. }else{
  851. node->SetMtl(Game_multi_mtl);
  852. }
  853. }
  854. Ip->ForceCompleteRedraw(TRUE);
  855. theHold.Accept(IDS_APPLYGAMEMTL);
  856. }
  857. //============================================================================================
  858. void GMaxMtlDlg::DeleteNodeMaterial(INode* node, MtlBase* mtl){
  859. Mtl* node_mtl;
  860. if((node_mtl = node->GetMtl()) == mtl){
  861. node->SetMtl(NULL);
  862. }
  863. //Multi/sub
  864. if(node_mtl){
  865. int num_subs(node_mtl->NumSubMtls());
  866. if( num_subs > 0){
  867. for(int i(0); i < num_subs; i++){
  868. if(mtl == node_mtl->GetSubMtl(i)){
  869. node_mtl->SetSubMtl(i,NULL);
  870. }
  871. }
  872. }
  873. }
  874. int node_count = node->NumberOfChildren();
  875. for(int i(0); i < node_count; i++){
  876. INode* node_i = node->GetChildNode(i);
  877. DeleteNodeMaterial(node_i, mtl);
  878. }
  879. }
  880. //============================================================================================
  881. void GMaxMtlDlg::DeleteMtl(){
  882. theHold.Begin ();
  883. MtlBaseLib* scene_mtls = Ip->GetSceneMtls();
  884. INode* root_node = Ip->GetRootNode();
  885. if(NULL != scene_mtls && NULL != root_node){
  886. DeleteNodeMaterial(root_node, TheMtl);
  887. //Remove from scene
  888. scene_mtls->Remove(TheMtl);
  889. //Reset
  890. DestroyDialog();
  891. GMaxMaterialDialog = NULL;
  892. }
  893. Ip->ForceCompleteRedraw(TRUE);
  894. theHold.Accept(IDS_APPLYGAMEMTL);
  895. }
  896. //============================================================================================
  897. void GMaxMtlDlg::DeleteAllSceneMtl(){
  898. MtlBaseLib* scene_mtls = Ip->GetSceneMtls();
  899. if(scene_mtls){
  900. if(!DontShowDeleteAll){
  901. DWORD ret;
  902. char msg[MAX_PATH];
  903. char title[MAX_PATH];
  904. LoadString(AppInstance, IDS_DELETE_ALLMTLS, msg, MAX_PATH);
  905. LoadString(AppInstance, IDS_W3DMSGCAPTION, title, MAX_PATH);
  906. if(IDYES == MaxMsgBox(Ip->GetMAXHWnd(), msg, title,MB_YESNO | MB_ICONINFORMATION, MAX_MB_DONTSHOWAGAIN, &ret)){
  907. scene_mtls->Empty();
  908. }
  909. if(ret & MAX_MB_DONTSHOWAGAIN){
  910. DontShowDeleteAll = true;
  911. }
  912. }else{
  913. scene_mtls->Empty();
  914. //Force Refresh navigator
  915. Ip->ExecuteMAXCommand( MAXCOM_TOOLS_MTLMAPBROWSER );
  916. }
  917. }
  918. }
  919. //============================================================================================
  920. GameMtl* CreateNewGameMtl(){
  921. Interface * Ip = GetCOREInterface();
  922. MtlBaseLib* scene_mtls = Ip->GetSceneMtls();
  923. GameMtl* mtl = new GameMtl();
  924. char namebuf[MAX_PATH] = {0};
  925. LoadString(AppInstance,IDS_DEFAULTGAMEMTL_NAME, namebuf, MAX_PATH);
  926. TSTR str = namebuf;
  927. int index = scene_mtls->FindMtl(mtl);
  928. if(index == -1){
  929. char tempbuf[32];
  930. itoa(_Num_Of_NoNames++, tempbuf, 10);
  931. str += tempbuf;
  932. mtl->SetName(str);
  933. }
  934. scene_mtls->AddMtl(mtl);
  935. return mtl;
  936. }
  937. //============================================================================================
  938. void GMaxMtlDlg::ShowHideControls(){
  939. if(NULL == Game_multi_mtl){
  940. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_SUBMTL_SPIN), SW_HIDE);
  941. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_SUBMTL_STATIC), SW_HIDE);
  942. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_SUBMTL_NUM), SW_HIDE);
  943. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_MULTIMTLNAME),SW_HIDE);
  944. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_MULTI_STATIC),SW_HIDE);
  945. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_NAME_STATIC),SW_SHOW);
  946. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_NEXTSIBLING),SW_HIDE);
  947. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_PREVIOUSSIBLING),SW_HIDE);
  948. }else{
  949. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_SUBMTL_SPIN), SW_SHOW);
  950. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_SUBMTL_STATIC), SW_SHOW);
  951. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_SUBMTL_NUM), SW_SHOW);
  952. int n_subs = Game_multi_mtl->NumSubMtls();
  953. SendDlgItemMessage(HwndSurfaceType,IDC_SUBMTL_SPIN, UDM_SETRANGE,(WPARAM)0, MAKELONG(n_subs, 1));
  954. ICustEdit* pEdit = GetICustEdit(GetDlgItem(HwndSurfaceType, IDC_SUBMTL_NUM));
  955. pEdit->SetText(1);
  956. ReleaseICustEdit(pEdit);
  957. //SetDlgItemInt(HwndSurfaceType,IDC_SUBMTL_NUM, 1, FALSE);
  958. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_MULTIMTLNAME),SW_SHOW);
  959. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_MULTI_STATIC),SW_SHOW);
  960. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_NAME_STATIC),SW_HIDE);
  961. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_NEXTSIBLING),SW_SHOW);
  962. ShowWindow(GetDlgItem(HwndSurfaceType,IDC_PREVIOUSSIBLING),SW_SHOW);
  963. }
  964. }
  965. //============================================================================================
  966. void GMaxMtlDlg::NextSibling(){
  967. // (gth) MATERIAL BEING CHANGED, user clicked the "next sibling" button
  968. if(HwndPassCount != NULL && Game_multi_mtl){ //Only after initializations
  969. int num_subs = Game_multi_mtl->NumSubMtls();
  970. Current_Submtl_Index = ++Current_Submtl_Index % num_subs;
  971. Mtl * new_mtl = Game_multi_mtl->GetSubMtl(Current_Submtl_Index);
  972. if(NULL != new_mtl){
  973. if(new_mtl->ClassID() == GameMaterialClassID){// && new_mtl != TheMtl){
  974. Reinitialize((GameMtl*)new_mtl, false);
  975. ICustEdit* pEdit = GetICustEdit(GetDlgItem(HwndSurfaceType, IDC_SUBMTL_NUM));
  976. pEdit->SetText(Current_Submtl_Index+1);
  977. ReleaseICustEdit(pEdit);
  978. }else{
  979. if(!DontShowMtlType){
  980. DWORD ret;
  981. char msg[MAX_PATH];
  982. char title[MAX_PATH];
  983. LoadString(AppInstance, IDS_NOTAGAMEMTL, msg, MAX_PATH);
  984. LoadString(AppInstance, IDS_W3DMSGCAPTION, title, MAX_PATH);
  985. MaxMsgBox(HwndSurfaceType, msg, title,MB_OK | MB_ICONINFORMATION, MAX_MB_DONTSHOWAGAIN, &ret);
  986. if(ret & MAX_MB_DONTSHOWAGAIN){
  987. DontShowMtlType = true;
  988. }
  989. }
  990. }
  991. }
  992. }
  993. }
  994. //============================================================================================
  995. void GMaxMtlDlg::PreviousSibling(){
  996. // (gth) MATERIAL BEING CHANGED, user clicked the "prev sibling" button
  997. if(HwndPassCount != NULL && Game_multi_mtl){ //Only after initializations
  998. int num_subs = Game_multi_mtl->NumSubMtls();
  999. if(Current_Submtl_Index > 0){
  1000. Current_Submtl_Index --;
  1001. }else{
  1002. Current_Submtl_Index = Game_multi_mtl->NumSubMtls()-1;
  1003. }
  1004. Mtl* new_mtl = (GameMtl*)(Game_multi_mtl->GetSubMtl(Current_Submtl_Index));
  1005. if(NULL != new_mtl){
  1006. if(new_mtl->ClassID() == GameMaterialClassID){// && new_mtl != TheMtl){
  1007. ICustEdit* pEdit = GetICustEdit(GetDlgItem(HwndSurfaceType, IDC_SUBMTL_NUM));
  1008. pEdit->SetText(Current_Submtl_Index + 1);
  1009. ReleaseICustEdit(pEdit);
  1010. Reinitialize((GameMtl*)new_mtl, false);
  1011. }else{
  1012. if(!DontShowMtlType){
  1013. DWORD ret;
  1014. char msg[MAX_PATH];
  1015. char title[MAX_PATH];
  1016. LoadString(AppInstance, IDS_NOTAGAMEMTL, msg, MAX_PATH);
  1017. LoadString(AppInstance, IDS_W3DMSGCAPTION, title, MAX_PATH);
  1018. MaxMsgBox(HwndSurfaceType, msg, title,MB_OK | MB_ICONINFORMATION, MAX_MB_DONTSHOWAGAIN, &ret);
  1019. if(ret & MAX_MB_DONTSHOWAGAIN){
  1020. DontShowMtlType = true;
  1021. }
  1022. }
  1023. }
  1024. }
  1025. }
  1026. }
  1027. //============================================================================================
  1028. BOOL CALLBACK GameMtlMainProc(HWND hMainDlg, UINT msg, WPARAM wParam, LPARAM lParam){
  1029. switch(msg){
  1030. case WM_INITDIALOG:{
  1031. break;
  1032. }
  1033. }
  1034. return FALSE;
  1035. }
  1036. //============================================================================================
  1037. GameMtl* GetMtlFromSelection(){
  1038. // (gth) MATERIAL BEING CHANGED, user clicked the "get from selection" button
  1039. // bool found_gamemtl(false);
  1040. Mtl* mtl = NULL;
  1041. GameMtl* game_mtl = NULL;
  1042. IMtlParams* mtl_params = NULL;
  1043. Interface* ip = GetCOREInterface();
  1044. int nsel;
  1045. if((nsel = ip->GetSelNodeCount()) < 1){
  1046. return NULL;
  1047. }else{
  1048. INode* node = ip->GetSelNode(0);
  1049. mtl = node->GetMtl();
  1050. if(NULL == mtl){// Node has no mtl
  1051. return NULL;
  1052. }else{
  1053. GMaxMaterialDialog->SetMultimaterial(NULL);
  1054. int n_subs = mtl->NumSubMtls() ;
  1055. if(n_subs > 0){
  1056. //case MultiMtl
  1057. //found_gamemtl = true;
  1058. //Set for multimaterial
  1059. GMaxMaterialDialog->SetMultimaterial(mtl);
  1060. for(int sub_i(0); sub_i < n_subs/* && ! found_gamemtl*/; sub_i ++){
  1061. Mtl* sub_mtl = mtl->GetSubMtl(sub_i);
  1062. if(sub_mtl->ClassID() == GameMaterialClassID){
  1063. game_mtl = (GameMtl*)sub_mtl;
  1064. }else{
  1065. game_mtl = GMaxMaterialDialog->ConvertStdMtl(sub_mtl);
  1066. //replace the submtl by the converted
  1067. mtl->SetSubMtl(sub_i,game_mtl );
  1068. }
  1069. }
  1070. }else{
  1071. // No submtls
  1072. if(mtl->ClassID() == GameMaterialClassID){
  1073. game_mtl = (GameMtl*) mtl;
  1074. }else{
  1075. game_mtl = GMaxMaterialDialog->ConvertStdMtl(mtl);
  1076. }
  1077. }
  1078. }
  1079. }
  1080. return game_mtl;
  1081. }
  1082. //============================================================================================
  1083. //============================================================================================
  1084. //============================================================================================
  1085. void GMaxMtlDlg::Launch()
  1086. {
  1087. }
  1088. void GMaxMtlDlg::SetMultiMaterialTabBySlot( int iSlot, int iSubMtlTexIndex, int iElement ) {
  1089. SetMultiMaterialBySlot(iSlot,iSubMtlTexIndex);
  1090. }
  1091. //============================================================================================
  1092. void GMaxMtlDlg::SetMaterialTabBySlot( int iSlot, int iElement ) {
  1093. SetMaterialBySlot(iSlot);
  1094. }
  1095. //============================================================================================
  1096. void GMaxMtlDlg::SetMultiMaterialBySlot( int iSlot, int iIndex ) {
  1097. // (gth) MATERIAL BEING CHANGED, user double clicked a member of a multi-material in the navagator
  1098. MtlBase * mtl_base = GetMtlEditInterface()->GetCurMtl();
  1099. if ((mtl_base->IsMultiMtl()) && (IsMtl(mtl_base))) {
  1100. Mtl * mtl = (Mtl*)mtl_base;
  1101. // Sub material iIndex is "1-based" but the sdk is "0-based"
  1102. if ((iIndex > 0) && (iIndex <= mtl->NumSubMtls())) {
  1103. MtlBase * sub_mtl = ((Mtl*)mtl)->GetSubMtl(iIndex - 1);
  1104. if ((sub_mtl != NULL) && (sub_mtl->ClassID() == GameMaterialClassID)) {
  1105. Game_multi_mtl = (Mtl*)mtl;
  1106. Reinitialize((GameMtl*)(sub_mtl));
  1107. ICustEdit* pEdit = GetICustEdit(GetDlgItem(HwndSurfaceType, IDC_SUBMTL_NUM));
  1108. Current_Submtl_Index = iIndex-1 ;
  1109. pEdit->SetText(iIndex);
  1110. ReleaseICustEdit(pEdit);
  1111. }
  1112. }
  1113. }
  1114. ShowWindow(HwndEdit, SW_SHOW);
  1115. }
  1116. //============================================================================================
  1117. void GMaxMtlDlg::SetMaterialBySlot( int iSlot ){
  1118. // (gth) MATERIAL BEING CHANGED, user double clicked a material in the navagator
  1119. MtlBase * mtl_base = GetMtlEditInterface()->GetCurMtl();
  1120. Class_ID clsid = mtl_base->ClassID();
  1121. if(clsid == GameMaterialClassID){
  1122. Game_multi_mtl = NULL;
  1123. Reinitialize((GameMtl*)mtl_base);
  1124. } else if ((mtl_base->IsMultiMtl()) && (IsMtl(mtl_base))) {
  1125. SetMultiMaterialBySlot( iSlot, 1 );
  1126. }
  1127. ShowWindow(HwndEdit, SW_SHOW);
  1128. }
  1129. //============================================================================================
  1130. void GMaxMtlDlg::DestroyDialog()
  1131. {
  1132. ShowWindow(HwndEdit, SW_HIDE);
  1133. DeleteThis();
  1134. }
  1135. //============================================================================================
  1136. GameMtl* GMaxMtlDlg::ConvertStdMtl(Mtl* stdmtl){
  1137. GameMtl* gmtl = CreateNewGameMtl();
  1138. gmtl->Set_Ambient(0,Ip->GetTime(), stdmtl->GetAmbient());
  1139. gmtl->Set_Diffuse(0,Ip->GetTime(), stdmtl->GetDiffuse());
  1140. gmtl->Set_Specular(0,Ip->GetTime(), stdmtl->GetSpecular());
  1141. gmtl->Set_Shininess(0,Ip->GetTime(), stdmtl->GetShininess());
  1142. float opacity = 1-stdmtl->GetXParency();
  1143. gmtl->Set_Opacity(0,Ip->GetTime(),opacity);
  1144. Texmap* tmap = (Texmap*)stdmtl->GetActiveTexmap();
  1145. if(tmap != NULL){
  1146. gmtl->Set_Texture(0,0,tmap);
  1147. gmtl->Set_Texture_Enable(0,0,true);
  1148. gmtl->Set_Texture_Display(0,0,true);
  1149. gmtl->Set_Texture_Frame_Rate(0,0,0);
  1150. gmtl->Set_Texture_Frame_Count(0,0,0);
  1151. gmtl->Set_Texture_Display(0,0,true);
  1152. gmtl->Set_Map_Channel(0,0,1);
  1153. }
  1154. return gmtl;
  1155. }
  1156. #endif