From 08bbb83b8e3a009c49c30bb6fedec61be59d6ba3 Mon Sep 17 00:00:00 2001 From: curt Date: Tue, 5 Feb 2002 20:54:08 +0000 Subject: [PATCH] A grab bag of tweaks and patches from Norman Vine. - Better mingwin/cygwin support - Various gui tweaks and code clean ups - Initialization clean ups - Hitlist/scenery tweaks - other misc. stuff. --- src/Autopilot/auto_gui.cxx | 32 ++-- src/Autopilot/auto_gui.hxx | 13 -- src/Autopilot/newauto.cxx | 32 ++-- src/FDM/flight.cxx | 2 +- src/GUI/gui.cxx | 1 + src/GUI/gui.h | 24 +-- src/GUI/mouse.cxx | 219 ++++++++++++++++------- src/GUI/sgVec3Slider.cxx | 3 +- src/Main/fg_init.cxx | 353 +++++++++++++++++-------------------- src/Main/main.cxx | 34 ++-- src/Network/atc610x.hxx | 4 +- src/Scenery/hitlist.cxx | 196 ++++++++++++++++++-- src/Scenery/hitlist.hxx | 25 --- 13 files changed, 556 insertions(+), 382 deletions(-) diff --git a/src/Autopilot/auto_gui.cxx b/src/Autopilot/auto_gui.cxx index 43c63b84a..a4859803d 100644 --- a/src/Autopilot/auto_gui.cxx +++ b/src/Autopilot/auto_gui.cxx @@ -26,12 +26,21 @@ # include #endif +#include + #include #include +#include + +#include STL_STRING +#include +#include +#include #include #include +#include #include #include #include @@ -46,6 +55,8 @@ #include "auto_gui.hxx" #include "newauto.hxx" +SG_USING_STD(string); + #define mySlider puSlider @@ -212,7 +223,7 @@ void NewHeading(puObject *cb) FG_PUSH_PUI_DIALOG( ApHeadingDialog ); } -void NewHeadingInit(void) +void NewHeadingInit() { // printf("NewHeadingInit\n"); char NewHeadingLabel[] = "Enter New Heading"; @@ -284,7 +295,7 @@ void NewAltitude(puObject *cb) FG_PUSH_PUI_DIALOG( ApAltitudeDialog ); } -void NewAltitudeInit(void) +void NewAltitudeInit() { // printf("NewAltitudeInit\n"); char NewAltitudeLabel[] = "Enter New Altitude"; @@ -331,15 +342,12 @@ void NewAltitudeInit(void) FG_FINALIZE_PUI_DIALOG( ApAltitudeDialog ); } -/////// simple AutoPilot GAIN / LIMITS ADJUSTER - -#define fgAP_CLAMP(val,min,max) ( (val) = (val) > (max) ? (max) : (val) < (min) ? (min) : (val) ) static void maxroll_adj( puObject *hs ) { float val ; hs-> getValue ( &val ) ; - fgAP_CLAMP ( val, 0.1, 1.0 ) ; + SG_CLAMP_RANGE ( val, 0.1f, 1.0f ) ; // printf ( "maxroll_adj( %p ) %f %f\n", hs, val, MaxRollAdjust * val ) ; current_autopilot->set_MaxRoll( MaxRollAdjust * val ); sprintf( SliderText[ 0 ], "%05.2f", current_autopilot->get_MaxRoll() ); @@ -350,7 +358,7 @@ static void rollout_adj( puObject *hs ) { float val ; hs-> getValue ( &val ) ; - fgAP_CLAMP ( val, 0.1, 1.0 ) ; + SG_CLAMP_RANGE ( val, 0.1f, 1.0f ) ; // printf ( "rollout_adj( %p ) %f %f\n", hs, val, RollOutAdjust * val ) ; current_autopilot->set_RollOut( RollOutAdjust * val ); sprintf( SliderText[ 1 ], "%05.2f", current_autopilot->get_RollOut() ); @@ -361,7 +369,7 @@ static void maxaileron_adj( puObject *hs ) { float val ; hs-> getValue ( &val ) ; - fgAP_CLAMP ( val, 0.1, 1.0 ) ; + SG_CLAMP_RANGE ( val, 0.1f, 1.0f ) ; // printf ( "maxaileron_adj( %p ) %f %f\n", hs, val, MaxAileronAdjust * val ) ; current_autopilot->set_MaxAileron( MaxAileronAdjust * val ); sprintf( SliderText[ 3 ], "%05.2f", current_autopilot->get_MaxAileron() ); @@ -372,7 +380,7 @@ static void rolloutsmooth_adj( puObject *hs ) { float val ; hs -> getValue ( &val ) ; - fgAP_CLAMP ( val, 0.1, 1.0 ) ; + SG_CLAMP_RANGE ( val, 0.1f, 1.0f ) ; // printf ( "rolloutsmooth_adj( %p ) %f %f\n", hs, val, RollOutSmoothAdjust * val ) ; current_autopilot->set_RollOutSmooth( RollOutSmoothAdjust * val ); sprintf( SliderText[ 2 ], "%5.2f", current_autopilot->get_RollOutSmooth() ); @@ -405,7 +413,7 @@ void resetAPAdjust( puObject *self ) { fgAPAdjust( self ); } -void fgAPAdjust( puObject * ) { +void fgAPAdjust( puObject *self ) { TmpMaxRollValue = current_autopilot->get_MaxRoll(); TmpRollOutValue = current_autopilot->get_RollOut(); TmpMaxAileronValue = current_autopilot->get_MaxAileron(); @@ -426,7 +434,7 @@ void fgAPAdjust( puObject * ) { } // Done once at system initialization -void fgAPAdjustInit( void ) { +void fgAPAdjustInit() { // printf("fgAPAdjustInit\n"); #define HORIZONTAL FALSE @@ -671,7 +679,7 @@ void ClearRoute(puObject *cb) globals->get_route()->clear(); } -void NewTgtAirportInit(void) +void NewTgtAirportInit() { SG_LOG( SG_AUTOPILOT, SG_INFO, " enter NewTgtAirportInit()" ); sprintf( NewTgtAirportId, "%s", diff --git a/src/Autopilot/auto_gui.hxx b/src/Autopilot/auto_gui.hxx index 6b7e490d8..e3e1e53bd 100644 --- a/src/Autopilot/auto_gui.hxx +++ b/src/Autopilot/auto_gui.hxx @@ -25,19 +25,6 @@ #ifndef _AUTO_GUI_HXX #define _AUTO_GUI_HXX -#include - -#include STL_STRING - -#include - -#include -#include -#include - -SG_USING_STD(string); - - // Defines #define AP_CURRENT_HEADING -1 diff --git a/src/Autopilot/newauto.cxx b/src/Autopilot/newauto.cxx index d55309703..78a1dcf29 100644 --- a/src/Autopilot/newauto.cxx +++ b/src/Autopilot/newauto.cxx @@ -30,6 +30,7 @@ #include // sprintf() #include +#include #include #include #include @@ -126,7 +127,7 @@ void FGAutopilot::MakeTargetAltitudeStr( double altitude ) { void FGAutopilot::MakeTargetHeadingStr( double bearing ) { - if( bearing < 0. ) { + if ( bearing < 0. ) { bearing += 360.; } else if (bearing > 360. ) { bearing -= 360.; @@ -273,7 +274,7 @@ void FGAutopilot::init() { TargetHeading = 0.0; // default direction, due north TargetAltitude = 3000; // default altitude in meters - alt_error_accum = 0; + alt_error_accum = 0.0; climb_error_accum = 0.0; MakeTargetAltitudeStr( TargetAltitude ); @@ -306,11 +307,6 @@ void FGAutopilot::init() { update_old_control_values(); - // Initialize GUI components of autopilot - // NewTgtAirportInit(); - // fgAPAdjustInit() ; - // NewHeadingInit(); - // NewAltitudeInit(); }; @@ -328,8 +324,7 @@ void FGAutopilot::reset() { // TargetAltitude = 3000; // default altitude in meters MakeTargetAltitudeStr( TargetAltitude ); - alt_error_accum = 0; - + alt_error_accum = 0.0; climb_error_accum = 0.0; update_old_control_values(); @@ -344,13 +339,10 @@ static double NormalizeDegrees( double Input ) { // normalize the input to the range (-180,180] // Input should not be greater than -360 to 360. // Current rules send the output to an undefined state. - if ( Input > 180 ) - while(Input > 180 ) - Input -= 360; - else if ( Input <= -180 ) - while ( Input <= -180 ) - Input += 360; - return ( Input ); + while ( Input > 180.0 ) { Input -= 360.0; } + while ( Input <= -180.0 ) { Input += 360.0; } + + return Input; }; static double LinearExtrapolate( double x, double x1, double y1, double x2, double y2 ) { @@ -467,8 +459,7 @@ int FGAutopilot::run() { double adjustment = current_radiostack->get_nav1_heading_needle_deflection() * (current_radiostack->get_nav1_loc_dist() * SG_METER_TO_NM); - if ( adjustment < -30.0 ) { adjustment = -30.0; } - if ( adjustment > 30.0 ) { adjustment = 30.0; } + SG_CLAMP_RANGE( adjustment, -30.0, 30.0 ); // determine the target heading to fly to intercept the // tgt_radial @@ -546,8 +537,7 @@ int FGAutopilot::run() { double turn = FGSteam::get_TC_std(); // cout << "turn rate = " << turn << endl; double AileronSet = -turn / 2.0; - if ( AileronSet < -1.0 ) { AileronSet = -1.0; } - if ( AileronSet > 1.0 ) { AileronSet = 1.0; } + SG_CLAMP_RANGE( AileronSet, -1.0, 1.0 ); globals->get_controls()->set_aileron( AileronSet ); globals->get_controls()->set_rudder( AileronSet / 4.0 ); } else { @@ -894,7 +884,7 @@ void FGAutopilot::set_HeadingMode( fgAutoHeadingMode mode ) { void FGAutopilot::set_AltitudeMode( fgAutoAltitudeMode mode ) { altitude_mode = mode; - alt_error_accum = 0; + alt_error_accum = 0.0; if ( altitude_mode == FG_ALTITUDE_LOCK ) { diff --git a/src/FDM/flight.cxx b/src/FDM/flight.cxx index 796842e9b..15404ec27 100644 --- a/src/FDM/flight.cxx +++ b/src/FDM/flight.cxx @@ -47,7 +47,7 @@ // world time, so we introduce cur_fdm_state which is extrapolated by // the difference between sim time and real world time -FGInterface *cur_fdm_state; +FGInterface *cur_fdm_state = 0; FGInterface base_fdm_state; inline void init_vec(FG_VECTOR_3 vec) { diff --git a/src/GUI/gui.cxx b/src/GUI/gui.cxx index 850423e32..3ecbcb6c9 100644 --- a/src/GUI/gui.cxx +++ b/src/GUI/gui.cxx @@ -1034,6 +1034,7 @@ void guiInit() // Set up our Dialog Boxes ConfirmExitDialogInit(); NewAirportInit(); + #ifdef FG_NETWORK_OLK NewNetIdInit(); NewNetFGDInit(); diff --git a/src/GUI/gui.h b/src/GUI/gui.h index 121ed76c3..496c3306c 100644 --- a/src/GUI/gui.h +++ b/src/GUI/gui.h @@ -60,6 +60,7 @@ extern char *gui_msg_CANCEL; // "CANCEL" extern char *gui_msg_RESET; // "RESET" // mouse.cxx +extern void guiInitMouse(int width, int height); extern void guiMotionFunc ( int x, int y ); extern void guiMouseFunc(int button, int updown, int x, int y); extern void maybeToggleMouse( void ); @@ -74,21 +75,24 @@ extern void TurnCursorOff( void ); // These will also repair any damage done to the Panel if active // Activate Dialog Box -#define FG_PUSH_PUI_DIALOG( X ) \ - maybeToggleMouse(); \ - puPushLiveInterface( (X) ) ; \ - ( X )->reveal() +inline void FG_PUSH_PUI_DIALOG( puObject *X ) { + maybeToggleMouse(); + puPushLiveInterface( (puInterface *)X ) ; + X->reveal() ; +} // Deactivate Dialog Box -#define FG_POP_PUI_DIALOG( X ) \ - (X)->hide(); \ - puPopLiveInterface(); \ +inline void FG_POP_PUI_DIALOG( puObject *X ) { + X->hide(); + puPopLiveInterface(); maybeToggleMouse(); +} // Finalize Dialog Box Construction -#define FG_FINALIZE_PUI_DIALOG( X ) \ - ( X )->close(); \ - ( X )->hide(); \ +inline void FG_FINALIZE_PUI_DIALOG( puObject *X ) { + ((puGroup *)X)->close(); + X->hide(); puPopLiveInterface(); +} #endif // _GUI_H_ diff --git a/src/GUI/mouse.cxx b/src/GUI/mouse.cxx index 9cf80a794..1c6a49476 100644 --- a/src/GUI/mouse.cxx +++ b/src/GUI/mouse.cxx @@ -96,13 +96,16 @@ static int mouse_joystick_control = 0; // on second left click in MOUSE_VIEW mode // This has file scope so that it can be reset // if the little rodent is moved NHV -static int _mVtoggle; +static int _mVtoggle = 0; // we break up the glutGetModifiers return mask // once per loop and stash what we need in these -static int glut_active_shift; -static int glut_active_ctrl; -static int glut_active_alt; +static int glut_active_shift = 0; +static int glut_active_ctrl = 0; +static int glut_active_alt = 0; + +static int MOUSE_XSIZE = 0; +static int MOUSE_YSIZE = 0; // uncomment this for view to exactly follow mouse in MOUSE_VIEW mode // else smooth out the view panning to .01 radian per frame @@ -141,6 +144,12 @@ static double throttle_sensitivity = 1.0/250.0; static double rudder_sensitivity = 1.0/500.0; static double trim_sensitivity = 1.0/1000.0; +void guiInitMouse(int width, int height) +{ + MOUSE_XSIZE = width; + MOUSE_YSIZE = height; +} + static inline int guiGetMouseButton(void) { return last_buttons; @@ -164,6 +173,64 @@ static inline int right_button( void ) { return( last_buttons & (1 << GLUT_RIGHT_BUTTON) ); } +static inline void set_goal_view_offset( float offset ) +{ + globals->get_current_view()->set_goal_view_offset(offset); +} + +static inline void set_view_offset( float offset ) +{ + globals->get_current_view()->set_view_offset(offset); +} + +static inline float get_view_offset() { + return globals->get_current_view()->get_view_offset(); +} + +static inline float get_goal_view_offset() { + return globals->get_current_view()->get_goal_view_offset(); +} + +static inline void move_brake(float offset) { + globals->get_controls()->move_brake(FGControls::ALL_WHEELS, offset); +} + +static inline void move_throttle(float offset) { + globals->get_controls()->move_throttle(FGControls::ALL_ENGINES, offset); +} + +static inline void move_rudder(float offset) { + globals->get_controls()->move_rudder(offset); +} + +static inline void move_elevator_trim(float offset) { + globals->get_controls()->move_elevator_trim(offset); +} + +static inline void move_aileron(float offset) { + globals->get_controls()->move_aileron(offset); +} + +static inline void move_elevator(float offset) { + globals->get_controls()->move_elevator(offset); +} + +static inline float get_aileron() { + return globals->get_controls()->get_aileron(); +} + +static inline float get_elevator() { + return globals->get_controls()->get_elevator(); +} + +static inline bool AP_HeadingEnabled() { + return current_autopilot->get_HeadingEnabled(); +} + +static inline bool AP_AltitudeEnabled() { + return current_autopilot->get_AltitudeEnabled(); +} + void TurnCursorOn( void ) { mouse_active = ~0; @@ -181,8 +248,8 @@ void TurnCursorOn( void ) } #endif #if defined(X_CURSOR_TWEAKS) - glutWarpPointer( fgGetInt("/sim/startup/xsize")/2, - fgGetInt("/sim/startup/ysize")/2); + glutWarpPointer( MOUSE_XSIZE/2, + MOUSE_YSIZE/2); #endif } @@ -192,8 +259,8 @@ void TurnCursorOff( void ) #if defined(WIN32_CURSOR_TWEAKS) glutSetCursor(GLUT_CURSOR_NONE); #elif defined(X_CURSOR_TWEAKS) - glutWarpPointer( fgGetInt("/sim/startup/xsize"), - fgGetInt("/sim/startup/ysize")); + glutWarpPointer( MOUSE_XSIZE, + MOUSE_YSIZE); #endif } @@ -242,8 +309,8 @@ void BusyCursor( int restore ) void CenterView( void ) { if( mouse_mode == MOUSE_VIEW ) { mouse_mode = MOUSE_POINTER; - _savedX = fgGetInt("/sim/startup/xsize")/2; - _savedY = fgGetInt("/sim/startup/ysize")/2; + _savedX = MOUSE_XSIZE/2; + _savedY = MOUSE_YSIZE/2; _mVtoggle = 0; Quat0(); build_rotmatrix(GuiQuat_mat, curGuiQuat); @@ -254,32 +321,58 @@ void CenterView( void ) { glutWarpPointer( _savedX, _savedY ); } - globals->get_current_view()->set_goal_view_offset(0.0); - globals->get_current_view()->set_view_offset(0.0); + set_goal_view_offset(0.0); + set_view_offset(0.0); } +//#define TRANSLATE_HUD +// temporary hack until pitch_offset is added to view pipeline +void fgTranslateHud( void ) { +#ifdef TRANSLATE_HUD + if(mouse_mode == MOUSE_VIEW) { + + int ww = MOUSE_XSIZE; + int wh = MOUSE_YSIZE; + + float y = 4*(_mY-(wh/2));// * ((wh/SGD_PI)*SG_RADIANS_TO_DEGREES); + + float x = get_view_offset() * SG_RADIANS_TO_DEGREES; + + if( x < -180 ) x += 360; + else if( x > 180 ) x -= 360; + + x *= ww/90.0; + // x *= ww/180.0; + // x *= ww/360.0; + + // glTranslatef( x*ww/640, y*wh/480, 0 ); + glTranslatef( x*640/ww, y*480/wh, 0 ); + } +#endif // TRANSLATE_HUD +} + void guiMotionFunc ( int x, int y ) { int ww, wh, need_warp = 0; float W, H; double offset; - ww = fgGetInt("/sim/startup/xsize"); - wh = fgGetInt("/sim/startup/ysize"); + ww = MOUSE_XSIZE; + wh = MOUSE_YSIZE; if (mouse_mode == MOUSE_POINTER) { // TURN MENU ON IF MOUSE AT TOP - if( y == 0 ) { + if( y < 1 ) { if( !gui_menu_on ) guiToggleMenu(); } // TURN MENU OFF IF MOUSE AT BOTTOM - else if( y > wh-1 ) { + else if( y > wh-2 ) { if( gui_menu_on ) guiToggleMenu(); } - puMouse ( x, y ) ; + // puMouse ( x, y ) ; glutPostRedisplay () ; } else { if( x == _mX && y == _mY) @@ -295,27 +388,21 @@ void guiMotionFunc ( int x, int y ) fgSetString("/sim/control-mode", "mouse"); } else { if ( left_button() ) { - offset = (_mX - x) * brake_sensitivity; - globals->get_controls()->move_brake(FGControls::ALL_WHEELS, offset); - offset = (_mY - y) * throttle_sensitivity; - globals->get_controls()->move_throttle(FGControls::ALL_ENGINES, offset); + move_brake( (_mX - x) * brake_sensitivity); + move_throttle((_mY - y) * throttle_sensitivity); } else if ( right_button() ) { - if( ! current_autopilot->get_HeadingEnabled() ) { - offset = (x - _mX) * rudder_sensitivity; - globals->get_controls()->move_rudder(offset); + if( ! AP_HeadingEnabled() ) { + move_rudder((x - _mX) * rudder_sensitivity); } - if( ! current_autopilot->get_AltitudeEnabled() ) { - offset = (_mY - y) * trim_sensitivity; - globals->get_controls()->move_elevator_trim(offset); + if( ! AP_AltitudeEnabled() ) { + move_elevator_trim((_mY - y) * trim_sensitivity); } } else { - if( ! current_autopilot->get_HeadingEnabled() ) { - offset = (x - _mX) * aileron_sensitivity; - globals->get_controls()->move_aileron(offset); + if( ! AP_HeadingEnabled() ) { + move_aileron((x - _mX) * aileron_sensitivity); } - if( ! current_autopilot->get_AltitudeEnabled() ) { - offset = (_mY - y) * elevator_sensitivity; - globals->get_controls()->move_elevator(offset); + if( ! AP_AltitudeEnabled() ) { + move_elevator((_mY - y) * elevator_sensitivity); } } } @@ -380,7 +467,7 @@ void guiMotionFunc ( int x, int y ) // do horizontal pan // this could be done in above quat // but requires redoing view pipeline - offset = globals->get_current_view()->get_goal_view_offset(); + offset = get_goal_view_offset(); offset += ((_mX - x) * SGD_2PI / W ); while (offset < 0.0) { offset += SGD_2PI; @@ -388,9 +475,9 @@ void guiMotionFunc ( int x, int y ) while (offset > SGD_2PI) { offset -= SGD_2PI; } - globals->get_current_view()->set_goal_view_offset(offset); + set_goal_view_offset(offset); #ifdef NO_SMOOTH_MOUSE_VIEW - globals->get_current_view()->set_view_offset(offset); + set_view_offset(offset); #endif break; @@ -443,13 +530,10 @@ void guiMouseFunc(int button, int updown, int x, int y) _mY = _mVy; x = _Vx; y = _Vy; - curGuiQuat[0] = _quat[0]; - curGuiQuat[1] = _quat[1]; - curGuiQuat[2] = _quat[2]; - curGuiQuat[3] = _quat[3]; - globals->get_current_view()->set_goal_view_offset(_view_offset); + sgCopyVec4(curGuiQuat, _quat); + set_goal_view_offset(_view_offset); #ifdef NO_SMOOTH_MOUSE_VIEW - globals->get_current_view()->set_view_offset(_view_offset); + set_view_offset(_view_offset); #endif } else { // center view @@ -457,18 +541,14 @@ void guiMouseFunc(int button, int updown, int x, int y) _mVy = _mY; _Vx = x; _Vy = y; - _quat[0] = curGuiQuat[0]; - _quat[1] = curGuiQuat[1]; - _quat[2] = curGuiQuat[2]; - _quat[3] = curGuiQuat[3]; - x = fgGetInt("/sim/startup/xsize")/2; - y = fgGetInt("/sim/startup/ysize")/2; + sgCopyVec4(_quat,curGuiQuat); + x = MOUSE_XSIZE/2; + y = MOUSE_YSIZE/2; Quat0(); - _view_offset = - globals->get_current_view()->get_goal_view_offset(); - globals->get_current_view()->set_goal_view_offset(0.0); + _view_offset = get_goal_view_offset(); + set_goal_view_offset(0.0); #ifdef NO_SMOOTH_MOUSE_VIEW - globals->get_current_view()->set_view_offset(0.0); + set_view_offset(0.0); #endif } glutWarpPointer( x , y); @@ -476,50 +556,57 @@ void guiMouseFunc(int button, int updown, int x, int y) _mVtoggle = ~_mVtoggle; break; } - }else if ( button == GLUT_RIGHT_BUTTON) { + } else if ( button == GLUT_RIGHT_BUTTON) { switch (mouse_mode) { + case MOUSE_POINTER: + SG_LOG( SG_INPUT, SG_INFO, "Mouse in yoke mode" ); + mouse_mode = MOUSE_YOKE; mouse_joystick_control = 0; _savedX = x; _savedY = y; // start with zero point in center of screen - _mX = fgGetInt("/sim/startup/xsize")/2; - _mY = fgGetInt("/sim/startup/ysize")/2; + _mX = MOUSE_XSIZE/2; + _mY = MOUSE_YSIZE/2; // try to have the MOUSE_YOKE position // reflect the current stick position - offset = globals->get_controls()->get_aileron(); - x = _mX - (int)(offset * aileron_sensitivity); - offset = globals->get_controls()->get_elevator(); - y = _mY - (int)(offset * elevator_sensitivity); + x = _mX - (int)(get_aileron() * aileron_sensitivity); + y = _mY - (int)(get_elevator() * elevator_sensitivity); glutSetCursor(GLUT_CURSOR_CROSSHAIR); - SG_LOG( SG_INPUT, SG_INFO, "Mouse in yoke mode" ); break; case MOUSE_YOKE: + SG_LOG( SG_INPUT, SG_INFO, "Mouse in view mode" ); + mouse_mode = MOUSE_VIEW; fgSetString("/sim/control-mode", "joystick"); - x = fgGetInt("/sim/startup/xsize")/2; - y = fgGetInt("/sim/startup/ysize")/2; + + // recenter cursor and reset + x = MOUSE_XSIZE/2; + y = MOUSE_YSIZE/2; _mVtoggle = 0; +// #ifndef RESET_VIEW_ON_LEAVING_MOUSE_VIEW Quat0(); build_rotmatrix(GuiQuat_mat, curGuiQuat); +// #endif glutSetCursor(GLUT_CURSOR_LEFT_RIGHT); - SG_LOG( SG_INPUT, SG_INFO, "Mouse in view mode" ); break; case MOUSE_VIEW: + SG_LOG( SG_INPUT, SG_INFO, "Mouse in pointer mode" ); + mouse_mode = MOUSE_POINTER; x = _savedX; y = _savedY; #ifdef RESET_VIEW_ON_LEAVING_MOUSE_VIEW Quat0(); build_rotmatrix(GuiQuat_mat, curGuiQuat); - globals->get_current_view()->set_goal_view_offset(0.0); + set_goal_view_offset(0.0); #ifdef NO_SMOOTH_MOUSE_VIEW - globals->get_current_view()->set_view_offset(0.0); + set_view_offset(0.0); #endif // NO_SMOOTH_MOUSE_VIEW #endif // RESET_VIEW_ON_LEAVING_MOUSE_VIEW glutSetCursor(GLUT_CURSOR_INHERIT); @@ -528,8 +615,6 @@ void guiMouseFunc(int button, int updown, int x, int y) if(!gui_menu_on) TurnCursorOff(); #endif // WIN32_CURSOR_TWEAKS_OFF - - SG_LOG( SG_INPUT, SG_INFO, "Mouse in pointer mode" ); break; } // end switch (mouse_mode) glutWarpPointer( x, y ); diff --git a/src/GUI/sgVec3Slider.cxx b/src/GUI/sgVec3Slider.cxx index df752b42b..412237281 100644 --- a/src/GUI/sgVec3Slider.cxx +++ b/src/GUI/sgVec3Slider.cxx @@ -286,7 +286,8 @@ sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 vec, const char *title, dialer_x = dialer_x + 170; /* pitch */ - HS1 = new FloatDial ( dialer_x, dialer_y, dialer_size, vec[1], Ytitle, 89.99f, -89.99f ); + // HS1 = new FloatDial ( dialer_x, dialer_y, dialer_size, vec[1], Ytitle, 89.99f, -89.99f ); + HS1 = new FloatDial ( dialer_x, dialer_y, dialer_size, vec[1], Ytitle, 179.99f, -179.99f ); /* radius */ HS2 = new FloatSlider ( slider_x, slider_y, slider_width, vec[2], Ztitle, 100.0f, 0.0f ); diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 56c4d9592..c0922a598 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -353,71 +353,71 @@ bool fgSetPosFromAirportIDandHdg( const string& id, double tgt_hdg ) { double found_dir = 0.0; if ( id.length() ) { - // set initial position from runway and heading - - SGPath path( globals->get_fg_root() ); - path.append( "Airports" ); - path.append( "runways.mk4" ); - FGRunways runways( path.c_str() ); - - SG_LOG( SG_GENERAL, SG_INFO, - "Attempting to set starting position from runway code " - << id << " heading " << tgt_hdg ); - - // SGPath inpath( globals->get_fg_root() ); - // inpath.append( "Airports" ); - // inpath.append( "apt_simple" ); - // airports.load( inpath.c_str() ); - - // SGPath outpath( globals->get_fg_root() ); - // outpath.append( "Airports" ); - // outpath.append( "simple.gdbm" ); - // airports.dump_gdbm( outpath.c_str() ); - - if ( ! runways.search( id, &r ) ) { - SG_LOG( SG_GENERAL, SG_ALERT, - "Failed to find " << id << " in database." ); - return false; - } - - double diff; - double min_diff = 360.0; - - while ( r.id == id ) { - // forward direction - diff = tgt_hdg - r.heading; - while ( diff < -180.0 ) { diff += 360.0; } - while ( diff > 180.0 ) { diff -= 360.0; } - diff = fabs(diff); - SG_LOG( SG_GENERAL, SG_INFO, - "Runway " << r.rwy_no << " heading = " << r.heading << - " diff = " << diff ); - if ( diff < min_diff ) { - min_diff = diff; - found_r = r; - found_dir = 0; - } - - // reverse direction - diff = tgt_hdg - r.heading - 180.0; - while ( diff < -180.0 ) { diff += 360.0; } - while ( diff > 180.0 ) { diff -= 360.0; } - diff = fabs(diff); - SG_LOG( SG_GENERAL, SG_INFO, - "Runway -" << r.rwy_no << " heading = " << - r.heading + 180.0 << - " diff = " << diff ); - if ( diff < min_diff ) { - min_diff = diff; - found_r = r; - found_dir = 180.0; - } - - runways.next( &r ); - } - - SG_LOG( SG_GENERAL, SG_INFO, "closest runway = " << found_r.rwy_no - << " + " << found_dir ); + // set initial position from runway and heading + + SGPath path( globals->get_fg_root() ); + path.append( "Airports" ); + path.append( "runways.mk4" ); + FGRunways runways( path.c_str() ); + + SG_LOG( SG_GENERAL, SG_INFO, + "Attempting to set starting position from runway code " + << id << " heading " << tgt_hdg ); + + // SGPath inpath( globals->get_fg_root() ); + // inpath.append( "Airports" ); + // inpath.append( "apt_simple" ); + // airports.load( inpath.c_str() ); + + // SGPath outpath( globals->get_fg_root() ); + // outpath.append( "Airports" ); + // outpath.append( "simple.gdbm" ); + // airports.dump_gdbm( outpath.c_str() ); + + if ( ! runways.search( id, &r ) ) { + SG_LOG( SG_GENERAL, SG_ALERT, + "Failed to find " << id << " in database." ); + return false; + } + + double diff; + double min_diff = 360.0; + + while ( r.id == id ) { + // forward direction + diff = tgt_hdg - r.heading; + while ( diff < -180.0 ) { diff += 360.0; } + while ( diff > 180.0 ) { diff -= 360.0; } + diff = fabs(diff); + SG_LOG( SG_GENERAL, SG_INFO, + "Runway " << r.rwy_no << " heading = " << r.heading << + " diff = " << diff ); + if ( diff < min_diff ) { + min_diff = diff; + found_r = r; + found_dir = 0; + } + + // reverse direction + diff = tgt_hdg - r.heading - 180.0; + while ( diff < -180.0 ) { diff += 360.0; } + while ( diff > 180.0 ) { diff -= 360.0; } + diff = fabs(diff); + SG_LOG( SG_GENERAL, SG_INFO, + "Runway -" << r.rwy_no << " heading = " << + r.heading + 180.0 << + " diff = " << diff ); + if ( diff < min_diff ) { + min_diff = diff; + found_r = r; + found_dir = 180.0; + } + + runways.next( &r ); + } + + SG_LOG( SG_GENERAL, SG_INFO, "closest runway = " << found_r.rwy_no + << " + " << found_dir ); } else { return false; @@ -452,6 +452,7 @@ bool fgSetPosFromAirportIDandHdg( const string& id, double tgt_hdg ) { lat2=olat; lon2=olon; } + fgSetDouble("/position/longitude-deg", lon2 ); fgSetDouble("/position/latitude-deg", lat2 ); fgSetDouble("/orientation/heading-deg", heading ); @@ -506,6 +507,82 @@ bool fgInitGeneral( void ) { } +// Initialize the flight model subsystem. This just creates the +// object. The actual fdm initialization is delayed until we get a +// proper scenery elevation hit. This is checked for in main.cxx + +void fgInitFDM() { + + if ( cur_fdm_state ) { + delete cur_fdm_state; + cur_fdm_state = 0; + } + + double dt = 1.0 / fgGetInt("/sim/model-hz"); + aircraft_dir = fgGetString("/sim/aircraft-dir"); + const string &model = fgGetString("/sim/flight-model"); + + try { + if (model == "larcsim") { + cur_fdm_state = new FGLaRCsim( dt ); + } else if (model == "jsb") { + cur_fdm_state = new FGJSBsim( dt ); + } else if (model == "ada") { + cur_fdm_state = new FGADA( dt ); + } else if (model == "balloon") { + cur_fdm_state = new FGBalloonSim( dt ); + } else if (model == "magic") { + cur_fdm_state = new FGMagicCarpet( dt ); + } else if (model == "external") { + cur_fdm_state = new FGExternal( dt ); + } else if (model == "null") { + cur_fdm_state = new FGNullFDM( dt ); + } else if (model == "yasim") { + cur_fdm_state = new YASim( dt ); + } else { + SG_LOG(SG_GENERAL, SG_ALERT, + "Unrecognized flight model '" << model + << "', cannot init flight dynamics model."); + exit(-1); + } + } catch ( ... ) { + SG_LOG(SG_GENERAL, SG_ALERT, "FlightGear aborting\n\n"); + exit(-1); + } +} + + +// Initialize view parameters +void fgInitView() { + // Initialize pilot view + static const SGPropertyNode *longitude + = fgGetNode("/position/longitude-deg"); + static const SGPropertyNode *latitude + = fgGetNode("/position/latitude-deg"); + static const SGPropertyNode *altitude + = fgGetNode("/position/altitude-ft"); + + FGViewerRPH *pilot_view + = (FGViewerRPH *)globals->get_viewmgr()->get_view( 0 ); + + pilot_view->set_geod_view_pos( longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + altitude->getDoubleValue() + * SG_FEET_TO_METER ); + pilot_view->set_rph( cur_fdm_state->get_Phi(), + cur_fdm_state->get_Theta(), + cur_fdm_state->get_Psi() ); + + // set current view to 0 (first) which is our main pilot view + globals->set_current_view( pilot_view ); + + SG_LOG( SG_GENERAL, SG_DEBUG, " abs_view_pos = " + << globals->get_current_view()->get_abs_view_pos()); +} + + // This is the top level init routine which calls all the other // initialization routines. If you are adding a subsystem to flight // gear, its initialization call should located in this routine. @@ -530,8 +607,7 @@ bool fgInitSubsystems( void ) { SGPath mpath( globals->get_fg_root() ); mpath.append( "materials.xml" ); - if ( material_lib.load( mpath.str() ) ) { - } else { + if ( ! material_lib.load( mpath.str() ) ) { SG_LOG( SG_GENERAL, SG_ALERT, "Error loading material lib!" ); exit(-1); } @@ -562,44 +638,8 @@ bool fgInitSubsystems( void ) { // Initialize the flight model subsystem. //////////////////////////////////////////////////////////////////// - double dt = 1.0 / fgGetInt("/sim/model-hz"); - // cout << "dt = " << dt << endl; - - aircraft_dir = fgGetString("/sim/aircraft-dir"); - const string &model = fgGetString("/sim/flight-model"); - try { - if (model == "larcsim") { - cur_fdm_state = new FGLaRCsim( dt ); - } else if (model == "jsb") { - cur_fdm_state = new FGJSBsim( dt ); - } else if (model == "ada") { - cur_fdm_state = new FGADA( dt ); - } else if (model == "balloon") { - cur_fdm_state = new FGBalloonSim( dt ); - } else if (model == "magic") { - cur_fdm_state = new FGMagicCarpet( dt ); - } else if (model == "external") { - cur_fdm_state = new FGExternal( dt ); - } else if (model == "null") { - cur_fdm_state = new FGNullFDM( dt ); - } else if (model == "yasim") { - cur_fdm_state = new YASim( dt ); - } else { - SG_LOG(SG_GENERAL, SG_ALERT, - "Unrecognized flight model '" << model - << "', cannot init flight dynamics model."); - exit(-1); - } - } catch ( ... ) { - SG_LOG(SG_GENERAL, SG_ALERT, "FlightGear aborting\n\n"); - exit(-1); - } - - // Actual fdm initialization is delayed until we get a proper - // scenery elevation hit. This is checked for in main.cxx - // cur_fdm_state->init(); - // cur_fdm_state->bind(); - + fgInitFDM(); + // allocates structures so must happen before any of the flight // model or control parameters are set fgAircraftInit(); // In the future this might not be the case. @@ -622,34 +662,7 @@ bool fgInitSubsystems( void ) { // Initialize the view manager subsystem. //////////////////////////////////////////////////////////////////// -#if 0 /* As this wrongly does an integer division and gets x and y the wrong way around, I guess it's not needed. JAF */ - // Initialize win_ratio parameters - for ( int i = 0; i < globals->get_viewmgr()->size(); ++i ) { - globals->get_viewmgr()->get_view(i)-> - set_win_ratio( fgGetInt("/sim/startup/xsize") / - fgGetInt("/sim/startup/ysize") ); - } -#endif - - // Initialize pilot view - FGViewerRPH *pilot_view = - (FGViewerRPH *)globals->get_viewmgr()->get_view( 0 ); - - pilot_view->set_geod_view_pos( longitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS, - latitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS, - altitude->getDoubleValue() - * SG_FEET_TO_METER ); - pilot_view->set_rph( cur_fdm_state->get_Phi(), - cur_fdm_state->get_Theta(), - cur_fdm_state->get_Psi() ); - - // set current view to 0 (first) which is our main pilot view - globals->set_current_view( pilot_view ); - - SG_LOG( SG_GENERAL, SG_DEBUG, " abs_view_pos = " - << globals->get_current_view()->get_abs_view_pos()); + fgInitView(); //////////////////////////////////////////////////////////////////// @@ -786,6 +799,7 @@ bool fgInitSubsystems( void ) { fgInitCommands(); +#ifdef ENABLE_AUDIO_SUPPORT //////////////////////////////////////////////////////////////////// // Initialize the sound subsystem. //////////////////////////////////////////////////////////////////// @@ -802,6 +816,7 @@ bool fgInitSubsystems( void ) { globals->get_fx()->init(); globals->get_fx()->bind(); +#endif //////////////////////////////////////////////////////////////////// // Initialize the radio stack subsystem. @@ -843,12 +858,11 @@ bool fgInitSubsystems( void ) { current_autopilot->init(); // initialize the gui parts of the autopilot + fgAPAdjustInit(); NewTgtAirportInit(); - fgAPAdjustInit() ; NewHeadingInit(); NewAltitudeInit(); - //////////////////////////////////////////////////////////////////// // Initialize I/O subsystem. //////////////////////////////////////////////////////////////////// @@ -930,71 +944,20 @@ void fgReInitSubsystems( void ) // Initialize the Scenery Management subsystem scenery.init(); - // if( global_tile_mgr.init() ) { - // Load the local scenery data +#if 0 + if( global_tile_mgr.init() ) { + Load the local scenery data global_tile_mgr.update( longitude->getDoubleValue(), latitude->getDoubleValue() ); - // } else { - // SG_LOG( SG_GENERAL, SG_ALERT, "Error in Tile Manager initialization!" ); - // exit(-1); - // } - - // Delete then Initialize the flight model subsystem. - delete cur_fdm_state; - - double dt = 1.0 / fgGetInt("/sim/model-hz"); - aircraft_dir = fgGetString("/sim/aircraft-dir"); - const string &model = fgGetString("/sim/flight-model"); - try { - if (model == "larcsim") { - cur_fdm_state = new FGLaRCsim( dt ); - } else if (model == "jsb") { - cur_fdm_state = new FGJSBsim( dt ); - } else if (model == "ada") { - cur_fdm_state = new FGADA( dt ); - } else if (model == "balloon") { - cur_fdm_state = new FGBalloonSim( dt ); - } else if (model == "magic") { - cur_fdm_state = new FGMagicCarpet( dt ); - } else if (model == "external") { - cur_fdm_state = new FGExternal( dt ); - } else if (model == "null") { - cur_fdm_state = new FGNullFDM( dt ); - } else if (model == "yasim") { - cur_fdm_state = new YASim( dt ); - } else { - SG_LOG(SG_GENERAL, SG_ALERT, - "Unrecognized flight model '" << model - << "', cannot init flight dynamics model."); - exit(-1); - } - } catch ( ... ) { - SG_LOG(SG_GENERAL, SG_ALERT, "FlightGear aborting\n\n"); - exit(-1); + } else { + SG_LOG( SG_GENERAL, SG_ALERT, "Error in Tile Manager initialization!" ); + exit(-1); } +#endif - // Initialize view parameters - FGViewerRPH *pilot_view = - (FGViewerRPH *)globals->get_viewmgr()->get_view( 0 ); - - pilot_view->set_view_offset( 0.0 ); - pilot_view->set_goal_view_offset( 0.0 ); - - pilot_view->set_geod_view_pos( longitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS, - latitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS, - cur_fdm_state->get_Altitude() - * SG_FEET_TO_METER ); - pilot_view->set_rph( cur_fdm_state->get_Phi(), - cur_fdm_state->get_Theta(), - cur_fdm_state->get_Psi() ); - - // set current view to 0 (first) which is our main pilot view - globals->set_current_view( pilot_view ); + fgInitFDM(); - SG_LOG( SG_GENERAL, SG_DEBUG, " abs_view_pos = " - << globals->get_current_view()->get_abs_view_pos()); + fgInitView(); globals->get_controls()->reset_all(); current_autopilot->reset(); diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 291fa049c..c935e4da2 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -114,6 +114,7 @@ #include #include #include + // Should already be inlcluded by gl.h if needed by your platform so // we shouldn't include this here. // #include @@ -203,7 +204,7 @@ sgMat4 copy_of_ssgOpenGLAxisSwapMatrix = { 0.0f, 0.0f, -1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 1.0f } -} ; +}; // The following defines flightgear options. Because glutlib will also // want to parse its own options, those options must not be included here @@ -259,20 +260,20 @@ void fgBuildRenderStates( void ) { // fgFindNode -- a function that finds a named node in an ssg graph ssgEntity *fgFindNode( ssgEntity *node, const char *name ) { - if ( node->getName() != NULL && strcmp( name, node->getName() ) == 0 ) { - return node; - } else if ( node->isAKindOf( ssgTypeBranch() ) ) { - ssgEntity *kid = ((ssgBranch*)node)->getKid(0); - while (kid != NULL) { - ssgEntity *n = fgFindNode(kid, name); - if (n != NULL) - return n; - - kid = ((ssgBranch*)node)->getNextKid(); + if ( node->getName() != NULL && strcmp( name, node->getName() ) == 0 ) { + return node; + } else if ( node->isAKindOf(ssgTypeBranch()) ) { + ssgEntity *kid = ((ssgBranch*)node)->getKid(0); + while ( kid != NULL ) { + ssgEntity *n = fgFindNode(kid, name); + if ( n != NULL ) { + return n; + } + kid = ((ssgBranch*)node)->getNextKid(); + } } - } - return NULL; + return NULL; } // fgInitVisuals() -- Initialize various GL/view parameters @@ -951,7 +952,7 @@ void fgUpdateTimeDepCalcs() { // run Autopilot system current_autopilot->run(); - // update autopilot + // update FDM cur_fdm_state->update( 1 ); } FGSteam::update( multi_loop * fgGetInt("/sim/speed-up") ); @@ -1308,6 +1309,7 @@ void fgReshape( int width, int height ) { fgSetInt("/sim/startup/xsize", width); fgSetInt("/sim/startup/ysize", height); + guiInitMouse(width, height); ssgSetFOV( globals->get_current_view()->get_h_fov(), globals->get_current_view()->get_v_fov() ); @@ -1400,7 +1402,7 @@ int fgGlutInitEvents( void ) { // draw the scene glutDisplayFunc( fgRenderFrame ); - return(1); + return 1; } @@ -1544,7 +1546,7 @@ int mainLoop( int argc, char **argv ) { int offset = fgGetInt("/sim/startup/time-offset"); const string &offset_type = fgGetString("/sim/startup/time-offset-type"); if (offset_type == "system-offset") { - globals->set_warp( offset ); + globals->set_warp( offset ); } else if (offset_type == "gmt-offset") { globals->set_warp( offset - (currGMT - systemLocalTime) ); } else if (offset_type == "latitude-offset") { diff --git a/src/Network/atc610x.hxx b/src/Network/atc610x.hxx index 085092afc..0b68462a1 100644 --- a/src/Network/atc610x.hxx +++ b/src/Network/atc610x.hxx @@ -86,9 +86,9 @@ class FGATC610x : public FGProtocol { public: - inline FGATC610x() { } + FGATC610x() { } - inline ~FGATC610x() { } + ~FGATC610x() { } bool open(); diff --git a/src/Scenery/hitlist.cxx b/src/Scenery/hitlist.cxx index 3db38628c..c52848ad3 100644 --- a/src/Scenery/hitlist.cxx +++ b/src/Scenery/hitlist.cxx @@ -12,6 +12,8 @@ #include #include +#include + #include #include #include @@ -27,7 +29,7 @@ extern ssgBranch *terrain; - +#if 0 // check to see if the intersection point is // actually inside this face static bool pointInTriangle( sgdVec3 point, sgdVec3 tri[3] ) @@ -167,6 +169,121 @@ static void sgdXformPnt3 ( sgdVec3 dst, const sgVec3 src, const sgdMat4 mat ) t2 * mat[ 2 ][ 2 ] + mat[ 3 ][ 2 ] ) ; } +#endif // 0 + + +/* + Find the intersection of an infinite line with a plane + (the line being defined by a point and direction). + + Norman Vine -- nhv@yahoo.com (with hacks by Steve) +*/ + +int sgdIsectInfLinePlane( sgdVec3 dst, sgdVec3 l_org, + sgdVec3 l_vec, sgdVec4 plane ) +{ + SGDfloat tmp = sgdScalarProductVec3 ( l_vec, plane ) ; + + /* Is line parallel to plane? */ + + if ( sgdAbs ( tmp ) < DBL_EPSILON ) + return FALSE ; + + sgdScaleVec3 ( dst, l_vec, -( sgdScalarProductVec3 ( l_org, plane ) + + plane[3] ) / tmp ) ; + sgdAddVec3 ( dst, l_org ) ; + + return TRUE ; +} + + +/* + * Given a point and a triangle lying on the same plane + * check to see if the point is inside the triangle + */ +bool sgdPointInTriangle( sgdVec3 point, sgdVec3 tri[3] ) +{ + sgdVec3 dif; + + int i; + for( i=0; i<3; i++ ) { + SGDfloat min, max; + SG_MIN_MAX3 ( min, max, tri[0][i], tri[1][i], tri[2][i] ); + // punt if outside bouding cube + if( (point[i] < min) || (point[i] > max) ) + return false; + dif[i] = max - min; + } + + // drop the smallest dimension so we only have to work in 2d. + SGDfloat min_dim = SG_MIN3 (dif[0], dif[1], dif[2]); + SGDfloat x1, y1, x2, y2, x3, y3, rx, ry; + if ( fabs(min_dim-dif[0]) <= DBL_EPSILON ) { + // x is the smallest dimension + x1 = point[1]; + y1 = point[2]; + x2 = tri[0][1]; + y2 = tri[0][2]; + x3 = tri[1][1]; + y3 = tri[1][2]; + rx = tri[2][1]; + ry = tri[2][2]; + } else if ( fabs(min_dim-dif[1]) <= DBL_EPSILON ) { + // y is the smallest dimension + x1 = point[0]; + y1 = point[2]; + x2 = tri[0][0]; + y2 = tri[0][2]; + x3 = tri[1][0]; + y3 = tri[1][2]; + rx = tri[2][0]; + ry = tri[2][2]; + } else if ( fabs(min_dim-dif[2]) <= DBL_EPSILON ) { + // z is the smallest dimension + x1 = point[0]; + y1 = point[1]; + x2 = tri[0][0]; + y2 = tri[0][1]; + x3 = tri[1][0]; + y3 = tri[1][1]; + rx = tri[2][0]; + ry = tri[2][1]; + } else { + // all dimensions are really small so lets call it close + // enough and return a successful match + return true; + } + + // check if intersection point is on the same side of p1 <-> p2 as p3 + SGDfloat tmp = (y2 - y3) / (x2 - x3); + int side1 = SG_SIGN (tmp * (rx - x3) + y3 - ry); + int side2 = SG_SIGN (tmp * (x1 - x3) + y3 - y1); + if ( side1 != side2 ) { + // printf("failed side 1 check\n"); + return false; + } + + // check if intersection point is on correct side of p2 <-> p3 as p1 + tmp = (y3 - ry) / (x3 - rx); + side1 = SG_SIGN (tmp * (x2 - rx) + ry - y2); + side2 = SG_SIGN (tmp * (x1 - rx) + ry - y1); + if ( side1 != side2 ) { + // printf("failed side 2 check\n"); + return false; + } + + // check if intersection point is on correct side of p1 <-> p3 as p2 + tmp = (y2 - ry) / (x2 - rx); + side1 = SG_SIGN (tmp * (x3 - rx) + ry - y3); + side2 = SG_SIGN (tmp * (x1 - rx) + ry - y1); + if ( side1 != side2 ) { + // printf("failed side 3 check\n"); + return false; + } + + return true; +} + /* Find the intersection of an infinite line with a leaf @@ -187,18 +304,18 @@ static void sgdXformPnt3 ( sgdVec3 dst, const sgVec3 src, const sgdMat4 mat ) false otherwise */ int FGHitList::IntersectLeaf( ssgLeaf *leaf, sgdMat4 m, - sgdVec3 orig, sgdVec3 dir ) + sgdVec3 orig, sgdVec3 dir ) { int num_hits = 0; for ( int i = 0; i < leaf->getNumTriangles(); ++i ) { short i1, i2, i3; leaf->getTriangle( i, &i1, &i2, &i3 ); - sgdVec3 tri[3]; - sgdXformPnt3( tri[0], leaf->getVertex( i1 ), m ); - sgdXformPnt3( tri[1], leaf->getVertex( i2 ), m ); - sgdXformPnt3( tri[2], leaf->getVertex( i3 ), m ); - + sgdVec3 tri[3]; + sgdSetVec3( tri[0], leaf->getVertex( i1 ) ); + sgdSetVec3( tri[1], leaf->getVertex( i2 ) ); + sgdSetVec3( tri[2], leaf->getVertex( i3 ) ); + //avoid division by zero when two points are the same if ( sgdEqualVec3(tri[0], tri[1]) || sgdEqualVec3(tri[1], tri[2]) || @@ -209,13 +326,21 @@ int FGHitList::IntersectLeaf( ssgLeaf *leaf, sgdMat4 m, sgdVec4 plane; sgdMakePlane( plane, tri[0], tri[1], tri[2] ); - sgdVec3 point; - if( sgdIsectInfLinePlane( point, orig, dir, plane ) ) { - if( pointInTriangle( point, tri ) ) { - add(leaf,i,point,plane); - num_hits++; - } - } + sgdVec3 point; + if( sgdIsectInfLinePlane( point, orig, dir, plane ) ) { +#if 0 + if( pointInTriangle( point, tri ) ) { + add(leaf,i,point,plane); + num_hits++; + } +#endif // 0 + if( sgdPointInTriangle( point, tri ) ) { + // transform point into passed into desired coordinate frame + sgdXformPnt3( point, point, m ); + add(leaf,i,point,plane); + num_hits++; + } + } } return num_hits; } @@ -224,6 +349,14 @@ void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m, sgdVec3 orig, sgdVec3 dir ) { sgSphere *bsphere; + + // lookat vector in branch's coordinate frame + sgdVec3 _orig, _dir; + sgdMat4 _m; + sgdTransposeNegateMat4( _m, m); + sgdXformPnt3( _orig, orig, _m ); + sgdXformPnt3( _dir, dir, _m ); + for ( ssgEntity *kid = branch->getKid( 0 ); kid != NULL; kid = branch->getNextKid() ) @@ -233,9 +366,7 @@ void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m, sgVec3 fcenter; sgCopyVec3( fcenter, bsphere->getCenter() ); sgdVec3 center; - center[0] = fcenter[0]; - center[1] = fcenter[1]; - center[2] = fcenter[2]; + sgdSetVec3( center, fcenter ); sgdXformPnt3( center, m ) ; // watch out for overflow if ( sgdClosestPointToLineDistSquared( center, orig, dir ) < @@ -253,8 +384,8 @@ void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m, sgdPreMultMat4( m_new, xform ); } IntersectBranch( (ssgBranch *)kid, m_new, orig, dir ); - } else if ( kid->isAKindOf ( ssgTypeLeaf() ) ) { - IntersectLeaf( (ssgLeaf *)kid, m, orig, dir ); + } else if ( kid->isAKindOf( ssgTypeLeaf() ) ) { + IntersectLeaf( (ssgLeaf *)kid, m, _orig, _dir ); } } else { // end of the line for this branch @@ -322,6 +453,33 @@ void FGHitList::IntersectCachedLeaf( sgdMat4 m, } +void FGHitList::Intersect( ssgBranch *scene, sgdVec3 orig, sgdVec3 dir ) { + sgdMat4 m; + +// #define USE_CACHED_HIT + +#ifdef USE_CACHED_HIT + // This optimization gives a slight speedup + // but it precludes using the hitlist for dynamic + // objects NHV + init(); + if( last_hit() ) { + sgdMakeIdentMat4 ( m ) ; + IntersectCachedLeaf(m, orig, dir); + } + if( ! num_hits() ) { +#endif + + clear(); + sgdMakeIdentMat4 ( m ) ; + IntersectBranch( scene, m, orig, dir); + +#ifdef USE_CACHED_HIT + } +#endif +} + + static void CurrentNormalInLocalPlane(sgVec3 dst, sgVec3 src) { sgVec3 tmp; sgSetVec3(tmp, src[0], src[1], src[2] ); diff --git a/src/Scenery/hitlist.hxx b/src/Scenery/hitlist.hxx index b73489700..f76361653 100644 --- a/src/Scenery/hitlist.hxx +++ b/src/Scenery/hitlist.hxx @@ -75,31 +75,6 @@ public: }; -inline void FGHitList::Intersect( ssgBranch *scene, - sgdVec3 orig, sgdVec3 dir ) -{ - sgdMat4 m; - -#ifdef USE_CACHED_HIT - // This optimization gives a slight speedup - // but it precludes using the hitlist for dynamic - // objects NHV - init(); - if( last_hit() ) { - sgdMakeIdentMat4 ( m ) ; - IntersectCachedLeaf(m, orig, dir); - } - if( ! num_hits() ) { -#endif - clear(); - sgdMakeIdentMat4 ( m ) ; - IntersectBranch( scene, m, orig, dir); -#ifdef USE_CACHED_HIT - } -#endif -} - - // Associated function, assuming a wgs84 world with 0,0,0 at the // center, find the current terrain intersection elevation for the // point specified. -- 2.39.5