Panda3D
|
00001 /* 00002 MaxEgg.cpp 00003 Created by Steven "Sauce" Osman, 01/??/03 00004 Modified by Ken Strickland, 02/25/03 00005 Carnegie Mellon University, Entertainment Technology Center 00006 00007 This file implements the classes that are used in the Panda 3D file 00008 exporter for 3D Studio Max. 00009 */ 00010 00011 #include "maxEgg.h" 00012 00013 00014 const double meshVerts[252][3] = { 00015 {0.729464, -0.919852, 0.714986}, 00016 {0.466137, -0.594656, 0.160201}, 00017 {-0.265897, -1.14704, 0.714986}, 00018 {0.466137, -0.594656, 0.160201}, 00019 {-0.177333, -0.741523, 0.160201}, 00020 {-0.265897, -1.14704, 0.714986}, 00021 {-0.265897, -1.14704, 0.714986}, 00022 {-0.177333, -0.741523, 0.160201}, 00023 {-1.06411, -0.510479, 0.714986}, 00024 {-0.177333, -0.741523, 0.160201}, 00025 {-0.693356, -0.330009, 0.160201}, 00026 {-1.06411, -0.510479, 0.714986}, 00027 {-1.06411, 0.510479, 0.714986}, 00028 {-1.06411, -0.510479, 0.714986}, 00029 {-0.693356, 0.330009, 0.160201}, 00030 {-0.693356, -0.330009, 0.160201}, 00031 {-0.693356, 0.330009, 0.160201}, 00032 {-1.06411, -0.510479, 0.714986}, 00033 {-0.265897, 1.14704, 0.714986}, 00034 {-1.06411, 0.510479, 0.714986}, 00035 {-0.177333, 0.741523, 0.160201}, 00036 {-0.693356, 0.330009, 0.160201}, 00037 {-0.177333, 0.741523, 0.160201}, 00038 {-1.06411, 0.510479, 0.714986}, 00039 {0.729464, 0.919852, 0.714986}, 00040 {-0.265897, 1.14704, 0.714986}, 00041 {0.466137, 0.594656, 0.160201}, 00042 {-0.177333, 0.741523, 0.160201}, 00043 {0.466137, 0.594656, 0.160201}, 00044 {-0.265897, 1.14704, 0.714986}, 00045 {1.17244, 0.0, 0.714986}, 00046 {0.729464, 0.919852, 0.714986}, 00047 {0.752508, 0.0, 0.160201}, 00048 {0.466137, 0.594656, 0.160201}, 00049 {0.752508, 0.0, 0.160201}, 00050 {0.729464, 0.919852, 0.714986}, 00051 {0.729464, -0.919852, 0.714986}, 00052 {1.17244, 0.0, 0.714986}, 00053 {0.466137, -0.594656, 0.160201}, 00054 {0.752508, 0.0, 0.160201}, 00055 {0.466137, -0.594656, 0.160201}, 00056 {1.17244, 0.0, 0.714986}, 00057 {-0.286334, -1.26822, 1.44995}, 00058 {0.814187, -1.01703, 1.44995}, 00059 {-0.265897, -1.14704, 0.714986}, 00060 {0.729464, -0.919852, 0.714986}, 00061 {-0.265897, -1.14704, 0.714986}, 00062 {0.814187, -1.01703, 1.44995}, 00063 {-1.16888, -0.564412, 1.44995}, 00064 {-0.286334, -1.26822, 1.44995}, 00065 {-1.06411, -0.510479, 0.714986}, 00066 {-0.265897, -1.14704, 0.714986}, 00067 {-1.06411, -0.510479, 0.714986}, 00068 {-0.286334, -1.26822, 1.44995}, 00069 {-1.16888, 0.564411, 1.44995}, 00070 {-1.16888, -0.564412, 1.44995}, 00071 {-1.06411, 0.510479, 0.714986}, 00072 {-1.06411, -0.510479, 0.714986}, 00073 {-1.06411, 0.510479, 0.714986}, 00074 {-1.16888, -0.564412, 1.44995}, 00075 {-1.16888, 0.564411, 1.44995}, 00076 {-1.06411, 0.510479, 0.714986}, 00077 {-0.286334, 1.26822, 1.44995}, 00078 {-1.06411, 0.510479, 0.714986}, 00079 {-0.265897, 1.14704, 0.714986}, 00080 {-0.286334, 1.26822, 1.44995}, 00081 {-0.286334, 1.26822, 1.44995}, 00082 {-0.265897, 1.14704, 0.714986}, 00083 {0.814187, 1.01703, 1.44995}, 00084 {-0.265897, 1.14704, 0.714986}, 00085 {0.729464, 0.919852, 0.714986}, 00086 {0.814187, 1.01703, 1.44995}, 00087 {1.30396, 0.0, 1.44995}, 00088 {0.814187, 1.01703, 1.44995}, 00089 {1.17244, 0.0, 0.714986}, 00090 {0.729464, 0.919852, 0.714986}, 00091 {1.17244, 0.0, 0.714986}, 00092 {0.814187, 1.01703, 1.44995}, 00093 {1.30396, 0.0, 1.44995}, 00094 {1.17244, 0.0, 0.714986}, 00095 {0.814187, -1.01703, 1.44995}, 00096 {1.17244, 0.0, 0.714986}, 00097 {0.729464, -0.919852, 0.714986}, 00098 {0.814187, -1.01703, 1.44995}, 00099 {-0.286334, -1.26822, 1.44995}, 00100 {-0.227573, -1.05763, 2.16723}, 00101 {0.814187, -1.01703, 1.44995}, 00102 {0.814187, -1.01703, 1.44995}, 00103 {-0.227573, -1.05763, 2.16723}, 00104 {0.690208, -0.848157, 2.16723}, 00105 {-1.16888, -0.564412, 1.44995}, 00106 {-0.963577, -0.470692, 2.16723}, 00107 {-0.286334, -1.26822, 1.44995}, 00108 {-0.286334, -1.26822, 1.44995}, 00109 {-0.963577, -0.470692, 2.16723}, 00110 {-0.227573, -1.05763, 2.16723}, 00111 {-1.16888, -0.564412, 1.44995}, 00112 {-1.16888, 0.564411, 1.44995}, 00113 {-0.963577, -0.470692, 2.16723}, 00114 {-1.16888, 0.564411, 1.44995}, 00115 {-0.963577, 0.470692, 2.16723}, 00116 {-0.963577, -0.470692, 2.16723}, 00117 {-1.16888, 0.564411, 1.44995}, 00118 {-0.286334, 1.26822, 1.44995}, 00119 {-0.963577, 0.470692, 2.16723}, 00120 {-0.286334, 1.26822, 1.44995}, 00121 {-0.227574, 1.05763, 2.16723}, 00122 {-0.963577, 0.470692, 2.16723}, 00123 {-0.286334, 1.26822, 1.44995}, 00124 {0.814187, 1.01703, 1.44995}, 00125 {-0.227574, 1.05763, 2.16723}, 00126 {0.814187, 1.01703, 1.44995}, 00127 {0.690208, 0.848157, 2.16723}, 00128 {-0.227574, 1.05763, 2.16723}, 00129 {0.814187, 1.01703, 1.44995}, 00130 {1.30396, 0.0, 1.44995}, 00131 {0.690208, 0.848157, 2.16723}, 00132 {1.30396, 0.0, 1.44995}, 00133 {1.09866, 0.0, 2.16723}, 00134 {0.690208, 0.848157, 2.16723}, 00135 {0.814187, -1.01703, 1.44995}, 00136 {0.690208, -0.848157, 2.16723}, 00137 {1.30396, 0.0, 1.44995}, 00138 {1.30396, 0.0, 1.44995}, 00139 {0.690208, -0.848157, 2.16723}, 00140 {1.09866, 0.0, 2.16723}, 00141 {-0.227573, -1.05763, 2.16723}, 00142 {-0.154893, -0.759032, 2.72566}, 00143 {0.690208, -0.848157, 2.16723}, 00144 {0.690208, -0.848157, 2.16723}, 00145 {-0.154893, -0.759032, 2.72566}, 00146 {0.50377, -0.608696, 2.72566}, 00147 {-0.963577, -0.470692, 2.16723}, 00148 {-0.683099, -0.337801, 2.72566}, 00149 {-0.227573, -1.05763, 2.16723}, 00150 {-0.227573, -1.05763, 2.16723}, 00151 {-0.683099, -0.337801, 2.72566}, 00152 {-0.154893, -0.759032, 2.72566}, 00153 {-0.963577, -0.470692, 2.16723}, 00154 {-0.963577, 0.470692, 2.16723}, 00155 {-0.683099, -0.337801, 2.72566}, 00156 {-0.963577, 0.470692, 2.16723}, 00157 {-0.683099, 0.337801, 2.72566}, 00158 {-0.683099, -0.337801, 2.72566}, 00159 {-0.963577, 0.470692, 2.16723}, 00160 {-0.227574, 1.05763, 2.16723}, 00161 {-0.683099, 0.337801, 2.72566}, 00162 {-0.227574, 1.05763, 2.16723}, 00163 {-0.154893, 0.759032, 2.72566}, 00164 {-0.683099, 0.337801, 2.72566}, 00165 {-0.227574, 1.05763, 2.16723}, 00166 {0.690208, 0.848157, 2.16723}, 00167 {-0.154893, 0.759032, 2.72566}, 00168 {0.690208, 0.848157, 2.16723}, 00169 {0.50377, 0.608696, 2.72566}, 00170 {-0.154893, 0.759032, 2.72566}, 00171 {0.690208, 0.848157, 2.16723}, 00172 {1.09866, 0.0, 2.16723}, 00173 {0.50377, 0.608696, 2.72566}, 00174 {1.09866, 0.0, 2.16723}, 00175 {0.796903, 0.0, 2.72566}, 00176 {0.50377, 0.608696, 2.72566}, 00177 {1.09866, 0.0, 2.16723}, 00178 {0.690208, -0.848157, 2.16723}, 00179 {0.796903, 0.0, 2.72566}, 00180 {0.690208, -0.848157, 2.16723}, 00181 {0.50377, -0.608696, 2.72566}, 00182 {0.796903, 0.0, 2.72566}, 00183 {0.50377, -0.608696, 2.72566}, 00184 {-0.154893, -0.759032, 2.72566}, 00185 {0.259722, -0.299638, 3.11175}, 00186 {-0.154893, -0.759032, 2.72566}, 00187 {-0.0645132, -0.373643, 3.11175}, 00188 {0.259722, -0.299638, 3.11175}, 00189 {-0.154893, -0.759032, 2.72566}, 00190 {-0.683099, -0.337801, 2.72566}, 00191 {-0.0645132, -0.373643, 3.11175}, 00192 {-0.683099, -0.337801, 2.72566}, 00193 {-0.324529, -0.166287, 3.11175}, 00194 {-0.0645132, -0.373643, 3.11175}, 00195 {-0.683099, -0.337801, 2.72566}, 00196 {-0.683099, 0.337801, 2.72566}, 00197 {-0.324529, -0.166287, 3.11175}, 00198 {-0.683099, 0.337801, 2.72566}, 00199 {-0.324529, 0.166287, 3.11175}, 00200 {-0.324529, -0.166287, 3.11175}, 00201 {-0.683099, 0.337801, 2.72566}, 00202 {-0.154893, 0.759032, 2.72566}, 00203 {-0.324529, 0.166287, 3.11175}, 00204 {-0.154893, 0.759032, 2.72566}, 00205 {-0.0645132, 0.373642, 3.11175}, 00206 {-0.324529, 0.166287, 3.11175}, 00207 {-0.154893, 0.759032, 2.72566}, 00208 {0.50377, 0.608696, 2.72566}, 00209 {-0.0645132, 0.373642, 3.11175}, 00210 {0.50377, 0.608696, 2.72566}, 00211 {0.259722, 0.299638, 3.11175}, 00212 {-0.0645132, 0.373642, 3.11175}, 00213 {0.50377, 0.608696, 2.72566}, 00214 {0.796903, 0.0, 2.72566}, 00215 {0.259722, 0.299638, 3.11175}, 00216 {0.796903, 0.0, 2.72566}, 00217 {0.40402, 0.0, 3.11175}, 00218 {0.259722, 0.299638, 3.11175}, 00219 {0.796903, 0.0, 2.72566}, 00220 {0.50377, -0.608696, 2.72566}, 00221 {0.40402, 0.0, 3.11175}, 00222 {0.50377, -0.608696, 2.72566}, 00223 {0.259722, -0.299638, 3.11175}, 00224 {0.40402, 0.0, 3.11175}, 00225 {-0.177333, -0.741523, 0.160201}, 00226 {0.466137, -0.594656, 0.160201}, 00227 {-0.00334214, 0.0, 0.00443203}, 00228 {-0.693356, -0.330009, 0.160201}, 00229 {-0.177333, -0.741523, 0.160201}, 00230 {-0.00334214, 0.0, 0.00443203}, 00231 {-0.693356, 0.330009, 0.160201}, 00232 {-0.693356, -0.330009, 0.160201}, 00233 {-0.00334214, 0.0, 0.00443203}, 00234 {-0.177333, 0.741523, 0.160201}, 00235 {-0.693356, 0.330009, 0.160201}, 00236 {-0.00334214, 0.0, 0.00443203}, 00237 {0.466137, 0.594656, 0.160201}, 00238 {-0.177333, 0.741523, 0.160201}, 00239 {-0.00334214, 0.0, 0.00443203}, 00240 {0.752508, 0.0, 0.160201}, 00241 {0.466137, 0.594656, 0.160201}, 00242 {-0.00334214, 0.0, 0.00443203}, 00243 {0.466137, -0.594656, 0.160201}, 00244 {0.752508, 0.0, 0.160201}, 00245 {-0.00334214, 0.0, 0.00443203}, 00246 {0.259722, -0.299638, 3.11175}, 00247 {-0.0645132, -0.373643, 3.11175}, 00248 {0.0207683, 0.0, 3.20912}, 00249 {-0.0645132, -0.373643, 3.11175}, 00250 {-0.324529, -0.166287, 3.11175}, 00251 {0.0207683, 0.0, 3.20912}, 00252 {-0.324529, -0.166287, 3.11175}, 00253 {-0.324529, 0.166287, 3.11175}, 00254 {0.0207683, 0.0, 3.20912}, 00255 {-0.324529, 0.166287, 3.11175}, 00256 {-0.0645132, 0.373642, 3.11175}, 00257 {0.0207683, 0.0, 3.20912}, 00258 {-0.0645132, 0.373642, 3.11175}, 00259 {0.259722, 0.299638, 3.11175}, 00260 {0.0207683, 0.0, 3.20912}, 00261 {0.259722, 0.299638, 3.11175}, 00262 {0.40402, 0.0, 3.11175}, 00263 {0.0207683, 0.0, 3.20912}, 00264 {0.40402, 0.0, 3.11175}, 00265 {0.259722, -0.299638, 3.11175}, 00266 {0.0207683, 0.0, 3.20912} 00267 }; 00268 00269 00270 //Disable the forcing int to true or false performance warning 00271 #pragma warning(disable: 4800) 00272 00273 /* MaxEggPluginClassDesc - A class that describes 3DS Plugin support. 00274 This basically says "Yes, I am a helper object!" 00275 */ 00276 00277 class MaxEggPluginClassDesc : public ClassDesc 00278 { 00279 public: 00280 int IsPublic() { return TRUE; } 00281 void *Create(BOOL loading = FALSE) { return new MaxEggPlugin(); } 00282 const TCHAR *ClassName() { return GetString(IDS_CLASS_NAME); } 00283 SClass_ID SuperClassID() { return HELPER_CLASS_ID; } 00284 Class_ID ClassID() { return MaxEggPlugin_CLASS_ID; } 00285 const TCHAR *Category() { return GetString(IDS_CATEGORY); } 00286 // returns fixed parsable name (scripter-visible name) 00287 const TCHAR *InternalName() { return _T("MaxEggPlugin"); } 00288 }; 00289 00290 // Our private global instance of the above class 00291 static MaxEggPluginClassDesc MaxEggPluginDesc; 00292 00293 // Called by LibClassDesc to find out what the plugin is 00294 ClassDesc* GetMaxEggPluginDesc() { return &MaxEggPluginDesc; } 00295 00296 // Initialize class-static variables 00297 Mesh MaxEggPlugin::mesh; 00298 short MaxEggPlugin::meshBuilt=0; 00299 HWND MaxEggPlugin::hMaxEggParams = NULL; 00300 IObjParam *MaxEggPlugin::iObjParams; 00301 00302 /* MaxEggPluginOptionsDlgProc() - This is the callback function for the 00303 dialog box that appears at the beginning of the conversion process. 00304 */ 00305 00306 INT_PTR CALLBACK MaxEggPluginOptionsDlgProc( HWND hWnd, UINT message, 00307 WPARAM wParam, LPARAM lParam ) 00308 { 00309 MaxOptionsDialog *tempEgg; 00310 int sel, res; 00311 00312 //We pass in our plugin through the lParam variable. Let's convert it back. 00313 MaxEggPlugin *imp = (MaxEggPlugin*)GetWindowLongPtr(hWnd,GWLP_USERDATA); 00314 if ( !imp && message != WM_INITDIALOG ) return FALSE; 00315 00316 switch(message) 00317 { 00318 // When we start, center the window. 00319 case WM_INITDIALOG: 00320 // this line is very necessary to pass the plugin as the lParam 00321 SetWindowLongPtr(hWnd,GWLP_USERDATA,lParam); 00322 SetDlgFont( hWnd, imp->iObjParams->GetAppHFont() ); 00323 MaxEggPlugin::hMaxEggParams = hWnd; 00324 return TRUE; break; 00325 00326 case WM_MOUSEACTIVATE: 00327 imp->iObjParams->RealizeParamPanel(); 00328 return TRUE; break; 00329 00330 case WM_LBUTTONDOWN: 00331 case WM_LBUTTONUP: 00332 case WM_MOUSEMOVE: 00333 imp->iObjParams->RollupMouseMessage(hWnd,message,wParam,lParam); 00334 return TRUE; break; 00335 00336 // A control was modified 00337 case WM_COMMAND: 00338 //The modified control is found in the lower word of the wParam long. 00339 switch( LOWORD(wParam) ) { 00340 case IDC_OVERWRITE_CHECK: 00341 imp->autoOverwrite = 00342 (IsDlgButtonChecked(hWnd, IDC_OVERWRITE_CHECK) == BST_CHECKED); 00343 return TRUE; break; 00344 case IDC_PVIEW_CHECK: 00345 imp->pview = 00346 (IsDlgButtonChecked(hWnd, IDC_PVIEW_CHECK) == BST_CHECKED); 00347 return TRUE; break; 00348 case IDC_LOGGING: 00349 imp->logOutput = 00350 (IsDlgButtonChecked(hWnd, IDC_LOGGING) == BST_CHECKED); 00351 return TRUE; break; 00352 case IDC_ADD_EGG: 00353 tempEgg = new MaxOptionsDialog(); 00354 tempEgg->SetMaxInterface(imp->iObjParams); 00355 tempEgg->SetAnimRange(); 00356 res = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_EGG_DETAILS), 00357 hWnd, MaxOptionsDialogProc, (LPARAM)tempEgg); 00358 if (res == TRUE) { 00359 imp->SaveCheckState(); 00360 imp->AddEgg(tempEgg); 00361 imp->UpdateUI(); 00362 } 00363 else delete tempEgg; 00364 return TRUE; break; 00365 case IDC_EDIT_EGG: 00366 sel = ListView_GetSelectionMark(GetDlgItem(hWnd, IDC_LIST_EGGS)); 00367 if (sel != -1) { 00368 MaxOptionsDialog *tempEgg = imp->GetEgg(sel); 00369 if (tempEgg) { 00370 tempEgg->SetAnimRange(); 00371 tempEgg->CullBadNodes(); 00372 DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_EGG_DETAILS), 00373 hWnd, MaxOptionsDialogProc, (LPARAM)tempEgg); 00374 } 00375 imp->SaveCheckState(); 00376 imp->UpdateUI(); 00377 } 00378 return TRUE; break; 00379 case IDC_REMOVE_EGG: 00380 sel = ListView_GetSelectionMark(GetDlgItem(hWnd, IDC_LIST_EGGS)); 00381 if (sel != -1) { 00382 imp->SaveCheckState(); 00383 imp->RemoveEgg(sel); 00384 imp->UpdateUI(); 00385 } 00386 return TRUE; break; 00387 case IDC_EXPORT: 00388 imp->DoExport(); 00389 return TRUE; break; 00390 } 00391 } 00392 return FALSE; 00393 } 00394 00395 MaxEggPlugin::MaxEggPlugin() : 00396 autoOverwrite(false), pview(true), logOutput(false), numEggs(0), maxEggs(5) 00397 { 00398 eggList = new MaxOptionsDialog*[maxEggs]; 00399 BuildMesh(); 00400 } 00401 00402 MaxEggPlugin::~MaxEggPlugin() { 00403 for (int i = 0; i < numEggs; i++) delete eggList[i]; 00404 delete [] eggList; 00405 } 00406 00407 void MaxEggPlugin::AddEgg(MaxOptionsDialog *newEgg) { 00408 if (numEggs >= maxEggs) { 00409 MaxOptionsDialog **newList; 00410 maxEggs *= 2; 00411 newList = new MaxOptionsDialog*[maxEggs]; 00412 for (int i = 0; i < numEggs; i++) newList[i] = eggList[i]; 00413 delete [] eggList; 00414 eggList = newList; 00415 } 00416 00417 eggList[numEggs++] = newEgg; 00418 } 00419 00420 void MaxEggPlugin::RemoveEgg(int i) { 00421 if (i >= 0 && i < numEggs) { 00422 delete eggList[i]; 00423 for (int j = i+1; j < numEggs;) eggList[i++] = eggList[j++]; 00424 --numEggs; 00425 } 00426 } 00427 00428 void MaxEggPlugin::BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev ) 00429 { 00430 iObjParams = ip; 00431 for (int i=0; i<numEggs; i++) { 00432 eggList[i]->SetMaxInterface(ip); 00433 } 00434 00435 if ( !hMaxEggParams ) { 00436 hMaxEggParams = ip->AddRollupPage(hInstance, 00437 MAKEINTRESOURCE(IDD_PANEL), 00438 MaxEggPluginOptionsDlgProc, 00439 GetString(IDS_PARAMS), 00440 (LPARAM)this ); 00441 ip->RegisterDlgWnd(hMaxEggParams); 00442 } else { 00443 SetWindowLongPtr( hMaxEggParams, GWLP_USERDATA, (LPARAM)this ); 00444 } 00445 00446 UpdateUI(); 00447 } 00448 00449 void MaxEggPlugin::EndEditParams( IObjParam *ip, ULONG flags,Animatable *prev) 00450 { 00451 SaveCheckState(); 00452 if ( flags&END_EDIT_REMOVEUI ) { 00453 ip->UnRegisterDlgWnd(hMaxEggParams); 00454 ip->DeleteRollupPage(hMaxEggParams); 00455 hMaxEggParams = NULL; 00456 } else { 00457 SetWindowLongPtr( hMaxEggParams, GWLP_USERDATA, NULL ); 00458 } 00459 } 00460 00461 void MaxEggPlugin::SaveCheckState() { 00462 if (!hMaxEggParams) return; 00463 HWND lv = GetDlgItem(hMaxEggParams, IDC_LIST_EGGS); 00464 for (int i = 0; i < numEggs; i++) 00465 eggList[i]->_checked = ListView_GetCheckState(lv, i); 00466 } 00467 00468 void MaxEggPlugin::UpdateUI() { 00469 HWND lv = GetDlgItem(hMaxEggParams, IDC_LIST_EGGS); 00470 LV_COLUMN pCol; 00471 00472 if (ListView_GetColumnWidth(lv, 1) <= 0 || ListView_GetColumnWidth(lv, 1) > 10000) { 00473 //Columns have not been setup, so initialize the control 00474 ListView_SetExtendedListViewStyleEx(lv, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT, 00475 LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT); 00476 00477 pCol.fmt = LVCFMT_LEFT; 00478 pCol.cx = 96; 00479 pCol.pszText = "Filename"; 00480 pCol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; 00481 pCol.iSubItem = 0; 00482 ListView_InsertColumn(lv, 0, &pCol); 00483 00484 pCol.cx = 44; 00485 pCol.pszText = "Type"; 00486 ListView_InsertColumn(lv, 1, &pCol); 00487 } 00488 00489 //Add the eggs to the list 00490 ListView_DeleteAllItems(lv); 00491 LV_ITEM Item; 00492 Item.mask = LVIF_TEXT; 00493 00494 for (int i = 0; i < numEggs; i++) { 00495 Item.iItem = i; 00496 Item.iSubItem = 0; 00497 Item.pszText = eggList[i]->_short_name; 00498 ListView_InsertItem(lv, &Item); 00499 Item.iSubItem = 1; 00500 switch(eggList[i]->_anim_type) { 00501 case MaxEggOptions::AT_chan: Item.pszText = "Animation"; break; 00502 case MaxEggOptions::AT_both: Item.pszText = "Both"; break; 00503 case MaxEggOptions::AT_pose: Item.pszText = "Static"; break; 00504 case MaxEggOptions::AT_model: Item.pszText = "Model"; break; 00505 default: Item.pszText = "Model"; break; 00506 } 00507 ListView_SetItem(lv, &Item); 00508 ListView_SetCheckState(lv, i, eggList[i]->_checked); 00509 } 00510 00511 // Set the "Overwrite Existing Files" and "Pview" checkboxes 00512 CheckDlgButton(hMaxEggParams, IDC_OVERWRITE_CHECK, 00513 autoOverwrite ? BST_CHECKED : BST_UNCHECKED); 00514 CheckDlgButton(hMaxEggParams, IDC_PVIEW_CHECK, 00515 pview ? BST_CHECKED : BST_UNCHECKED); 00516 CheckDlgButton(hMaxEggParams, IDC_LOGGING, 00517 logOutput ? BST_CHECKED : BST_UNCHECKED); 00518 } 00519 00520 void MaxEggPlugin::DoExport() { 00521 int good = 0, bad = 0; 00522 00523 std::stringstream status; 00524 00525 SaveCheckState(); 00526 00527 for (int i = 0; i < numEggs; i++) { 00528 if (eggList[i]->_checked) { 00529 // If "auto overwrite" was not checked and the file exists, 00530 // ask if the user wishes to overwrite the file 00531 bool do_write = true; 00532 if (!autoOverwrite && Filename::from_os_specific(eggList[i]->_file_name).exists()) { 00533 char msg[1024]; 00534 sprintf(msg, "Overwrite file \"%s.egg\"?", eggList[i]->_short_name); 00535 do_write = (MessageBox(hMaxEggParams, msg, "Panda3D Exporter", MB_YESNO | MB_ICONQUESTION) == IDYES); 00536 } 00537 if (do_write) { 00538 MaxToEggConverter converter; 00539 if (converter.convert((MaxEggOptions*)eggList[i])) { 00540 good += 1; 00541 status << "Successfully created " << eggList[i]->_short_name << ".egg\n"; 00542 } else { 00543 bad += 1; 00544 status << "Could not export " << eggList[i]->_short_name << ".egg\n"; 00545 } 00546 } else { 00547 bad += 1; 00548 status << "Skipped file " << eggList[i]->_short_name << ".egg\n"; 00549 } 00550 } 00551 } 00552 00553 UINT mask = MB_OK; 00554 00555 if (good == 0 && bad == 0) { 00556 mask |= MB_ICONEXCLAMATION; 00557 MessageBox(hMaxEggParams, "Nothing to export!", "Panda3D Export results", mask); 00558 } else { 00559 if (bad > 0) mask |= MB_ICONEXCLAMATION; 00560 else mask |= MB_ICONINFORMATION; 00561 MessageBox(hMaxEggParams, status.str().c_str(), "Panda3D Export results", mask); 00562 } 00563 00564 int pviewed = 0; 00565 if (pview && good > 0) { 00566 for (i = 0; i < numEggs; i++) { 00567 if (eggList[i]->_checked && eggList[i]->_successful) { 00568 if (eggList[i]->_anim_type != MaxEggOptions::AT_chan) { 00569 PROCESS_INFORMATION pi; 00570 STARTUPINFO si; 00571 00572 memset(&si,0,sizeof(si)); 00573 si.cb= sizeof(si); 00574 00575 char cmdLine[2048]; 00576 // If we have just one model and animation file, pview them both 00577 if (numEggs == 2 && eggList[i]->_anim_type == MaxEggOptions::AT_model && 00578 eggList[1-i]->_checked && eggList[1-i]->_successful && 00579 eggList[1-i]->_anim_type == MaxEggOptions::AT_chan) { 00580 sprintf(cmdLine, "pview \"%s\" \"%s\"", eggList[i]->_file_name, eggList[1-i]->_file_name); 00581 } else { 00582 sprintf(cmdLine, "pview \"%s\"", eggList[i]->_file_name); 00583 } 00584 CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, 00585 NULL, NULL, &si, &pi); 00586 pviewed += 1; 00587 } 00588 } 00589 } 00590 } 00591 } 00592 00593 00594 void MaxEggPlugin::BuildMesh() 00595 { 00596 int i; 00597 if(meshBuilt) return; 00598 00599 mesh.setNumVerts(252); 00600 mesh.setNumFaces(84); 00601 mesh.setSmoothFlags(0); 00602 mesh.setNumTVerts (0); 00603 mesh.setNumTVFaces (0); 00604 00605 for (i=0; i<252; i++) 00606 mesh.setVert(i, meshVerts[i][0]*10, meshVerts[i][1]*10, meshVerts[i][2]*10); 00607 for (i=0; i<84; i++) { 00608 mesh.faces[i].setEdgeVisFlags(1, 1, 0); 00609 mesh.faces[i].setSmGroup(0); 00610 mesh.faces[i].setVerts(i*3, i*3+1, i*3+2); 00611 } 00612 00613 mesh.InvalidateGeomCache(); 00614 mesh.BuildStripsAndEdges(); 00615 00616 meshBuilt = TRUE; 00617 } 00618 00619 /////////////////////////////////////////////////////////////////////////////////////////////////////// 00620 // The creation callback - sets the initial position of the helper in the scene. 00621 /////////////////////////////////////////////////////////////////////////////////////////////////////// 00622 00623 class MaxEggPluginCreateMouseCallBack: public CreateMouseCallBack 00624 { 00625 public: 00626 int proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat ); 00627 }; 00628 00629 int MaxEggPluginCreateMouseCallBack::proc(ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat ) 00630 { 00631 if (msg==MOUSE_POINT||msg==MOUSE_MOVE) { 00632 switch(point) { 00633 case 0: 00634 mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE)); 00635 break; 00636 case 1: 00637 mat.SetTrans(vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE)); 00638 if (msg==MOUSE_POINT) return CREATE_STOP; 00639 break; 00640 } 00641 } else if (msg == MOUSE_ABORT) { 00642 return CREATE_ABORT; 00643 } 00644 return CREATE_CONTINUE; 00645 } 00646 00647 static MaxEggPluginCreateMouseCallBack MaxEggCreateMouseCB; 00648 00649 CreateMouseCallBack* MaxEggPlugin::GetCreateMouseCallBack() 00650 { return &MaxEggCreateMouseCB; } 00651 00652 /////////////////////////////////////////////////////////////////////////////////////////////////////// 00653 //Boilerplate functions for dealing with the display of the plugin 00654 /////////////////////////////////////////////////////////////////////////////////////////////////////// 00655 00656 void MaxEggPlugin::GetMat(TimeValue t, INode* inode, ViewExp* vpt, Matrix3& tm) 00657 { 00658 tm = inode->GetObjectTM(t); 00659 tm.NoScale(); 00660 PN_stdfloat scaleFactor = vpt->NonScalingObjectSize()*vpt->GetVPWorldWidth(tm.GetTrans())/(PN_stdfloat)360.0; 00661 tm.Scale(Point3(scaleFactor,scaleFactor,scaleFactor)); 00662 } 00663 00664 void MaxEggPlugin::GetDeformBBox(TimeValue t, Box3& box, Matrix3 *tm, BOOL useSel ) 00665 { 00666 box = mesh.getBoundingBox(tm); 00667 } 00668 00669 void MaxEggPlugin::GetLocalBoundBox(TimeValue t, INode* inode, ViewExp* vpt, Box3& box ) 00670 { 00671 Matrix3 m = inode->GetObjectTM(t); 00672 Point3 pt; 00673 Point3 q[4]; 00674 PN_stdfloat scaleFactor = vpt->GetVPWorldWidth(m.GetTrans())/360.0f; 00675 box = mesh.getBoundingBox(); 00676 box.Scale(scaleFactor); 00677 } 00678 00679 void MaxEggPlugin::GetWorldBoundBox(TimeValue t, INode* inode, ViewExp* vpt, Box3& box ) 00680 { 00681 int i, nv; Matrix3 tm; Point3 pt; 00682 GetMat(t,inode,vpt,tm); 00683 nv = mesh.getNumVerts(); 00684 box.Init(); 00685 for (i=0; i<nv; i++) 00686 box += tm*mesh.getVert(i); 00687 } 00688 00689 int MaxEggPlugin::HitTest(TimeValue t, INode *inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt) 00690 { 00691 HitRegion hitRegion; 00692 DWORD savedLimits; 00693 Matrix3 m; 00694 GraphicsWindow *gw = vpt->getGW(); 00695 Material *mtl = gw->getMaterial(); 00696 MakeHitRegion(hitRegion,type,crossing,4,p); 00697 gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM); 00698 GetMat(t,inode,vpt,m); 00699 gw->setTransform(m); 00700 gw->clearHitCode(); 00701 if (mesh.select( gw, mtl, &hitRegion, flags & HIT_ABORTONHIT )) 00702 return TRUE; 00703 return FALSE; 00704 } 00705 00706 int MaxEggPlugin::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags) 00707 { 00708 Matrix3 m; 00709 GraphicsWindow *gw = vpt->getGW(); 00710 Material *mtl = gw->getMaterial(); 00711 00712 GetMat(t,inode,vpt,m); 00713 gw->setTransform(m); 00714 DWORD rlim = gw->getRndLimits(); 00715 gw->setRndLimits(GW_WIREFRAME|GW_BACKCULL); 00716 if (inode->Selected()) 00717 gw->setColor( LINE_COLOR, GetSelColor()); 00718 else if(!inode->IsFrozen()) 00719 gw->setColor( LINE_COLOR, GetUIColor(COLOR_TAPE_OBJ)); 00720 mesh.render( gw, mtl, NULL, COMP_ALL); 00721 return 0; 00722 } 00723 00724 RefResult MaxEggPlugin::NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message ) 00725 { 00726 UpdateUI(); 00727 return REF_SUCCEED; 00728 } 00729 00730 ObjectState MaxEggPlugin::Eval(TimeValue time) 00731 { 00732 return ObjectState(this); 00733 } 00734 00735 Interval MaxEggPlugin::ObjectValidity(TimeValue t) 00736 { 00737 Interval ivalid; 00738 ivalid.SetInfinite(); 00739 return ivalid; 00740 } 00741 00742 RefTargetHandle MaxEggPlugin::Clone(RemapDir& remap) 00743 { 00744 MaxEggPlugin* newob = new MaxEggPlugin(); 00745 return(newob); 00746 } 00747 00748 /////////////////////////////////////////////////////////// 00749 // Loading and saving the plugin 00750 /////////////////////////////////////////////////////////// 00751 00752 IOResult MaxEggPlugin::Save(ISave *isave) { 00753 SaveCheckState(); 00754 for (int i = 0; i < numEggs; i++) 00755 eggList[i]->Save(isave); 00756 ChunkSave(isave, CHUNK_OVERWRITE_FLAG, autoOverwrite); 00757 ChunkSave(isave, CHUNK_PVIEW_FLAG, pview); 00758 ChunkSave(isave, CHUNK_LOG_OUTPUT, logOutput); 00759 00760 return IO_OK; 00761 } 00762 00763 IOResult MaxEggPlugin::Load(ILoad *iload) { 00764 IOResult res = iload->OpenChunk(); 00765 MaxOptionsDialog *temp; 00766 00767 while (res == IO_OK) { 00768 switch(iload->CurChunkID()) { 00769 case CHUNK_OVERWRITE_FLAG: autoOverwrite = ChunkLoadBool(iload); break; 00770 case CHUNK_PVIEW_FLAG: pview = ChunkLoadBool(iload); break; 00771 case CHUNK_LOG_OUTPUT: logOutput = ChunkLoadBool(iload); break; 00772 case CHUNK_EGG_EXP_OPTIONS: 00773 temp = new MaxOptionsDialog(); 00774 temp->SetMaxInterface(iObjParams); 00775 temp->Load(iload); 00776 AddEgg(temp); 00777 break; 00778 } 00779 iload->CloseChunk(); 00780 res = iload->OpenChunk(); 00781 } 00782 00783 return IO_OK; 00784 } 00785 00786 /********************************************************************** 00787 * 00788 * DLL Initialization 00789 * 00790 **********************************************************************/ 00791 00792 extern ClassDesc* GetMaxEggPluginDesc(); 00793 00794 HINSTANCE hInstance; 00795 int controlsInit = FALSE; 00796 00797 // This function is called by Windows when the DLL is loaded. This 00798 // function may also be called many times during time critical operations 00799 // like rendering. Therefore developers need to be careful what they 00800 // do inside this function. In the code below, note how after the DLL is 00801 // loaded the first time only a few statements are executed. 00802 00803 BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) 00804 { 00805 hInstance = hinstDLL; // Hang on to this DLL's instance handle. 00806 00807 if (!controlsInit) { 00808 controlsInit = TRUE; 00809 00810 #if MAX_VERSION_MAJOR < 14 00811 // It appears that InitCustomControls is deprecated in 2012. 00812 // I'm not sure if we can just remove it like this, but 00813 // I've heard that it seems to work, so let's do it like this. 00814 InitCustomControls(hInstance); // Initialize MAX's custom controls 00815 #endif 00816 InitCommonControls(); // Initialize Win95 controls 00817 } 00818 00819 return (TRUE); 00820 } 00821 00822 // This function returns a string that describes the DLL and where the user 00823 // could purchase the DLL if they don't have it. 00824 __declspec( dllexport ) const TCHAR* LibDescription() 00825 { 00826 return GetString(IDS_LIBDESCRIPTION); 00827 } 00828 00829 // This function returns the number of plug-in classes this DLL operates on. 00830 //TODO: Must change this number when adding a new class 00831 __declspec( dllexport ) int LibNumberClasses() 00832 { 00833 return 1; 00834 } 00835 00836 // This function returns the descriptions of the plug-in classes this DLL operates on. 00837 __declspec( dllexport ) ClassDesc* LibClassDesc(int i) 00838 { 00839 switch(i) { 00840 case 0: return GetMaxEggPluginDesc(); 00841 default: return NULL; 00842 } 00843 } 00844 00845 // This function returns a pre-defined constant indicating the version of 00846 // the system under which it was compiled. It is used to allow the system 00847 // to catch obsolete DLLs. 00848 __declspec( dllexport ) ULONG LibVersion() 00849 { 00850 return VERSION_3DSMAX; 00851 } 00852 00853 TCHAR *GetString(int id) 00854 { 00855 static TCHAR buf[256]; 00856 00857 if (hInstance) 00858 return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL; 00859 return NULL; 00860 } 00861