Panda3D
|
00001 /* 00002 maxEggExpOptions.cxx 00003 Created by Phillip Saltzman, 2/15/05 00004 Carnegie Mellon University, Entetainment Technology Center 00005 00006 This file implements the classes that are used to choose 00007 what to export from 3D Studio max 00008 00009 Updated by Fei Wang, Carnegie Mellon University Entertainment 00010 Technology Center student, 14Aug2009: added enableAddCollisionChoices 00011 */ 00012 00013 #include "maxEgg.h" 00014 00015 //Disable the forcing int to true or false performance warning 00016 #pragma warning(disable: 4800) 00017 00018 void SetICustEdit(HWND wnd, int nIDDlgItem, char *text) 00019 { 00020 ICustEdit *edit = GetICustEdit(GetDlgItem(wnd, nIDDlgItem)); 00021 edit->SetText(text); 00022 ReleaseICustEdit(edit); 00023 } 00024 00025 void SetICustEdit(HWND wnd, int nIDDlgItem, int n) 00026 { 00027 char text[80]; 00028 sprintf(text, "%d", n); 00029 ICustEdit *edit = GetICustEdit(GetDlgItem(wnd, nIDDlgItem)); 00030 edit->SetText(text); 00031 ReleaseICustEdit(edit); 00032 } 00033 00034 char *GetICustEditT(HWND wnd) 00035 { 00036 static char buffer[2084]; 00037 ICustEdit *edit = GetICustEdit(wnd); 00038 edit->GetText(buffer,2084); 00039 ReleaseICustEdit(edit); 00040 return buffer; 00041 } 00042 00043 int GetICustEditI(HWND wnd, BOOL *valid) 00044 { 00045 ICustEdit *edit = GetICustEdit(wnd); 00046 int i = edit->GetInt(valid); 00047 ReleaseICustEdit(edit); 00048 return i; 00049 } 00050 00051 void ChunkSave(ISave *isave, int chunkid, int value) 00052 { 00053 ULONG nb; 00054 isave->BeginChunk(chunkid); 00055 isave->Write(&value, sizeof(int), &nb); 00056 isave->EndChunk(); 00057 } 00058 00059 void ChunkSave(ISave *isave, int chunkid, ULONG value) 00060 { 00061 ULONG nb; 00062 isave->BeginChunk(chunkid); 00063 isave->Write(&value, sizeof(ULONG), &nb); 00064 isave->EndChunk(); 00065 } 00066 00067 void ChunkSave(ISave *isave, int chunkid, bool value) 00068 { 00069 ULONG nb; 00070 isave->BeginChunk(chunkid); 00071 isave->Write(&value, sizeof(bool), &nb); 00072 isave->EndChunk(); 00073 } 00074 00075 void ChunkSave(ISave *isave, int chunkid, char *value) 00076 { 00077 ULONG nb; 00078 isave->BeginChunk(chunkid); 00079 int bytes = strlen(value) + 1; 00080 isave->Write(&bytes, sizeof(int), &nb); 00081 isave->Write(value, bytes, &nb); 00082 isave->EndChunk(); 00083 } 00084 00085 char *ChunkLoadString(ILoad *iload, char *buffer, int maxBytes) 00086 { 00087 ULONG nb; 00088 int bytes; 00089 IOResult res; 00090 res = iload->Read(&bytes, sizeof(int), &nb); 00091 assert(res == IO_OK && bytes <= maxBytes); 00092 res = iload->Read(buffer, bytes, &nb); 00093 assert(res == IO_OK); 00094 return buffer; 00095 } 00096 00097 int ChunkLoadInt(ILoad *iload) 00098 { 00099 ULONG nb; 00100 int value; 00101 IOResult res; 00102 res = iload->Read(&value, sizeof(int), &nb); 00103 assert(res == IO_OK); 00104 return value; 00105 } 00106 00107 int ChunkLoadULONG(ILoad *iload) 00108 { 00109 ULONG nb, value; 00110 IOResult res; 00111 res = iload->Read(&value, sizeof(ULONG), &nb); 00112 assert(res == IO_OK); 00113 return value; 00114 } 00115 00116 bool ChunkLoadBool(ILoad *iload) 00117 { 00118 ULONG nb; 00119 bool value; 00120 IOResult res; 00121 res = iload->Read(&value, sizeof(bool), &nb); 00122 assert(res == IO_OK); 00123 return value; 00124 } 00125 00126 void showAnimControls(HWND hWnd, BOOL val) { 00127 ShowWindow(GetDlgItem(hWnd, IDC_EF_LABEL), val); 00128 ShowWindow(GetDlgItem(hWnd, IDC_EF), val); 00129 ShowWindow(GetDlgItem(hWnd, IDC_SF_LABEL), val); 00130 SetWindowText(GetDlgItem(hWnd, IDC_EXP_SEL_FRAMES), 00131 val ? "Use Range:" : "Use Frame:"); 00132 } 00133 00134 void enableAnimControls(HWND hWnd, BOOL val) { 00135 EnableWindow(GetDlgItem(hWnd, IDC_SF_LABEL), val); 00136 EnableWindow(GetDlgItem(hWnd, IDC_SF), val); 00137 EnableWindow(GetDlgItem(hWnd, IDC_EF_LABEL), val); 00138 EnableWindow(GetDlgItem(hWnd, IDC_EF), val); 00139 } 00140 00141 void enableChooserControls(HWND hWnd, BOOL val) { 00142 EnableWindow(GetDlgItem(hWnd, IDC_LIST_EXPORT), val); 00143 EnableWindow(GetDlgItem(hWnd, IDC_ADD_EXPORT), val); 00144 EnableWindow(GetDlgItem(hWnd, IDC_REMOVE_EXPORT), val); 00145 } 00146 00147 00148 #define ANIM_RAD_NONE 0 00149 #define ANIM_RAD_EXPALL 1 00150 #define ANIM_RAD_EXPSEL 2 00151 #define ANIM_RAD_ALL 3 00152 void enableAnimRadios(HWND hWnd, int mask) { 00153 EnableWindow(GetDlgItem(hWnd, IDC_EXP_ALL_FRAMES), mask & ANIM_RAD_EXPALL); 00154 EnableWindow(GetDlgItem(hWnd, IDC_EXP_SEL_FRAMES), mask & ANIM_RAD_EXPSEL); 00155 } 00156 00157 // Handles the work of actually picking the target. 00158 class AddNodeCB : public HitByNameDlgCallback 00159 { 00160 public: 00161 MaxOptionsDialog *ph; //Pointer to the parent class 00162 HWND hWnd; //Handle to the parent dialog 00163 00164 AddNodeCB (MaxOptionsDialog *instance, HWND wnd) : 00165 ph(instance), hWnd(wnd) {} 00166 00167 virtual TCHAR *dialogTitle() {return _T("Objects to Export");} 00168 virtual TCHAR *buttonText() {return _T("Select");} 00169 virtual int filter(INode *node); 00170 virtual void proc(INodeTab &nodeTab); 00171 }; 00172 00173 //This tells what should be in the list 00174 //Allow only triangular objects, nurbs, and joints 00175 int AddNodeCB::filter(INode *node) { 00176 if (!node) return 0; 00177 00178 Object *obj = node->EvalWorldState(0).obj; 00179 Control *c = node->GetTMController(); 00180 NURBSSet getSet; 00181 bool is_bone = (node->GetBoneNodeOnOff() || //True for bones 00182 (c && //True for bipeds 00183 ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) || 00184 (c->ClassID() == BIPBODY_CONTROL_CLASS_ID) || 00185 (c->ClassID() == FOOTPRINT_CLASS_ID)))); 00186 00187 00188 if (IsDlgButtonChecked(hWnd, IDC_ANIMATION) == BST_CHECKED) 00189 return is_bone && !ph->FindNode(node->GetHandle()); 00190 else 00191 return ( 00192 is_bone || ((obj->SuperClassID() == HELPER_CLASS_ID && obj->ClassID() != MaxEggPlugin_CLASS_ID)) || 00193 ((obj->SuperClassID() == GEOMOBJECT_CLASS_ID && //Allow geometrics 00194 obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) || 00195 (obj->SuperClassID() == SHAPE_CLASS_ID && //Allow CV NURBS 00196 obj->ClassID() == EDITABLE_SURF_CLASS_ID && 00197 GetNURBSSet(obj, 0, getSet, TRUE) && 00198 getSet.GetNURBSObject(0)->GetType() == kNCVCurve)) && 00199 !ph->FindNode(node->GetHandle())); //Only allow items not already selected 00200 } 00201 00202 //Adds all of the selected items to the list 00203 void AddNodeCB::proc(INodeTab &nodeTab) { 00204 00205 for (int i = 0; i < nodeTab.Count(); i++) 00206 ph->AddNode(nodeTab[i]->GetHandle()); 00207 ph->RefreshNodeList(hWnd); 00208 } 00209 00210 //This callback class generates a list of nodes that have previously been selected 00211 class RemoveNodeCB : public HitByNameDlgCallback 00212 { 00213 public: 00214 MaxOptionsDialog *ph; //Pointer to the parent class 00215 HWND hWnd; //Handle to the parent dialog 00216 00217 RemoveNodeCB (MaxOptionsDialog *instance, HWND wnd) : 00218 ph(instance), hWnd(wnd) {} 00219 00220 virtual TCHAR *dialogTitle() {return _T("Objects to Remove");} 00221 virtual TCHAR *buttonText() {return _T("Remove");} 00222 virtual int filter(INode *node) {return (node && ph->FindNode(node->GetHandle()));} 00223 virtual void proc(INodeTab &nodeTab); 00224 }; 00225 00226 00227 //Adds all of the selected items to the list 00228 void RemoveNodeCB::proc(INodeTab &nodeTab) { 00229 for (int i = 0; i < nodeTab.Count(); i++) 00230 ph->RemoveNodeByHandle(nodeTab[i]->GetHandle()); 00231 ph->RefreshNodeList(hWnd); 00232 } 00233 00234 MaxEggOptions::MaxEggOptions() { 00235 _max_interface = NULL; 00236 _anim_type = MaxEggOptions::AT_model; 00237 _start_frame = INT_MIN; 00238 _end_frame = INT_MIN; 00239 _double_sided = false; 00240 00241 00242 _file_name[0]=0; 00243 _short_name[0]=0; 00244 _path_replace = new PathReplace; 00245 _path_replace->_path_store = PS_relative; 00246 _export_whole_scene = true; 00247 _export_all_frames = true; 00248 _successful = false; 00249 } 00250 00251 INT_PTR CALLBACK MaxOptionsDialogProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) 00252 { 00253 char tempFilename[2048]; 00254 //We pass in our plugin through the lParam variable. Let's convert it back. 00255 MaxOptionsDialog *imp = (MaxOptionsDialog*)GetWindowLongPtr(hWnd,GWLP_USERDATA); 00256 if ( !imp && message != WM_INITDIALOG ) return FALSE; 00257 00258 switch(message) { 00259 00260 case WM_INITDIALOG: 00261 // this line is very necessary to pass the plugin as the lParam 00262 SetWindowLongPtr(hWnd,GWLP_USERDATA,lParam); 00263 ((MaxOptionsDialog*)lParam)->UpdateUI(hWnd); 00264 00265 return TRUE; break; 00266 00267 case WM_CLOSE: 00268 EndDialog(hWnd, FALSE); 00269 return TRUE; break; 00270 00271 case WM_COMMAND: 00272 //The modified control is found in the lower word of the wParam long. 00273 switch( LOWORD(wParam) ) { 00274 case IDC_MODEL: 00275 if (HIWORD(wParam) == BN_CLICKED) { 00276 SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED), 00277 "Export Meshes:"); 00278 enableAnimRadios(hWnd, ANIM_RAD_NONE); 00279 showAnimControls(hWnd, TRUE); 00280 enableAnimControls(hWnd, FALSE); 00281 if (imp->_prev_type == MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd); 00282 imp->_prev_type = MaxEggOptions::AT_model; 00283 00284 return TRUE; 00285 } 00286 break; 00287 00288 case IDC_ANIMATION: 00289 if (HIWORD(wParam) == BN_CLICKED) { 00290 SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED), 00291 "Export Bones:"); 00292 enableAnimRadios(hWnd, ANIM_RAD_ALL); 00293 showAnimControls(hWnd, TRUE); 00294 enableAnimControls(hWnd, IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES)); 00295 if (imp->_prev_type != MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd); 00296 imp->_prev_type = MaxEggOptions::AT_chan; 00297 CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, IDC_EXP_ALL_FRAMES); 00298 00299 return TRUE; 00300 } 00301 break; 00302 case IDC_BOTH: 00303 if (HIWORD(wParam) == BN_CLICKED) { 00304 SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED), 00305 "Export Models:"); 00306 enableAnimRadios(hWnd, ANIM_RAD_ALL); 00307 showAnimControls(hWnd, TRUE); 00308 enableAnimControls(hWnd, IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES)); 00309 if (imp->_prev_type == MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd); 00310 imp->_prev_type = MaxEggOptions::AT_both; 00311 CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, IDC_EXP_ALL_FRAMES); 00312 00313 return TRUE; 00314 } 00315 break; 00316 case IDC_POSE: 00317 if (HIWORD(wParam) == BN_CLICKED) { 00318 SetWindowText(GetDlgItem(hWnd, IDC_EXPORT_SELECTED), 00319 "Export Meshes:"); 00320 enableAnimRadios(hWnd, ANIM_RAD_EXPSEL); 00321 showAnimControls(hWnd, FALSE); 00322 enableAnimControls(hWnd, TRUE); 00323 CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, IDC_EXP_SEL_FRAMES); 00324 if (imp->_prev_type == MaxEggOptions::AT_chan) imp->ClearNodeList(hWnd); 00325 imp->_prev_type = MaxEggOptions::AT_pose; 00326 00327 return TRUE; 00328 } 00329 break; 00330 case IDC_EXP_ALL_FRAMES: 00331 if (HIWORD(wParam) == BN_CLICKED) { 00332 enableAnimControls(hWnd, FALSE); 00333 if(imp->_prev_type == MaxEggOptions::AT_chan) 00334 { 00335 CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_ANIMATION); 00336 } 00337 if(imp->_prev_type == MaxEggOptions::AT_both) 00338 { 00339 CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_BOTH); 00340 } 00341 return TRUE; 00342 } 00343 break; 00344 00345 case IDC_EXP_SEL_FRAMES: 00346 if (HIWORD(wParam) == BN_CLICKED) { 00347 enableAnimControls(hWnd, TRUE); 00348 if(imp->_prev_type == MaxEggOptions::AT_chan) 00349 { 00350 CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_ANIMATION); 00351 } 00352 if(imp->_prev_type == MaxEggOptions::AT_both) 00353 { 00354 CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, IDC_BOTH); 00355 } 00356 return TRUE; 00357 } 00358 break; 00359 00360 case IDC_EXPORT_ALL: 00361 if (HIWORD(wParam) == BN_CLICKED) { 00362 enableChooserControls(hWnd, FALSE); 00363 return TRUE; 00364 } 00365 break; 00366 00367 case IDC_EXPORT_SELECTED: 00368 if (HIWORD(wParam) == BN_CLICKED) { 00369 enableChooserControls(hWnd, TRUE); 00370 return TRUE; 00371 } 00372 break; 00373 00374 00375 // deal with adding meshes 00376 case IDC_ADD_EXPORT: 00377 { 00378 if (!imp->_choosing_nodes) { 00379 AddNodeCB PickCB(imp, hWnd); 00380 imp->_choosing_nodes = true; 00381 imp->_max_interface->DoHitByNameDialog(&PickCB); 00382 imp->_choosing_nodes = false; 00383 } 00384 } 00385 return TRUE; break; 00386 00387 case IDC_REMOVE_EXPORT: 00388 { 00389 if (!imp->_choosing_nodes) { 00390 imp->_choosing_nodes = true; 00391 RemoveNodeCB PickCB(imp, hWnd); 00392 imp->_max_interface->DoHitByNameDialog(&PickCB); 00393 imp->_choosing_nodes = false; 00394 } 00395 } 00396 return TRUE; break; 00397 00398 case IDC_OK: 00399 if (imp->UpdateFromUI(hWnd)) EndDialog(hWnd, TRUE); 00400 return TRUE; break; 00401 case IDC_CANCEL: 00402 EndDialog(hWnd, FALSE); 00403 return TRUE; break; 00404 case IDC_BROWSE: 00405 OPENFILENAME ofn; 00406 strcpy(tempFilename, GetICustEditT(GetDlgItem(hWnd, IDC_FILENAME))); 00407 00408 memset(&ofn, 0, sizeof(ofn)); 00409 ofn.nMaxFile = 2047; 00410 ofn.lpstrFile = tempFilename; 00411 ofn.lStructSize = sizeof(ofn); 00412 ofn.hwndOwner = hWnd; 00413 ofn.Flags = OFN_HIDEREADONLY | OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST; 00414 ofn.lpstrDefExt = "egg"; 00415 ofn.lpstrFilter = "Panda3D Egg Files (*.egg)\0*.egg\0All Files (*.*)\0*.*\0"; 00416 00417 SetFocus(GetDlgItem(hWnd, IDC_FILENAME)); 00418 if (GetSaveFileName(&ofn)) 00419 SetICustEdit(hWnd, IDC_FILENAME, ofn.lpstrFile); 00420 //else { 00421 // char buf[255]; 00422 // sprintf(buf, "%d", CommDlgExtendedError()); 00423 // MessageBox(hWnd, buf, "Error on GetSaveFileName", MB_OK); 00424 //} 00425 return TRUE; break; 00426 case IDC_CHECK1: 00427 if (IsDlgButtonChecked(hWnd, IDC_CHECK1)) 00428 if (MessageBox(hWnd, "Warning: Exporting double-sided polygons can severely hurt " 00429 "performance in Panda3D.\n\nAre you sure you want to export them?", 00430 "Panda3D Exporter", MB_YESNO | MB_ICONQUESTION) != IDYES) 00431 CheckDlgButton(hWnd, IDC_CHECK1, BST_UNCHECKED); 00432 return TRUE; break; 00433 00434 default: 00435 //char buf[255]; 00436 //sprintf(buf, "%d", LOWORD(wParam)); 00437 //MessageBox(hWnd, buf, "Unknown WParam", MB_OK); 00438 break; 00439 } 00440 } 00441 return FALSE; 00442 } 00443 00444 void MaxOptionsDialog::SetAnimRange() { 00445 // Get the start and end frames and the animation frame rate from Max 00446 Interval anim_range = _max_interface->GetAnimRange(); 00447 _min_frame = anim_range.Start()/GetTicksPerFrame(); 00448 _max_frame = anim_range.End()/GetTicksPerFrame(); 00449 } 00450 00451 MaxOptionsDialog::MaxOptionsDialog() : 00452 MaxEggOptions(), 00453 _min_frame(0), 00454 _max_frame(0), 00455 _checked(true), 00456 _choosing_nodes(false), 00457 _prev_type(AT_model) 00458 { 00459 } 00460 00461 MaxOptionsDialog::~MaxOptionsDialog () 00462 { 00463 } 00464 00465 00466 void MaxOptionsDialog::UpdateUI(HWND hWnd) { 00467 int typeButton = IDC_MODEL; 00468 int anim_exp = _export_all_frames ? IDC_EXP_ALL_FRAMES : IDC_EXP_SEL_FRAMES; 00469 int model_exp = _export_whole_scene ? IDC_EXPORT_ALL : IDC_EXPORT_SELECTED; 00470 00471 switch (_anim_type) { 00472 case MaxEggOptions::AT_chan: typeButton = IDC_ANIMATION; break; 00473 case MaxEggOptions::AT_both: typeButton = IDC_BOTH; break; 00474 case MaxEggOptions::AT_pose: typeButton = IDC_POSE; break; 00475 case MaxEggOptions::AT_model: typeButton = IDC_MODEL; break; 00476 } 00477 00478 _prev_type = _anim_type; 00479 00480 CheckRadioButton(hWnd, IDC_MODEL, IDC_POSE, typeButton); 00481 SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(typeButton, BN_CLICKED), 0); 00482 CheckRadioButton(hWnd, IDC_EXPORT_ALL, IDC_EXPORT_SELECTED, model_exp); 00483 SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(model_exp, BN_CLICKED), 0); 00484 CheckRadioButton(hWnd, IDC_EXP_ALL_FRAMES, IDC_EXP_SEL_FRAMES, anim_exp); 00485 SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(anim_exp, BN_CLICKED), 0); 00486 00487 CheckDlgButton(hWnd, IDC_CHECK1, 00488 _double_sided ? BST_CHECKED : BST_UNCHECKED); 00489 00490 00491 SetICustEdit(hWnd, IDC_FILENAME, _file_name); 00492 if (_start_frame != INT_MIN) { 00493 SetICustEdit(hWnd, IDC_SF, _start_frame); 00494 SetICustEdit(hWnd, IDC_EF, _end_frame); 00495 } else { 00496 SetICustEdit(hWnd, IDC_SF, _min_frame); 00497 SetICustEdit(hWnd, IDC_EF, _max_frame); 00498 } 00499 00500 RefreshNodeList(hWnd); 00501 } 00502 00503 void MaxOptionsDialog::ClearNodeList(HWND hWnd) { 00504 _node_list.clear(); 00505 RefreshNodeList(hWnd); 00506 } 00507 00508 void MaxOptionsDialog::RefreshNodeList(HWND hWnd) { 00509 //Clear and repopulate the node box 00510 HWND nodeLB = GetDlgItem(hWnd, IDC_LIST_EXPORT); 00511 SendMessage(nodeLB, LB_RESETCONTENT, 0, 0); 00512 for (int i = 0; i < _node_list.size(); i++) { 00513 INode *temp = _max_interface->GetINodeByHandle(_node_list[i]); 00514 TCHAR *name = _T("Unknown Node"); 00515 if (temp) name = temp->GetName(); 00516 SendMessage(nodeLB, LB_ADDSTRING, 0, (LPARAM)name); 00517 } 00518 } 00519 00520 bool MaxOptionsDialog::UpdateFromUI(HWND hWnd) { 00521 BOOL valid; 00522 Anim_Type newAnimType; 00523 int newSF = INT_MIN, newEF = INT_MIN; 00524 char msg[1024]; 00525 00526 if (IsDlgButtonChecked(hWnd, IDC_MODEL)) newAnimType = MaxEggOptions::AT_model; 00527 else if (IsDlgButtonChecked(hWnd, IDC_ANIMATION)) newAnimType = MaxEggOptions::AT_chan; 00528 else if (IsDlgButtonChecked(hWnd, IDC_BOTH)) newAnimType = MaxEggOptions::AT_both; 00529 else newAnimType = MaxEggOptions::AT_pose; 00530 00531 if (newAnimType != MaxEggOptions::AT_model && IsDlgButtonChecked(hWnd, IDC_EXP_SEL_FRAMES)) { 00532 newSF = GetICustEditI(GetDlgItem(hWnd, IDC_SF), &valid); 00533 if (!valid) { 00534 MessageBox(hWnd, "Start Frame must be an integer", "Invalid Value", MB_OK | MB_ICONEXCLAMATION); 00535 return false; 00536 } 00537 if (newSF < _min_frame) { 00538 sprintf(msg, "Start Frame must be at least %d", _min_frame); 00539 MessageBox(hWnd, msg, "Invalid Value", MB_OK | MB_ICONEXCLAMATION); 00540 return false; 00541 } 00542 if (newSF > _max_frame) { 00543 sprintf(msg, "Start Frame must be at most %d", _max_frame); 00544 MessageBox(hWnd, msg, "Invalid Value", MB_OK | MB_ICONEXCLAMATION); 00545 return false; 00546 } 00547 if (newAnimType != MaxEggOptions::AT_pose) { 00548 newEF = GetICustEditI(GetDlgItem(hWnd, IDC_EF), &valid); 00549 if (!valid) { 00550 MessageBox(hWnd, "End Frame must be an integer", "Invalid Value", MB_OK | MB_ICONEXCLAMATION); 00551 return false; 00552 } 00553 if (newEF > _max_frame) { 00554 sprintf(msg, "End Frame must be at most %d", _max_frame); 00555 MessageBox(hWnd, msg, "Invalid Value", MB_OK | MB_ICONEXCLAMATION); 00556 return false; 00557 } 00558 if (newEF < newSF) { 00559 MessageBox(hWnd, "End Frame must be greater than the start frame", "Invalid Value", MB_OK | MB_ICONEXCLAMATION); 00560 return false; 00561 } 00562 } 00563 } 00564 00565 char *temp = GetICustEditT(GetDlgItem(hWnd, IDC_FILENAME)); 00566 if (!strlen(temp)) { 00567 MessageBox(hWnd, "The filename cannot be empty", "Invalid Value", MB_OK | MB_ICONEXCLAMATION); 00568 return false; 00569 } 00570 00571 if (strlen(temp) < 4 || strncmp(".egg", temp+(strlen(temp) - 4), 4)) 00572 sprintf(_file_name, "%s.egg", temp); 00573 else strcpy(_file_name, temp); 00574 00575 temp = strrchr(_file_name, '\\'); 00576 if (!temp) temp = _file_name; 00577 else temp++; 00578 00579 if (strlen(temp) > sizeof(_short_name)) 00580 sprintf(_short_name, "%.*s...", sizeof(_short_name)-4, temp); 00581 else { 00582 strcpy(_short_name, temp); 00583 _short_name[strlen(_short_name) - 4] = NULL; //Cut off the .egg 00584 } 00585 00586 _start_frame = newSF; 00587 _end_frame = newEF; 00588 _anim_type = newAnimType; 00589 _double_sided = IsDlgButtonChecked(hWnd, IDC_CHECK1); 00590 00591 00592 _export_whole_scene = IsDlgButtonChecked(hWnd, IDC_EXPORT_ALL); 00593 _export_all_frames = IsDlgButtonChecked(hWnd, IDC_EXP_ALL_FRAMES); 00594 00595 return true; 00596 } 00597 00598 bool MaxOptionsDialog::FindNode(ULONG INodeHandle) { 00599 for (int i = 0; i < _node_list.size(); i++) 00600 if (_node_list[i] == INodeHandle) return true; 00601 return false; 00602 } 00603 00604 void MaxOptionsDialog::AddNode(ULONG INodeHandle) { 00605 if (FindNode(INodeHandle)) return; 00606 _node_list.push_back(INodeHandle); 00607 } 00608 00609 void MaxOptionsDialog::CullBadNodes() { 00610 if (!_max_interface) return; 00611 std::vector<ULONG> good; 00612 for (int i=0; i<_node_list.size(); i++) { 00613 ULONG handle = _node_list[i]; 00614 if (_max_interface->GetINodeByHandle(handle)) { 00615 good.push_back(handle); 00616 } 00617 } 00618 _node_list = good; 00619 } 00620 00621 void MaxOptionsDialog::RemoveNode(int i) { 00622 if (i >= 0 && i < _node_list.size()) { 00623 for (int j = i+1; j < _node_list.size(); j++) 00624 _node_list[i++] = _node_list[j++]; 00625 _node_list.pop_back(); 00626 } 00627 } 00628 00629 void MaxOptionsDialog::RemoveNodeByHandle(ULONG INodeHandle) { 00630 for (int i = 0; i < _node_list.size(); i++) { 00631 if (_node_list[i] == INodeHandle) { 00632 RemoveNode(i); 00633 return; 00634 } 00635 } 00636 } 00637 00638 IOResult MaxOptionsDialog::Save(ISave *isave) { 00639 isave->BeginChunk(CHUNK_EGG_EXP_OPTIONS); 00640 ChunkSave(isave, CHUNK_ANIM_TYPE, _anim_type); 00641 ChunkSave(isave, CHUNK_FILENAME, _file_name); 00642 ChunkSave(isave, CHUNK_SHORTNAME, _short_name); 00643 ChunkSave(isave, CHUNK_SF, _start_frame); 00644 ChunkSave(isave, CHUNK_EF, _end_frame); 00645 ChunkSave(isave, CHUNK_DBL_SIDED, _double_sided); 00646 ChunkSave(isave, CHUNK_EGG_CHECKED, _checked); 00647 ChunkSave(isave, CHUNK_ALL_FRAMES, _export_all_frames); 00648 ChunkSave(isave, CHUNK_EXPORT_FULL, _export_whole_scene); 00649 00650 isave->BeginChunk(CHUNK_NODE_LIST); 00651 for (int i = 0; i < _node_list.size(); i++) 00652 ChunkSave(isave, CHUNK_NODE_HANDLE, _node_list[i]); 00653 isave->EndChunk(); 00654 isave->EndChunk(); 00655 return IO_OK; 00656 } 00657 00658 IOResult MaxOptionsDialog::Load(ILoad *iload) { 00659 IOResult res = iload->OpenChunk(); 00660 00661 while (res == IO_OK) { 00662 switch(iload->CurChunkID()) { 00663 case CHUNK_ANIM_TYPE: _anim_type = (Anim_Type)ChunkLoadInt(iload); break; 00664 case CHUNK_FILENAME: ChunkLoadString(iload, _file_name, sizeof(_file_name)); break; 00665 case CHUNK_SHORTNAME: ChunkLoadString(iload, _short_name, sizeof(_short_name)); break; 00666 case CHUNK_SF: _start_frame = ChunkLoadInt(iload); break; 00667 case CHUNK_EF: _end_frame = ChunkLoadInt(iload); break; 00668 case CHUNK_DBL_SIDED: _double_sided = ChunkLoadBool(iload); break; 00669 case CHUNK_EGG_CHECKED: _checked = ChunkLoadBool(iload); break; 00670 case CHUNK_ALL_FRAMES: _export_all_frames = ChunkLoadBool(iload); break; 00671 case CHUNK_EXPORT_FULL: _export_whole_scene = ChunkLoadBool(iload); break; 00672 00673 case CHUNK_NODE_LIST: 00674 res = iload->OpenChunk(); 00675 while (res == IO_OK) { 00676 if (iload->CurChunkID() == CHUNK_NODE_HANDLE) AddNode(ChunkLoadULONG(iload)); 00677 iload->CloseChunk(); 00678 res = iload->OpenChunk(); 00679 } 00680 break; 00681 } 00682 iload->CloseChunk(); 00683 res = iload->OpenChunk(); 00684 } 00685 00686 if (res == IO_END) return IO_OK; 00687 return IO_ERROR; 00688 } 00689