Panda3D

maxEgg.cxx

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 
 All Classes Functions Variables Enumerations