00001
00002
00003
00004
00005
00006
00012 #include "Window.h"
00013 #include "Configuration.h"
00014 #include "Opengl.h"
00015 #include "Object.h"
00016 #include "ObjectManager.h"
00017 #include "Camera.h"
00018 #include "Message.h"
00019 #include "random.h"
00020
00021
00022 #include <sys/types.h>
00023 #include <dirent.h>
00024
00025
00026
00027
00028 int Window::mainWindow;
00029 GLUI* Window::optionWindow;
00030 GLUI * Window::subWindow;
00031 GLUI * Window::constructWindow;
00032
00033 GLUI_Listbox * Window::fileSelector;
00034 GLUI_Listbox * Window::intSelector;
00035 GLUI_Listbox * Window::objectSelector;
00036 GLUI_Button * Window::bAnimationForward;
00037 GLUI_Button * Window::bToggleConstructMode;
00038 GLUI_Spinner * Window::sCameraSave ;
00039 int Window::fileCount;
00040 int Window::objectCount = 0;
00041 GLUI_Translation * Window::tz;
00042 GLUI_Translation * Window::txy;
00043 GLUI_StaticText * Window::txtRenderDetails;
00044 char * Window::txt = 0;
00045 Window::CONSTRUCT_MODE Window::move_mode = NONE;
00046
00047 GLUI_Panel * Window::pSelectedObject;
00048 GLUI_Spinner * Window::sSemimajor;
00049 GLUI_Spinner * Window::sSemiminor;
00050 GLUI_Spinner * Window::sMass;
00051 GLUI_Spinner * Window::sRadius;
00052 GLUI_Spinner * Window::sScaleFactor;
00053
00054 GLUI_Spinner * Window::sCSMaxMass;
00055 GLUI_Spinner * Window::sCSMaxV;
00056 GLUI_Spinner * Window::sCSMaxR;
00057 GLUI_Spinner * Window::sCSMaxPos;
00058 GLUI_Spinner * Window::sCSPlanets;
00059 GLUI_Spinner * Window::sCSSuns;
00060
00061
00063 int Window::count_mouse_buttons=0;
00065 int Window::xlast=0, Window::ylast=0;
00068 Vector Window::constructVectorBackup;
00069
00070
00078 void Window::HandleKeyboard(unsigned char key, int x, int y) {
00079 switch (key) {
00080 case 'p':
00081
00082 ourObjectManager.viewDetailInformationForAllObjects();
00083 break;
00084 case '.':
00085
00086 ourCamera.rotateKeepViewPoint(0, 0,-1);
00087
00088 glutPostRedisplay();
00089 break;
00090 case ',':
00091
00092 ourCamera.rotateKeepViewPoint(0, 0,1);
00093
00094 glutPostRedisplay();
00095 break;
00096 case 's':
00097
00098 Opengl::singleStep();
00099 break;
00100 case 27:
00101
00102 exit(0);
00103 break;
00104 }
00105 }
00106
00115 void Window::HandlePassiveMouseMotion(int x, int y) {
00116 if(x < 10 && ! ourConfiguration.showMenu) {
00117 Window::showMenu();
00118 }
00119 }
00120
00130 void Window::HandleMouse(int button, int state, int x, int y) {
00131 int modifier_ = glutGetModifiers();
00132
00133 if (state == GLUT_DOWN) {
00134
00135 count_mouse_buttons++;
00136 ourCamera.action = Camera::NONE;
00137
00138
00139 uint objClickedPointer_=Opengl::getObjectID(x, y);
00140
00141 if (count_mouse_buttons == 1) {
00142
00143 if( ourConfiguration.constructMode && objClickedPointer_ != 0 &&
00144 button != GLUT_LEFT_BUTTON) {
00145
00146
00147 Window::selectObject(reinterpret_cast<Object*>
00148 (objClickedPointer_));
00149 if(button == GLUT_RIGHT_BUTTON) {
00150 if(modifier_ == GLUT_ACTIVE_SHIFT)
00151 Window::setConstructMode(Window::MOVEZ);
00152 else
00153 Window::setConstructMode(Window::MOVEXY);
00154 constructVectorBackup = ourConfiguration.clickedObject->pos;
00155 } else if(button == GLUT_MIDDLE_BUTTON) {
00156 if(modifier_ == GLUT_ACTIVE_SHIFT)
00157 Window::setConstructMode(Window::SPEEDZ);
00158 else
00159 Window::setConstructMode(Window::SPEEDXY);
00160 constructVectorBackup = ourConfiguration.clickedObject->v;
00161 }
00162
00163 } else {
00164 if (modifier_ == 0) {
00165 if (button == GLUT_RIGHT_BUTTON)
00166 ourCamera.action = Camera::ROTATEXY;
00167 else if (button == GLUT_MIDDLE_BUTTON)
00168 ourCamera.action = Camera::ROTATEZ;
00169 else {
00170 if (objClickedPointer_ != 0) {
00171
00172
00173 Window::selectObject(reinterpret_cast<Object*>
00174 (objClickedPointer_));
00175 ourCamera.setProjectionCenter(
00176 ourConfiguration.clickedObject->getScaledPos() );
00177 glutPostRedisplay();
00178 }
00179 }
00180 } else if(modifier_ == GLUT_ACTIVE_SHIFT) {
00181
00182 if (button == GLUT_MIDDLE_BUTTON)
00183 ourCamera.action = Camera::FORWARD;
00184 else if (button == GLUT_RIGHT_BUTTON)
00185 ourCamera.action = Camera::ROTATEKEEPPOSXY;
00186 else
00187 ourCamera.action = Camera::MOVE;
00188 } else if(modifier_ == GLUT_ACTIVE_CTRL) {
00189 if (button == GLUT_LEFT_BUTTON)
00190 ourCamera.action = Camera::ZOOM;
00191 }
00192 }
00193 }
00194 } else if (state == GLUT_UP) {
00195
00196 count_mouse_buttons--;
00197
00198 ourCamera.action = Camera::NONE;
00199
00200 Window::setConstructMode(Window::NONE);
00201 }
00202
00203
00204 xlast = x;
00205 ylast = y;
00206 }
00207
00208
00217 void Window::HandleMouseMotion(int x, int y) {
00218 int dx, dy;
00219
00220
00221 dx = xlast -x;
00222 dy = y - ylast;
00223
00224
00225 if(dy==0 && dx == 0)
00226 return;
00227
00228
00229 Window::CONSTRUCT_MODE cmodus=Window::getConstructMode();
00230
00231 if(! cmodus == Window::NONE) {
00232
00233
00234
00235
00236
00237
00238
00239 switch(cmodus) {
00240 case Window::SPEEDZ: {
00241 Vector viewDirection =
00242 ourCamera.getPosition()-ourConfiguration.clickedObject->pos;
00243 double length = viewDirection.length();
00244
00245 ourConfiguration.clickedObject->v = constructVectorBackup -
00246 viewDirection * dy * length / ourCamera.getScreenHeight();
00247
00248 ourConfiguration.clickedObject->refreshAttributes();
00249 return;
00250 }
00251 case Window::SPEEDXY: {
00252 Vector cupper = ourCamera.getUpper();
00253 Vector cviewDirectionOrthogonal =
00254 ourCamera.getViewDirectionOrthogonal();
00255
00256 double distance=(ourCamera.getPosition() -
00257 constructVectorBackup).length();
00258 ourConfiguration.clickedObject->v = constructVectorBackup -
00259 cupper * dy * distance / ourCamera.getScreenHeight();
00260
00261 ourConfiguration.clickedObject->v -= cviewDirectionOrthogonal *
00262 dx * distance / ourCamera.getScreenWidth();
00263
00264 ourConfiguration.clickedObject->refreshAttributes();
00265 return;
00266 }
00267 case Window::MOVEZ: {
00268 Vector viewDirection =
00269 ourCamera.getPosition()-constructVectorBackup;
00270 double length = viewDirection.length();
00271
00272 ourConfiguration.clickedObject->pos = constructVectorBackup -
00273 viewDirection * dy * length / ourCamera.getScreenHeight();
00274
00275 ourConfiguration.clickedObject->refreshAttributes();
00276 return;
00277 }
00278 case Window::MOVEXY: {
00279 Vector cupper = ourCamera.getUpper();
00280 Vector cviewDirectionOrthogonal =
00281 ourCamera.getViewDirectionOrthogonal();
00282
00283 double distance=(ourCamera.getPosition() -
00284 constructVectorBackup).length();
00285 ourConfiguration.clickedObject->pos = constructVectorBackup -
00286 cupper * dy * distance / ourCamera.getScreenHeight();
00287
00288 ourConfiguration.clickedObject->pos -= cviewDirectionOrthogonal
00289 * dx * distance / ourCamera.getScreenWidth();
00290
00291 ourConfiguration.clickedObject->refreshAttributes();
00292 return;
00293 }
00294 default:
00295 cerr << "WARNING UNKNOWN CONSTRUCTION MODE" << endl;
00296 }
00297
00298 } else {
00299
00300
00301
00302
00303 switch(ourCamera.action) {
00304 case Camera::ROTATEXY: {
00305 ourCamera.rotateKeepViewPoint(dy, dx, 0);
00306 break;
00307 }
00308 case Camera::ROTATEZ: {
00309 ourCamera.rotateKeepViewPoint(0, 0, dx);
00310 break;
00311 }
00312 case Camera::ZOOM: {
00313 if(dy < 0)
00314
00315 ourCamera.zoom(0.9);
00316 else
00317
00318 ourCamera.zoom(1.11);
00319 break;
00320 }
00321 case Camera::FORWARD: {
00322
00323 ourCamera.moveForward(dy);
00324 break;
00325 }
00326 case Camera::MOVE: {
00327
00328 ourCamera.move(-dy,-dx);
00329 break;
00330 }
00331 case Camera::ROTATEKEEPPOSXY: {
00332
00333 ourCamera.rotateKeepPosition(dy, -dx);
00334 break;
00335 }
00336 case Camera::NONE: {}
00337
00338 }
00339 }
00340
00341
00342 xlast = x;
00343 ylast = y;
00344
00345
00346 glutPostRedisplay();
00347 }
00348
00357 void Window::HandleSpecialKeyboard(int key, int x, int y) {
00358 int modifier_ = glutGetModifiers();
00359
00360
00361 if(modifier_ == 0) {
00362
00363
00364
00365
00366
00367 switch (key) {
00368 case GLUT_KEY_LEFT:
00369 ourCamera.rotateKeepViewPoint(0,1,0);
00370 break;
00371 case GLUT_KEY_RIGHT:
00372 ourCamera.rotateKeepViewPoint(0,-1,0);
00373 break;
00374 case GLUT_KEY_UP:
00375 ourCamera.rotateKeepViewPoint(1,0,0);
00376 break;
00377 case GLUT_KEY_DOWN:
00378 ourCamera.rotateKeepViewPoint(-1,0, 0);
00379 break;
00380 case GLUT_KEY_PAGE_DOWN:
00381 ourCamera.zoom(2);
00382 break;
00383 case GLUT_KEY_PAGE_UP:
00384 ourCamera.zoom(0.5);
00385 break;
00386 case GLUT_KEY_END:
00387
00388 ourCamera.setAllToViewObject(
00389 ourObjectManager.getFarthestAwayObject());
00390 break;
00391 case GLUT_KEY_HOME:
00392 ourCamera.home();
00393 break;
00394 case GLUT_KEY_F9:
00395 ourCamera.saveAktuallCameraPosition(ourConfiguration.cameraSaveSlot);
00396 break;
00397 case GLUT_KEY_F10:
00398 ourCamera.loadAktuallCameraPosition(ourConfiguration.cameraSaveSlot);
00399 break;
00400 case GLUT_KEY_F11:
00401
00402 ourConfiguration.saveWorld(ourConfiguration.filename,true);
00403 break;
00404 case GLUT_KEY_F12:
00405
00406 ourConfiguration.loadWorld(ourConfiguration.filename,true);
00407 break;
00408 }
00409 } else if(modifier_ == GLUT_ACTIVE_SHIFT ) {
00410
00411 switch (key) {
00412 case GLUT_KEY_LEFT:
00413 ourCamera.move(0, -1);
00414 break;
00415 case GLUT_KEY_RIGHT:
00416 ourCamera.move(0, 1);
00417 break;
00418 case GLUT_KEY_UP:
00419 ourCamera.move(1,0);
00420 break;
00421 case GLUT_KEY_DOWN:
00422 ourCamera.move(-1, 0);
00423 break;
00424 case GLUT_KEY_PAGE_DOWN:
00425 ourCamera.moveForward(-1);
00426 break;
00427 case GLUT_KEY_PAGE_UP:
00428 ourCamera.moveForward(1);
00429 break;
00430 }
00431
00432 } else if(modifier_ == GLUT_ACTIVE_ALT ) {
00433
00434 switch (key) {
00435 case GLUT_KEY_LEFT:
00436 ourCamera.rotateKeepPosition(0, -1);
00437 break;
00438 case GLUT_KEY_RIGHT:
00439 ourCamera.rotateKeepPosition(0, 1);
00440 break;
00441 case GLUT_KEY_UP:
00442 ourCamera.rotateKeepPosition(-1, 0);
00443 break;
00444 case GLUT_KEY_DOWN:
00445 ourCamera.rotateKeepPosition(1, 0);
00446 break;
00447 }
00448 }
00449
00450
00451 glutPostRedisplay();
00452 }
00453
00454
00460 void Window::setRenderDetails(const string & s) {
00461 if(txt != 0)
00462 delete(txt);
00463 txt= new char[s.length()+1];
00464 strncpy(txt,s.c_str(), s.length()+1);
00465
00466
00467 txtRenderDetails->set_text(txt);
00468 }
00469
00470
00476 Window::CONSTRUCT_MODE Window::getConstructMode() {
00477 if ( ourConfiguration.constructMode )
00478 return move_mode;
00479 return NONE;
00480 }
00481
00482
00488 void Window::reloadObjectSelector() {
00489 loadObjectSelector(true);
00490
00491 objectSelector->do_selection(0);
00492
00493 selectObject(ourConfiguration.clickedObject);
00494 }
00495
00496
00501 void Window::setSatelliteProperties() {
00502 if(ourConfiguration.clickedObject == NULL)
00503 return;
00504 sSemiminor->set_double_limits( 1e-100, 1e100 );
00505 sSemimajor->set_double_limits( 1e-100, 1e100 );
00506 sMass->set_double_limits( 1e-100, ourConfiguration.clickedObject->mass );
00507 sRadius->set_double_limits( 1e-100, ourConfiguration.clickedObject->radius*4);
00508
00509 sSemimajor->set_double_val(ourConfiguration.clickedObject->radius*150);
00510 sSemiminor->set_double_val(ourConfiguration.clickedObject->radius*100);
00511 sMass->set_double_val(ourConfiguration.clickedObject->mass/1e12);
00512 sRadius->set_double_val(ourConfiguration.clickedObject->radius/4);
00513 }
00514
00515
00521 void Window::selectObject( Object * obj ) {
00522
00523 if ( obj == NULL && ourConfiguration.clickedObject != NULL )
00524 ourConfiguration.clickedObject->closeAttributeWindow();
00525
00526
00527 ourConfiguration.clickedObject = obj;
00528 if( ourConfiguration.constructMode ) {
00529 if ( ourConfiguration.clickedObject == NULL ) {
00530 pSelectedObject->disable();
00531 } else {
00532 pSelectedObject->enable();
00533 setSatelliteProperties();
00534 }
00535 if(obj != NULL)
00536 obj->createAttributeWindow();
00537 }
00538
00539 if(obj == NULL) {
00540 objectSelector->do_selection(0);
00541 } else if ( ! objectSelector->active ) {
00542
00543 objectList * oList = ourObjectManager.getObjectList();
00544 objectCount = oList->size();
00545
00546 int id = 0;
00547 int select = 0;
00548 for ( objectList::iterator it = oList->begin() ; it != oList->end();
00549 it ++ ) {
00550 if ( *it == ourConfiguration.clickedObject )
00551 select = id;
00552 id++;
00553 }
00554 objectSelector->do_selection( select + 1 );
00555 }
00556
00557 }
00558
00564 void Window::setAnimationControls( bool disable ) {
00565 if ( disable ) {
00566
00567
00568 bToggleConstructMode->disable();
00569 loadObjectSelector( false );
00570 } else {
00571
00572
00573 bToggleConstructMode->enable();
00574 loadObjectSelector( true );
00575 }
00576
00577 }
00578
00584 void Window::load() {
00585 Window::showConstructMenu( ourConfiguration.constructMode );
00586 Window::setAnimationControls( false );
00587 Window::selectObject(ourConfiguration.clickedObject);
00588
00589
00590 intSelector->do_selection( Integrator::TypeToInt(
00591 ourConfiguration.integrator->getName() ) );
00592
00593
00594 setSatelliteProperties();
00595
00596 sCameraSave->set_int_val( ourConfiguration.cameraSaveSlot );
00597 sScaleFactor->set_double_val( ourConfiguration.linearScaleFactor);
00598 subWindow->sync_live();
00599 optionWindow->sync_live();
00600 constructWindow->sync_live();
00601 }
00602
00609 void Window::loadObjectSelector( bool load ) {
00610 if ( load ) {
00611
00612 for ( int i = 1; i <= objectCount; i++ )
00613 objectSelector->delete_item( i );
00614
00615 objectSelector->enable();
00616
00617
00618 objectList * oList = ourObjectManager.getObjectList();
00619 objectCount = oList->size();
00620
00621
00622 int id = 1;
00623 int select = 0;
00624 for ( objectList::iterator it = oList->begin() ; it != oList->end();
00625 it ++ ) {
00626 objectSelector->add_item( id, ( *it ) ->getName() );
00627 if ( *it == ourConfiguration.clickedObject )
00628 select = id;
00629 id++;
00630 }
00631 objectSelector->do_selection( select );
00632
00633 } else {
00634
00635 objectSelector->disable();
00636 for ( int i = 1; i <= objectCount; i++ )
00637 objectSelector->delete_item( i );
00638 objectCount = 0;
00639 }
00640 }
00641
00642
00646 void Window::showMenu() {
00647 ourConfiguration.showMenu = true;
00648 subWindow->show();
00649 Opengl::reloadWindow();
00650 }
00651
00656 void Window::showConstructMenu( bool show ) {
00657 if ( show ) {
00658 bAnimationForward->disable();
00659 constructWindow->show();
00660 } else {
00661 Object::closeAttributeWindow();
00662 constructWindow->hide();
00663 bAnimationForward->enable();
00664 }
00665 }
00666
00672 void Window::CreateWindows( int mainWin ) {
00673 mainWindow = mainWin;
00674
00675
00676 glutPassiveMotionFunc(& Window::HandlePassiveMouseMotion);
00677
00678
00679 GLUI_Master.set_glutKeyboardFunc(& Window::HandleKeyboard);
00680
00681
00682 GLUI_Master.set_glutSpecialFunc(& Window::HandleSpecialKeyboard);
00683
00684
00685 GLUI_Master.set_glutMouseFunc(& Window::HandleMouse);
00686
00687
00688 glutMotionFunc(& Window::HandleMouseMotion);
00689
00690
00691 CreateMainWindow(mainWin);
00692 CreateConstructWindow();
00693 CreateOptionWindow();
00694 Message::CreateWindow(mainWin);
00695 }
00696
00700 void Window::CreateOptionWindow() {
00701
00702 const GLUI_Update_CB mc = ( GLUI_Update_CB ) Window::MenuOptionCallback;
00703
00704
00705 optionWindow = GLUI_Master.create_glui( "Options" );
00706
00707
00708 GLUI_Panel * pLoadSave = optionWindow->add_panel( "Files" );
00709 GLUI_EditText * etSave= optionWindow->add_edittext_to_panel( pLoadSave,
00710 "Filename", GLUI_EDITTEXT_TEXT, & ourConfiguration.filename );
00711
00712 etSave->set_w(300);
00713
00714 fileSelector = optionWindow->add_listbox_to_panel( pLoadSave, "Files",
00715 NULL , FILE_SELECTOR_LIST, mc );
00716 fileSelector->set_w(300);
00717 optionWindow->add_column_to_panel( pLoadSave, false );
00718 optionWindow->add_button_to_panel( pLoadSave, "Save", SAVE, mc );
00719 optionWindow->add_button_to_panel( pLoadSave, "Load", LOAD, mc );
00720
00721
00722
00723 GLUI_Panel * pDisplayOptions = optionWindow->add_panel( "Display Options" );
00724
00725 GLUI_Panel * pModelView = optionWindow->add_panel_to_panel( pDisplayOptions,
00726 "Model View" );
00727 GLUI_RadioGroup * rgModel = optionWindow->add_radiogroup_to_panel(
00728 pModelView, & ourConfiguration.viewModel );
00729 optionWindow->add_radiobutton_to_group( rgModel, "Points" );
00730 optionWindow->add_radiobutton_to_group( rgModel, "Grid" );
00731 optionWindow->add_radiobutton_to_group( rgModel, "Solid" );
00732
00733 GLUI_Panel * pLight = optionWindow->add_panel_to_panel( pDisplayOptions,
00734 "Light" );
00735 optionWindow->add_checkbox_to_panel( pLight, "Show", ( &
00736 ourConfiguration.showLighting ) );
00737
00738 GLUI_Panel * pTexture = optionWindow->add_panel_to_panel( pDisplayOptions,
00739 "Texture" );
00740 optionWindow->add_checkbox_to_panel( pTexture, "Show", (
00741 &ourConfiguration.showTextures ) );
00742
00743 optionWindow->add_column_to_panel( pDisplayOptions, true );
00744
00745 GLUI_Spinner * sphereDetail = optionWindow->add_spinner_to_panel(
00746 pDisplayOptions, "Sphere Detail", GLUI_SPINNER_INT,
00747 & ourConfiguration.sphereDetaillevel );
00748 sphereDetail->set_int_limits( 2, 200 );
00749
00750 GLUI_Spinner * radiusAdaption = optionWindow->add_spinner_to_panel(
00751 pDisplayOptions, "Radius adaption",
00752 GLUI_SPINNER_INT,
00753 & ourConfiguration.radiusAdaption );
00754 radiusAdaption->set_int_limits( 1, 300000 );
00755 radiusAdaption->set_w(250);
00756
00757 sScaleFactor = optionWindow->add_spinner_to_panel( pDisplayOptions,
00758 "Scale Factor", GLUI_SPINNER_DOUBLE, NULL, CHANGE_SCALEFAKTOR , mc );
00759 sScaleFactor->set_double_limits( 1e-300, 1e300 );
00760 sScaleFactor->set_w(250);
00761 sScaleFactor->set_double_val(1.0);
00762
00763 optionWindow->add_button_to_panel(pDisplayOptions, "Autoscaling",
00764 AUTOSCALING , mc);
00765 optionWindow->add_checkbox_to_panel( pDisplayOptions, "Auto adaption", (
00766 & ourConfiguration.autoAdaption ) , AUTOADAPTION,mc);
00767 optionWindow->add_checkbox_to_panel( pDisplayOptions, "View Vector", (
00768 & ourConfiguration.viewVectors ) );
00769 optionWindow->add_checkbox_to_panel( pDisplayOptions, "Draw Old Positions",(
00770 & ourConfiguration.drawOldPositions ) );
00771
00772 GLUI_Spinner * sTimeSteps = optionWindow->add_spinner_to_panel( pDisplayOptions,
00773 "Draw Old Steps", GLUI_SPINNER_INT,
00774 & ourConfiguration.drawOldPositionsTimeSteps);
00775 sTimeSteps->set_int_limits( 0, 300000 );
00776 sTimeSteps->set_w(200);
00777
00778
00779
00780
00781 GLUI_Panel * pInt = optionWindow->add_panel( "Integrator" );
00782 intSelector = optionWindow->add_listbox_to_panel( pInt, "Type", NULL,
00783 INTEGRATOR, mc );
00784
00785 for ( int i = 0; i < Integrator::getTypeCount(); i++ ) {
00786 intSelector->add_item( i, Integrator::NumToType( i ) );
00787 }
00788 optionWindow->add_button_to_panel( pInt, "Options", INTEGRATOROPTION, mc );
00789
00790
00791
00792 optionWindow->set_main_gfx_window( getMainWindow() );
00793
00794
00795 optionWindow->hide();
00796 }
00797
00802 void Window::CreateMainWindow(int mainWindow) {
00803
00804 const GLUI_Update_CB mc = ( GLUI_Update_CB ) Window::MenuMainCallback;
00805
00806 subWindow = GLUI_Master.create_glui_subwindow( mainWindow,
00807 GLUI_SUBWINDOW_LEFT );
00808
00809
00810 GLUI_Panel * pPosition = subWindow->add_panel( "Position" );
00811 subWindow->add_checkbox_to_panel( pPosition, "3D shooter like", (
00812 & ourConfiguration.movelike3Dshooter ) );
00813 txy = subWindow->add_translation_to_panel( pPosition, "XY",
00814 GLUI_TRANSLATION_XY, NULL, TRANSLATION_XY, mc );
00815 tz = subWindow->add_translation_to_panel( pPosition, "Z",
00816 GLUI_TRANSLATION_Z, NULL, TRANSLATION_Z, mc );
00817
00818
00819 GLUI_Panel * pObject = subWindow->add_panel( "Object" );
00820 subWindow->add_checkbox_to_panel( pObject, "Follow",
00821 & ourConfiguration.followObject );
00822 subWindow->add_checkbox_to_panel( pObject, "View Flight",
00823 & ourConfiguration.viewToObjectsFlightDirection );
00824 objectSelector = subWindow->add_listbox_to_panel( pObject, "Object", NULL,
00825 OBJECT_SELECT, mc );
00826 objectSelector->add_item( 0, "NONE" );
00827 subWindow->add_button_to_panel(pObject,"Zoom", ZOOM_OBJECT,mc );
00828
00829
00830 GLUI_Panel * pControl = subWindow->add_panel( "Control" );
00831 GLUI_Panel * pControlAnimation = subWindow->add_panel_to_panel( pControl,
00832 "", 0 );
00833 GLUI_Button * b = subWindow->add_button_to_panel( pControlAnimation, "||",
00834 PAUSE, mc );
00835 subWindow->add_column_to_panel( pControlAnimation, false );
00836 b = subWindow->add_button_to_panel( pControlAnimation, "+", SINGLESTEP, mc );
00837 subWindow->add_column_to_panel( pControlAnimation, false );
00838 bAnimationForward = subWindow->add_button_to_panel( pControlAnimation, ">",
00839 CONTINUE, mc );
00840
00841 GLUI_EditText * sspeed = subWindow->add_edittext_to_panel( pControl, "time",
00842 GLUI_EDITTEXT_DOUBLE, & ourConfiguration.speed );
00843 sspeed->set_double_limits( 1e-3, 1e20 );
00844 sspeed->set_w(30);
00845 subWindow->add_column_to_panel(pControl,true);
00846
00847 GLUI_RadioGroup * rgTime = subWindow->add_radiogroup_to_panel( pControl,
00848 & ourConfiguration.speedType );
00849 subWindow->add_radiobutton_to_group( rgTime, "s" );
00850 subWindow->add_radiobutton_to_group( rgTime, "h" );
00851 subWindow->add_radiobutton_to_group( rgTime, "d" );
00852 subWindow->add_radiobutton_to_group( rgTime, "m" );
00853 subWindow->add_radiobutton_to_group( rgTime, "y" );
00854
00855
00856
00857 GLUI_Panel * pCamera = subWindow->add_panel( "Camera", true );
00858 sCameraSave = subWindow->add_spinner_to_panel( pCamera, "Slot",
00859 GLUI_SPINNER_INT,
00860 & ourConfiguration.cameraSaveSlot );
00861 sCameraSave->set_int_limits( 0, Camera::CAMERA_SAVES-1 );
00862 GLUI_Panel * pCameraLS = subWindow->add_panel_to_panel( pCamera, "", 0 );
00863 b = subWindow->add_button_to_panel( pCameraLS, "Save", SAVECAMERA, mc );
00864 subWindow->add_column_to_panel( pCameraLS, false );
00865 b = subWindow->add_button_to_panel( pCameraLS, "Load", LOADCAMERA, mc );
00866 b=subWindow->add_button( "Optionen", TOGGLE_VIEW_OPTIONS , mc );
00867 bToggleConstructMode = subWindow->add_button( "Construct Mode",
00868 TOGGLE_CONSTRUCT_MODE , mc );
00869 b=subWindow->add_button( "Hide Menu", HIDE_MENU , mc );
00870
00871
00872 txtRenderDetails = subWindow->add_statictext( "fps:" );
00873
00874
00875 subWindow->set_main_gfx_window( mainWindow );
00876 }
00877
00881 void Window::CreateConstructWindow() {
00882
00883 GLUI_Update_CB mc = ( GLUI_Update_CB ) Window::MenuConstructionCallback;
00884
00885 constructWindow = GLUI_Master.create_glui( "Constructor" );
00886
00887
00888 GLUI_Panel * pCreate = constructWindow->add_panel( "Create" );
00889
00890
00891
00892
00893
00894
00895
00896 for ( int i = 0; i < ObjectManager::getTypeCount(); i++ ) {
00897 GLUI_Button * b = constructWindow->add_button_to_panel( pCreate,
00898 ObjectManager::NumToType( i ), i ,mc );
00899 b->set_w(100);
00900 }
00901
00902
00903 pSelectedObject = constructWindow->add_rollout( "Selected Object" );
00904 pSelectedObject->disable();
00905
00906 constructWindow->add_button_to_panel( pSelectedObject,"Delete", DELETE, mc );
00907 constructWindow->add_separator_to_panel(pSelectedObject);
00908 GLUI_Panel * pAddMoon =
00909 constructWindow->add_rollout_to_panel(pSelectedObject, "Add Satellite" );
00910 sSemimajor = constructWindow->add_spinner_to_panel( pAddMoon,
00911 "semimajor axis",GLUI_SPINNER_DOUBLE);
00912 sSemimajor->set_w(200);
00913 sSemiminor = constructWindow->add_spinner_to_panel( pAddMoon,
00914 "semiminor axis",GLUI_SPINNER_DOUBLE);
00915 sSemiminor->set_w(200);
00916 sMass = constructWindow->add_spinner_to_panel( pAddMoon,
00917 "mass",GLUI_SPINNER_DOUBLE);
00918 sMass->set_w(200);
00919 sMass->set_double_limits(1.0,1e80);
00920 sRadius = constructWindow->add_spinner_to_panel( pAddMoon,
00921 "radius",GLUI_SPINNER_DOUBLE);
00922 sRadius->set_w(200);
00923 constructWindow->add_button_to_panel( pAddMoon,"Add", ADD_MOON, mc );
00924
00925
00926
00927 GLUI_Panel * pConstructSystem= constructWindow->add_rollout(
00928 "Construct System",false);
00929 sCSMaxMass = constructWindow->add_spinner_to_panel( pConstructSystem,
00930 "mass max",GLUI_SPINNER_INT);
00931 sCSMaxMass->set_int_limits(1,70);
00932 sCSMaxMass->set_int_val(30);
00933
00934 sCSMaxV = constructWindow->add_spinner_to_panel( pConstructSystem,
00935 "v max",GLUI_SPINNER_INT);
00936 sCSMaxV->set_int_limits(0,9);
00937 sCSMaxV->set_int_val(2);
00938
00939 sCSMaxR = constructWindow->add_spinner_to_panel( pConstructSystem,
00940 "r max",GLUI_SPINNER_INT);
00941 sCSMaxR->set_int_limits(1,30);
00942 sCSMaxR->set_int_val(7);
00943
00944 sCSMaxPos = constructWindow->add_spinner_to_panel( pConstructSystem,
00945 "pos max",GLUI_SPINNER_INT);
00946 sCSMaxPos->set_int_limits(3,30);
00947 sCSMaxPos->set_int_val(10);
00948
00949 constructWindow->add_separator_to_panel(pConstructSystem);
00950
00951 sCSPlanets = constructWindow->add_spinner_to_panel( pConstructSystem,
00952 "Planets",GLUI_SPINNER_INT);
00953 sCSPlanets->set_int_limits(0,100);
00954 sCSPlanets->set_int_val(10);
00955
00956 sCSSuns = constructWindow->add_spinner_to_panel( pConstructSystem,
00957 "Suns",GLUI_SPINNER_INT);
00958 sCSSuns->set_int_limits(0,10);
00959 sCSSuns->set_int_val(2);
00960
00961 constructWindow->add_button_to_panel( pConstructSystem,"Create System",
00962 CREATE_SYSTEM, mc );
00963 constructWindow->add_button_to_panel( pConstructSystem,"CLEAR SYSTEM",
00964 CLEAR_SYSTEM, mc );
00965
00966
00967 constructWindow->set_main_gfx_window( getMainWindow() );
00968
00969 constructWindow->hide();
00970 }
00971
00976 void Window::FillFileSelector() {
00977
00978 ClearFileSelector();
00979
00980 DIR * dir = opendir( "save" );
00981 if ( dir == 0 ) {
00982 cerr << "WARNUNG: Directory save does not exist!" << endl;
00983 return ;
00984 }
00985 dirent * dentry;
00986 while ( ( dentry = readdir( dir ) ) ) {
00987 if ( dentry->d_reclen < 300 ) {
00988 string s( dentry->d_name );
00989 uint pos = s.find( FILE_EXTENSION );
00990
00991 if ( pos != string::npos ) {
00992 dentry->d_name[ pos ] = 0;
00993 fileSelector->add_item( fileCount, dentry->d_name );
00994 fileCount ++;
00995 }
00996 } else
00997 cerr << "WARNING save/" << dentry->d_name <<
00998 " name is longer than 300" << endl;
00999 }
01000 closedir( dir );
01001 }
01002
01006 void Window::ClearFileSelector() {
01007 for ( int i = 0; i < fileCount; i++ )
01008 fileSelector->delete_item( i );
01009 fileCount = 0;
01010 }
01011
01018 void Window::MenuConstructionCallback( callbackConstruction b ) {
01019 if ( b < 1000 ) {
01020
01021 string type =ObjectManager::NumToType( b );
01022 Object * newObject = ourObjectManager.createObject( type );
01023 newObject->pos = ourCamera.getProjectionCenter();
01024 newObject->radius = ( ourCamera.getPosition() -
01025 ourCamera.getProjectionCenter() ).length() * 0.1;
01026 selectObject(newObject);
01027 newObject->createAttributeWindow();
01028
01029
01030 loadObjectSelector( true );
01031 return ;
01032 }
01033
01034
01035 switch ( b ) {
01036 case ( ADD_MOON ) : {
01037
01038
01039
01040 if ( ourConfiguration.clickedObject == 0 ) {
01041 cerr << "WARNING No Basis Object selected" << endl;
01042 return ;
01043 }
01044
01045 Object * newObject = ourObjectManager.createObject( "planet" );
01046 Object * basisObject = ourConfiguration.clickedObject;
01047
01048 double a = sSemimajor->get_double_val();
01049 double b = sSemiminor->get_double_val();
01050 if(a<b) {
01051 double z=a;
01052 a=b;
01053 b=z;
01054 }
01055
01056 double perigaeumLength = a - sqrt( sqr( a ) - sqr( b ) );
01057 double apogaeumLength = 2 * a - perigaeumLength;
01058 double numericalExcentricity = ( apogaeumLength - perigaeumLength )
01059 / ( apogaeumLength + perigaeumLength );
01060 double formParameter = a * ( 1 - sqr( numericalExcentricity ) );
01061 double vLength = ( sqrt( GAMMA * basisObject->mass * formParameter )
01062 / perigaeumLength );
01063
01064 newObject->radius = sRadius->get_double_val();
01065 newObject->mass = sMass->get_double_val();
01066
01067
01068 Vector randv( drand( -1, 1 ), drand( -1, 1 ), drand( -1, 1 ) );
01069 while ( randv.length() == 0 )
01070 randv = Vector( drand( -1, 1 ), drand( -1, 1 ), drand( -1, 1 ) );
01071 newObject->pos = basisObject->pos + randv.getNormalised() *
01072 perigaeumLength;
01073
01074
01075 randv = Vector( drand( -1, 1 ), drand( -1, 1 ), drand( -1, 1 ) );
01076 Vector diff = basisObject->pos - newObject->pos;
01077
01078
01079
01080 while ( randv.length() == 0 || randv.x / diff.x ==
01081 randv.y / diff.y ) {
01082 randv = Vector( drand( -1, 1 ), drand( -1, 1 ), drand( -1, 1 ) );
01083 }
01084
01085 Vector flight = randv.getNormalised().crossProduct(
01086 diff ).getNormalised();
01087 newObject->v = basisObject->v + flight * vLength;
01088 break;
01089 }
01090 case ( DELETE ) : {
01091
01092 if ( ourConfiguration.clickedObject != 0 ) {
01093 ourConfiguration.clickedObject->closeAttributeWindow();
01094 ourObjectManager.deleteObject( ourConfiguration.clickedObject );
01095 selectObject(NULL);
01096 } else {
01097 cerr << "No Valid Object Selected !" << endl;
01098 }
01099 break;
01100 }
01101 case(CLEAR_SYSTEM): {
01102
01103 ourObjectManager.deleteAllObjects();
01104 break;
01105 }
01106 case(CREATE_SYSTEM): {
01107
01108 for(int i=0; i < sCSPlanets->get_int_val() ;i++) {
01109 ourObjectManager.createRandomObject("planet",
01110 sCSMaxMass->get_int_val(),
01111 sCSMaxPos->get_int_val(),
01112 sCSMaxR->get_int_val(),
01113 sCSMaxV->get_int_val());
01114 }
01115
01116 for(int i=0; i < sCSSuns->get_int_val() ;i++) {
01117 ourObjectManager.createRandomObject("sun",
01118 sCSMaxMass->get_int_val(),
01119 sCSMaxPos->get_int_val(),
01120 sCSMaxR->get_int_val(),
01121 sCSMaxV->get_int_val());
01122 }
01123
01124
01125 ourCamera.setAllToViewObject(
01126 ourObjectManager.getFarthestAwayObject());
01127 break;
01128 }
01129 default:
01130 cerr << "WARNING Unknown CREATE BUTTON PRESSED: " << b << endl;
01131 }
01132
01133
01134 loadObjectSelector( true );
01135 }
01136
01143 void Window::MenuMainCallback( callbackMain b ) {
01144 switch ( b ) {
01145 case ( PAUSE ) : {
01146
01147 Opengl::setAnimation( false );
01148 break;
01149 }
01150 case ( CONTINUE ) : {
01151
01152 Opengl::setAnimation( true );
01153 break;
01154 }
01155 case ( SINGLESTEP ) : {
01156
01157
01158 Opengl::singleStep();
01159 break;
01160 }
01161 case ( TRANSLATION_XY ) : {
01162
01163 static double oldx = txy->get_x();
01164 static double oldy = txy->get_y();
01165 int diffx = int( oldx - txy->get_x() );
01166 int diffy = int( oldy - txy->get_y() );
01167
01168 if ( ourConfiguration.movelike3Dshooter )
01169 ourCamera.move( -diffy, -diffx );
01170 else
01171 ourCamera.rotateKeepViewPoint( -diffy, diffx, 0 );
01172
01173 oldx = txy->get_x();
01174 oldy = txy->get_y();
01175 break;
01176 }
01177 case ( TRANSLATION_Z ) : {
01178
01179 static double oldz = tz->get_z();
01180 double diffz = ( oldz - tz->get_z() );
01181
01182 if ( ourConfiguration.movelike3Dshooter )
01183 ourCamera.moveForward( -diffz );
01184 else {
01185 if ( diffz > 0 )
01186 diffz = 1.11;
01187 else
01188 diffz = 0.9;
01189 ourCamera.zoom( diffz );
01190 }
01191
01192 oldz = tz->get_z();
01193 break;
01194 }
01195 case(SAVECAMERA) : {
01196 ourCamera.saveAktuallCameraPosition(
01197 ourConfiguration.cameraSaveSlot );
01198 break;
01199 }
01200 case(LOADCAMERA) : {
01201 ourCamera.loadAktuallCameraPosition(
01202 ourConfiguration.cameraSaveSlot );
01203 break;
01204 }
01205 case( OBJECT_SELECT ) : {
01206
01207 int sel = objectSelector->get_int_val();
01208 if ( sel == 0 ) {
01209 selectObject(NULL) ;
01210 return ;
01211 }
01212
01213
01214
01215
01216 objectList * oList = ourObjectManager.getObjectList();
01217 objectCount = oList->size();
01218 objectList::iterator it = oList->begin();
01219 for ( int c = 1 ; c < sel;c ++ )
01220 it++;
01221
01222
01223 Object * obj_ = *it;
01224 Vector pos_=obj_->getScaledPos();
01225
01226 ourCamera.zoomTo( pos_, obj_->getScaledRadius() * 10 );
01227 ourCamera.setProjectionCenter( pos_ );
01228
01229 selectObject(obj_);
01230
01231 if( ourConfiguration.constructMode )
01232 obj_->createAttributeWindow();
01233 break;
01234 }
01235 case(ZOOM_OBJECT): {
01236
01237 if(ourConfiguration.clickedObject == NULL)
01238 break;
01239
01240 Vector pos_=ourConfiguration.clickedObject->getScaledPos();
01241 if (ourConfiguration.autoAdaption )
01242 ourCamera.zoomTo( pos_, ourConfiguration.clickedObject->radius *
01243 ourConfiguration.linearScaleFactor * 10 );
01244 else
01245 ourCamera.zoomTo( pos_,
01246 ourConfiguration.clickedObject->getScaledRadius() * 10 );
01247 ourCamera.setProjectionCenter( pos_ );
01248 break;
01249 }
01250 case ( HIDE_MENU ) : {
01251
01252 ourConfiguration.showMenu = false;
01253 subWindow->hide();
01254 Opengl::reloadWindow();
01255
01256 break;
01257 }
01258 case( TOGGLE_CONSTRUCT_MODE ) : {
01259
01260 ourConfiguration.constructMode = !ourConfiguration.constructMode;
01261 showConstructMenu( ourConfiguration.constructMode );
01262 break;
01263 }
01264 case( TOGGLE_VIEW_OPTIONS ) : {
01265
01266 ourConfiguration.showOptionMenu = !ourConfiguration.showOptionMenu;
01267 if ( ourConfiguration.showOptionMenu ) {
01268 FillFileSelector();
01269 optionWindow->show();
01270 } else {
01271 ClearFileSelector();
01272 optionWindow->hide();
01273 }
01274 break;
01275 }
01276 default:
01277 cout << "KEY " << b << " nicht definiert !" << endl;
01278 }
01279
01280
01281 Opengl::redraw();
01282 }
01283
01284
01291 void Window::MenuOptionCallback( callbackOption b ) {
01292 switch ( b ) {
01293 case(CHANGE_SCALEFAKTOR): {
01294
01295
01296 double oldLSF = ourConfiguration.linearScaleFactor;
01297 double newLSF = sScaleFactor->get_double_val();
01298 ourConfiguration.linearScaleFactor = newLSF;
01299 ourCamera.changeLinearScaleFactor(newLSF/oldLSF);
01300 break;
01301 }
01302 case(AUTOADAPTION): {
01303
01304
01305 ourCamera.reloadAutomaticAdaption();
01306 optionWindow->sync_live();
01307 break;
01308 }
01309 case (AUTOSCALING): {
01310
01311
01312 double old_ = ourConfiguration.linearScaleFactor;
01313 double maxdist =
01314 ourObjectManager.getFarthestAwayObject()->pos.length();
01315 if(maxdist == 0) maxdist = 1;
01316 ourConfiguration.linearScaleFactor = 100.0 / maxdist;
01317 ourCamera.changeLinearScaleFactor(
01318 ourConfiguration.linearScaleFactor / old_);
01319
01320 sScaleFactor->set_double_val(ourConfiguration.linearScaleFactor);
01321 break;
01322 }
01323 case( INTEGRATOROPTION ) : {
01324
01325 ourConfiguration.integrator->createAttributeWindow();
01326 break;
01327 }
01328 case( INTEGRATOR ) : {
01329
01330
01331 Integrator::closeAttributeWindow();
01332 delete( ourConfiguration.integrator );
01333 ourConfiguration.integrator = Integrator::createIntegrator(
01334 ( char * ) intSelector->curr_text );
01335 break;
01336 }
01337 case( SAVE ) : {
01338
01339 ourConfiguration.saveWorld( ourConfiguration.filename, true );
01340
01341 FillFileSelector();
01342 break;
01343 }
01344 case( LOAD ) : {
01345
01346 ourConfiguration.loadWorld( ourConfiguration.filename, true );
01347 break;
01348 }
01349 case( FILE_SELECTOR_LIST ) : {
01350
01351 strncpy( ourConfiguration.filename, fileSelector->curr_text,
01352 SIZEOFGLUISTRING );
01353 optionWindow->sync_live();
01354 break;
01355 }
01356 default:
01357 cout << "KEY " << b << " nicht definiert !" << endl;
01358 }
01359
01360 }
01361
01367 void Window::setConstructMode(CONSTRUCT_MODE m) {
01368 move_mode = m;
01369 }
01370
01375 int Window::getMainWindow() {
01376 return mainWindow;
01377 }
01378
01379
01380