1
0
Fork 0

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.
This commit is contained in:
curt 2002-02-05 20:54:08 +00:00
parent 9e8b00e2e0
commit 08bbb83b8e
13 changed files with 546 additions and 372 deletions

View file

@ -26,12 +26,21 @@
# include <config.h> # include <config.h>
#endif #endif
#include <simgear/compiler.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include STL_STRING
#include <Aircraft/aircraft.hxx>
#include <FDM/flight.hxx>
#include <Controls/controls.hxx>
#include <Scenery/scenery.hxx> #include <Scenery/scenery.hxx>
#include <simgear/constants.h> #include <simgear/constants.h>
#include <simgear/sg_inlines.h>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_geodesy.hxx> #include <simgear/math/sg_geodesy.hxx>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
@ -46,6 +55,8 @@
#include "auto_gui.hxx" #include "auto_gui.hxx"
#include "newauto.hxx" #include "newauto.hxx"
SG_USING_STD(string);
#define mySlider puSlider #define mySlider puSlider
@ -212,7 +223,7 @@ void NewHeading(puObject *cb)
FG_PUSH_PUI_DIALOG( ApHeadingDialog ); FG_PUSH_PUI_DIALOG( ApHeadingDialog );
} }
void NewHeadingInit(void) void NewHeadingInit()
{ {
// printf("NewHeadingInit\n"); // printf("NewHeadingInit\n");
char NewHeadingLabel[] = "Enter New Heading"; char NewHeadingLabel[] = "Enter New Heading";
@ -284,7 +295,7 @@ void NewAltitude(puObject *cb)
FG_PUSH_PUI_DIALOG( ApAltitudeDialog ); FG_PUSH_PUI_DIALOG( ApAltitudeDialog );
} }
void NewAltitudeInit(void) void NewAltitudeInit()
{ {
// printf("NewAltitudeInit\n"); // printf("NewAltitudeInit\n");
char NewAltitudeLabel[] = "Enter New Altitude"; char NewAltitudeLabel[] = "Enter New Altitude";
@ -331,15 +342,12 @@ void NewAltitudeInit(void)
FG_FINALIZE_PUI_DIALOG( ApAltitudeDialog ); 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 ) { static void maxroll_adj( puObject *hs ) {
float val ; float val ;
hs-> getValue ( &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 ) ; // printf ( "maxroll_adj( %p ) %f %f\n", hs, val, MaxRollAdjust * val ) ;
current_autopilot->set_MaxRoll( MaxRollAdjust * val ); current_autopilot->set_MaxRoll( MaxRollAdjust * val );
sprintf( SliderText[ 0 ], "%05.2f", current_autopilot->get_MaxRoll() ); sprintf( SliderText[ 0 ], "%05.2f", current_autopilot->get_MaxRoll() );
@ -350,7 +358,7 @@ static void rollout_adj( puObject *hs ) {
float val ; float val ;
hs-> getValue ( &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 ) ; // printf ( "rollout_adj( %p ) %f %f\n", hs, val, RollOutAdjust * val ) ;
current_autopilot->set_RollOut( RollOutAdjust * val ); current_autopilot->set_RollOut( RollOutAdjust * val );
sprintf( SliderText[ 1 ], "%05.2f", current_autopilot->get_RollOut() ); sprintf( SliderText[ 1 ], "%05.2f", current_autopilot->get_RollOut() );
@ -361,7 +369,7 @@ static void maxaileron_adj( puObject *hs ) {
float val ; float val ;
hs-> getValue ( &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 ) ; // printf ( "maxaileron_adj( %p ) %f %f\n", hs, val, MaxAileronAdjust * val ) ;
current_autopilot->set_MaxAileron( MaxAileronAdjust * val ); current_autopilot->set_MaxAileron( MaxAileronAdjust * val );
sprintf( SliderText[ 3 ], "%05.2f", current_autopilot->get_MaxAileron() ); sprintf( SliderText[ 3 ], "%05.2f", current_autopilot->get_MaxAileron() );
@ -372,7 +380,7 @@ static void rolloutsmooth_adj( puObject *hs ) {
float val ; float val ;
hs -> getValue ( &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 ) ; // printf ( "rolloutsmooth_adj( %p ) %f %f\n", hs, val, RollOutSmoothAdjust * val ) ;
current_autopilot->set_RollOutSmooth( RollOutSmoothAdjust * val ); current_autopilot->set_RollOutSmooth( RollOutSmoothAdjust * val );
sprintf( SliderText[ 2 ], "%5.2f", current_autopilot->get_RollOutSmooth() ); sprintf( SliderText[ 2 ], "%5.2f", current_autopilot->get_RollOutSmooth() );
@ -405,7 +413,7 @@ void resetAPAdjust( puObject *self ) {
fgAPAdjust( self ); fgAPAdjust( self );
} }
void fgAPAdjust( puObject * ) { void fgAPAdjust( puObject *self ) {
TmpMaxRollValue = current_autopilot->get_MaxRoll(); TmpMaxRollValue = current_autopilot->get_MaxRoll();
TmpRollOutValue = current_autopilot->get_RollOut(); TmpRollOutValue = current_autopilot->get_RollOut();
TmpMaxAileronValue = current_autopilot->get_MaxAileron(); TmpMaxAileronValue = current_autopilot->get_MaxAileron();
@ -426,7 +434,7 @@ void fgAPAdjust( puObject * ) {
} }
// Done once at system initialization // Done once at system initialization
void fgAPAdjustInit( void ) { void fgAPAdjustInit() {
// printf("fgAPAdjustInit\n"); // printf("fgAPAdjustInit\n");
#define HORIZONTAL FALSE #define HORIZONTAL FALSE
@ -671,7 +679,7 @@ void ClearRoute(puObject *cb)
globals->get_route()->clear(); globals->get_route()->clear();
} }
void NewTgtAirportInit(void) void NewTgtAirportInit()
{ {
SG_LOG( SG_AUTOPILOT, SG_INFO, " enter NewTgtAirportInit()" ); SG_LOG( SG_AUTOPILOT, SG_INFO, " enter NewTgtAirportInit()" );
sprintf( NewTgtAirportId, "%s", sprintf( NewTgtAirportId, "%s",

View file

@ -25,19 +25,6 @@
#ifndef _AUTO_GUI_HXX #ifndef _AUTO_GUI_HXX
#define _AUTO_GUI_HXX #define _AUTO_GUI_HXX
#include <simgear/compiler.h>
#include STL_STRING
#include <string.h>
#include <Aircraft/aircraft.hxx>
#include <FDM/flight.hxx>
#include <Controls/controls.hxx>
SG_USING_STD(string);
// Defines // Defines
#define AP_CURRENT_HEADING -1 #define AP_CURRENT_HEADING -1

View file

@ -30,6 +30,7 @@
#include <stdio.h> // sprintf() #include <stdio.h> // sprintf()
#include <simgear/constants.h> #include <simgear/constants.h>
#include <simgear/sg_inlines.h>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_geodesy.hxx> #include <simgear/math/sg_geodesy.hxx>
#include <simgear/math/sg_random.h> #include <simgear/math/sg_random.h>
@ -273,7 +274,7 @@ void FGAutopilot::init() {
TargetHeading = 0.0; // default direction, due north TargetHeading = 0.0; // default direction, due north
TargetAltitude = 3000; // default altitude in meters TargetAltitude = 3000; // default altitude in meters
alt_error_accum = 0; alt_error_accum = 0.0;
climb_error_accum = 0.0; climb_error_accum = 0.0;
MakeTargetAltitudeStr( TargetAltitude ); MakeTargetAltitudeStr( TargetAltitude );
@ -306,11 +307,6 @@ void FGAutopilot::init() {
update_old_control_values(); 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 // TargetAltitude = 3000; // default altitude in meters
MakeTargetAltitudeStr( TargetAltitude ); MakeTargetAltitudeStr( TargetAltitude );
alt_error_accum = 0; alt_error_accum = 0.0;
climb_error_accum = 0.0; climb_error_accum = 0.0;
update_old_control_values(); update_old_control_values();
@ -344,13 +339,10 @@ static double NormalizeDegrees( double Input ) {
// normalize the input to the range (-180,180] // normalize the input to the range (-180,180]
// Input should not be greater than -360 to 360. // Input should not be greater than -360 to 360.
// Current rules send the output to an undefined state. // Current rules send the output to an undefined state.
if ( Input > 180 ) while ( Input > 180.0 ) { Input -= 360.0; }
while(Input > 180 ) while ( Input <= -180.0 ) { Input += 360.0; }
Input -= 360;
else if ( Input <= -180 ) return Input;
while ( Input <= -180 )
Input += 360;
return ( Input );
}; };
static double LinearExtrapolate( double x, double x1, double y1, double x2, double y2 ) { static double LinearExtrapolate( double x, double x1, double y1, double x2, double y2 ) {
@ -467,8 +459,7 @@ int FGAutopilot::run() {
double adjustment = double adjustment =
current_radiostack->get_nav1_heading_needle_deflection() current_radiostack->get_nav1_heading_needle_deflection()
* (current_radiostack->get_nav1_loc_dist() * SG_METER_TO_NM); * (current_radiostack->get_nav1_loc_dist() * SG_METER_TO_NM);
if ( adjustment < -30.0 ) { adjustment = -30.0; } SG_CLAMP_RANGE( adjustment, -30.0, 30.0 );
if ( adjustment > 30.0 ) { adjustment = 30.0; }
// determine the target heading to fly to intercept the // determine the target heading to fly to intercept the
// tgt_radial // tgt_radial
@ -546,8 +537,7 @@ int FGAutopilot::run() {
double turn = FGSteam::get_TC_std(); double turn = FGSteam::get_TC_std();
// cout << "turn rate = " << turn << endl; // cout << "turn rate = " << turn << endl;
double AileronSet = -turn / 2.0; double AileronSet = -turn / 2.0;
if ( AileronSet < -1.0 ) { AileronSet = -1.0; } SG_CLAMP_RANGE( AileronSet, -1.0, 1.0 );
if ( AileronSet > 1.0 ) { AileronSet = 1.0; }
globals->get_controls()->set_aileron( AileronSet ); globals->get_controls()->set_aileron( AileronSet );
globals->get_controls()->set_rudder( AileronSet / 4.0 ); globals->get_controls()->set_rudder( AileronSet / 4.0 );
} else { } else {
@ -894,7 +884,7 @@ void FGAutopilot::set_HeadingMode( fgAutoHeadingMode mode ) {
void FGAutopilot::set_AltitudeMode( fgAutoAltitudeMode mode ) { void FGAutopilot::set_AltitudeMode( fgAutoAltitudeMode mode ) {
altitude_mode = mode; altitude_mode = mode;
alt_error_accum = 0; alt_error_accum = 0.0;
if ( altitude_mode == FG_ALTITUDE_LOCK ) { if ( altitude_mode == FG_ALTITUDE_LOCK ) {

View file

@ -47,7 +47,7 @@
// world time, so we introduce cur_fdm_state which is extrapolated by // world time, so we introduce cur_fdm_state which is extrapolated by
// the difference between sim time and real world time // the difference between sim time and real world time
FGInterface *cur_fdm_state; FGInterface *cur_fdm_state = 0;
FGInterface base_fdm_state; FGInterface base_fdm_state;
inline void init_vec(FG_VECTOR_3 vec) { inline void init_vec(FG_VECTOR_3 vec) {

View file

@ -1034,6 +1034,7 @@ void guiInit()
// Set up our Dialog Boxes // Set up our Dialog Boxes
ConfirmExitDialogInit(); ConfirmExitDialogInit();
NewAirportInit(); NewAirportInit();
#ifdef FG_NETWORK_OLK #ifdef FG_NETWORK_OLK
NewNetIdInit(); NewNetIdInit();
NewNetFGDInit(); NewNetFGDInit();

View file

@ -60,6 +60,7 @@ extern char *gui_msg_CANCEL; // "CANCEL"
extern char *gui_msg_RESET; // "RESET" extern char *gui_msg_RESET; // "RESET"
// mouse.cxx // mouse.cxx
extern void guiInitMouse(int width, int height);
extern void guiMotionFunc ( int x, int y ); extern void guiMotionFunc ( int x, int y );
extern void guiMouseFunc(int button, int updown, int x, int y); extern void guiMouseFunc(int button, int updown, int x, int y);
extern void maybeToggleMouse( void ); extern void maybeToggleMouse( void );
@ -74,21 +75,24 @@ extern void TurnCursorOff( void );
// These will also repair any damage done to the Panel if active // These will also repair any damage done to the Panel if active
// Activate Dialog Box // Activate Dialog Box
#define FG_PUSH_PUI_DIALOG( X ) \ inline void FG_PUSH_PUI_DIALOG( puObject *X ) {
maybeToggleMouse(); \ maybeToggleMouse();
puPushLiveInterface( (X) ) ; \ puPushLiveInterface( (puInterface *)X ) ;
( X )->reveal() X->reveal() ;
}
// Deactivate Dialog Box // Deactivate Dialog Box
#define FG_POP_PUI_DIALOG( X ) \ inline void FG_POP_PUI_DIALOG( puObject *X ) {
(X)->hide(); \ X->hide();
puPopLiveInterface(); \ puPopLiveInterface();
maybeToggleMouse(); maybeToggleMouse();
}
// Finalize Dialog Box Construction // Finalize Dialog Box Construction
#define FG_FINALIZE_PUI_DIALOG( X ) \ inline void FG_FINALIZE_PUI_DIALOG( puObject *X ) {
( X )->close(); \ ((puGroup *)X)->close();
( X )->hide(); \ X->hide();
puPopLiveInterface(); puPopLiveInterface();
}
#endif // _GUI_H_ #endif // _GUI_H_

View file

@ -96,13 +96,16 @@ static int mouse_joystick_control = 0;
// on second left click in MOUSE_VIEW mode // on second left click in MOUSE_VIEW mode
// This has file scope so that it can be reset // This has file scope so that it can be reset
// if the little rodent is moved NHV // if the little rodent is moved NHV
static int _mVtoggle; static int _mVtoggle = 0;
// we break up the glutGetModifiers return mask // we break up the glutGetModifiers return mask
// once per loop and stash what we need in these // once per loop and stash what we need in these
static int glut_active_shift; static int glut_active_shift = 0;
static int glut_active_ctrl; static int glut_active_ctrl = 0;
static int glut_active_alt; 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 // uncomment this for view to exactly follow mouse in MOUSE_VIEW mode
// else smooth out the view panning to .01 radian per frame // 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 rudder_sensitivity = 1.0/500.0;
static double trim_sensitivity = 1.0/1000.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) static inline int guiGetMouseButton(void)
{ {
return last_buttons; return last_buttons;
@ -164,6 +173,64 @@ static inline int right_button( void ) {
return( last_buttons & (1 << GLUT_RIGHT_BUTTON) ); 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 ) void TurnCursorOn( void )
{ {
mouse_active = ~0; mouse_active = ~0;
@ -181,8 +248,8 @@ void TurnCursorOn( void )
} }
#endif #endif
#if defined(X_CURSOR_TWEAKS) #if defined(X_CURSOR_TWEAKS)
glutWarpPointer( fgGetInt("/sim/startup/xsize")/2, glutWarpPointer( MOUSE_XSIZE/2,
fgGetInt("/sim/startup/ysize")/2); MOUSE_YSIZE/2);
#endif #endif
} }
@ -192,8 +259,8 @@ void TurnCursorOff( void )
#if defined(WIN32_CURSOR_TWEAKS) #if defined(WIN32_CURSOR_TWEAKS)
glutSetCursor(GLUT_CURSOR_NONE); glutSetCursor(GLUT_CURSOR_NONE);
#elif defined(X_CURSOR_TWEAKS) #elif defined(X_CURSOR_TWEAKS)
glutWarpPointer( fgGetInt("/sim/startup/xsize"), glutWarpPointer( MOUSE_XSIZE,
fgGetInt("/sim/startup/ysize")); MOUSE_YSIZE);
#endif #endif
} }
@ -242,8 +309,8 @@ void BusyCursor( int restore )
void CenterView( void ) { void CenterView( void ) {
if( mouse_mode == MOUSE_VIEW ) { if( mouse_mode == MOUSE_VIEW ) {
mouse_mode = MOUSE_POINTER; mouse_mode = MOUSE_POINTER;
_savedX = fgGetInt("/sim/startup/xsize")/2; _savedX = MOUSE_XSIZE/2;
_savedY = fgGetInt("/sim/startup/ysize")/2; _savedY = MOUSE_YSIZE/2;
_mVtoggle = 0; _mVtoggle = 0;
Quat0(); Quat0();
build_rotmatrix(GuiQuat_mat, curGuiQuat); build_rotmatrix(GuiQuat_mat, curGuiQuat);
@ -254,32 +321,58 @@ void CenterView( void ) {
glutWarpPointer( _savedX, _savedY ); glutWarpPointer( _savedX, _savedY );
} }
globals->get_current_view()->set_goal_view_offset(0.0); set_goal_view_offset(0.0);
globals->get_current_view()->set_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 ) void guiMotionFunc ( int x, int y )
{ {
int ww, wh, need_warp = 0; int ww, wh, need_warp = 0;
float W, H; float W, H;
double offset; double offset;
ww = fgGetInt("/sim/startup/xsize"); ww = MOUSE_XSIZE;
wh = fgGetInt("/sim/startup/ysize"); wh = MOUSE_YSIZE;
if (mouse_mode == MOUSE_POINTER) { if (mouse_mode == MOUSE_POINTER) {
// TURN MENU ON IF MOUSE AT TOP // TURN MENU ON IF MOUSE AT TOP
if( y == 0 ) { if( y < 1 ) {
if( !gui_menu_on ) if( !gui_menu_on )
guiToggleMenu(); guiToggleMenu();
} }
// TURN MENU OFF IF MOUSE AT BOTTOM // TURN MENU OFF IF MOUSE AT BOTTOM
else if( y > wh-1 ) { else if( y > wh-2 ) {
if( gui_menu_on ) if( gui_menu_on )
guiToggleMenu(); guiToggleMenu();
} }
puMouse ( x, y ) ; // puMouse ( x, y ) ;
glutPostRedisplay () ; glutPostRedisplay () ;
} else { } else {
if( x == _mX && y == _mY) if( x == _mX && y == _mY)
@ -295,27 +388,21 @@ void guiMotionFunc ( int x, int y )
fgSetString("/sim/control-mode", "mouse"); fgSetString("/sim/control-mode", "mouse");
} else { } else {
if ( left_button() ) { if ( left_button() ) {
offset = (_mX - x) * brake_sensitivity; move_brake( (_mX - x) * brake_sensitivity);
globals->get_controls()->move_brake(FGControls::ALL_WHEELS, offset); move_throttle((_mY - y) * throttle_sensitivity);
offset = (_mY - y) * throttle_sensitivity;
globals->get_controls()->move_throttle(FGControls::ALL_ENGINES, offset);
} else if ( right_button() ) { } else if ( right_button() ) {
if( ! current_autopilot->get_HeadingEnabled() ) { if( ! AP_HeadingEnabled() ) {
offset = (x - _mX) * rudder_sensitivity; move_rudder((x - _mX) * rudder_sensitivity);
globals->get_controls()->move_rudder(offset);
} }
if( ! current_autopilot->get_AltitudeEnabled() ) { if( ! AP_AltitudeEnabled() ) {
offset = (_mY - y) * trim_sensitivity; move_elevator_trim((_mY - y) * trim_sensitivity);
globals->get_controls()->move_elevator_trim(offset);
} }
} else { } else {
if( ! current_autopilot->get_HeadingEnabled() ) { if( ! AP_HeadingEnabled() ) {
offset = (x - _mX) * aileron_sensitivity; move_aileron((x - _mX) * aileron_sensitivity);
globals->get_controls()->move_aileron(offset);
} }
if( ! current_autopilot->get_AltitudeEnabled() ) { if( ! AP_AltitudeEnabled() ) {
offset = (_mY - y) * elevator_sensitivity; move_elevator((_mY - y) * elevator_sensitivity);
globals->get_controls()->move_elevator(offset);
} }
} }
} }
@ -380,7 +467,7 @@ void guiMotionFunc ( int x, int y )
// do horizontal pan // do horizontal pan
// this could be done in above quat // this could be done in above quat
// but requires redoing view pipeline // 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 ); offset += ((_mX - x) * SGD_2PI / W );
while (offset < 0.0) { while (offset < 0.0) {
offset += SGD_2PI; offset += SGD_2PI;
@ -388,9 +475,9 @@ void guiMotionFunc ( int x, int y )
while (offset > SGD_2PI) { while (offset > SGD_2PI) {
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 #ifdef NO_SMOOTH_MOUSE_VIEW
globals->get_current_view()->set_view_offset(offset); set_view_offset(offset);
#endif #endif
break; break;
@ -443,13 +530,10 @@ void guiMouseFunc(int button, int updown, int x, int y)
_mY = _mVy; _mY = _mVy;
x = _Vx; x = _Vx;
y = _Vy; y = _Vy;
curGuiQuat[0] = _quat[0]; sgCopyVec4(curGuiQuat, _quat);
curGuiQuat[1] = _quat[1]; set_goal_view_offset(_view_offset);
curGuiQuat[2] = _quat[2];
curGuiQuat[3] = _quat[3];
globals->get_current_view()->set_goal_view_offset(_view_offset);
#ifdef NO_SMOOTH_MOUSE_VIEW #ifdef NO_SMOOTH_MOUSE_VIEW
globals->get_current_view()->set_view_offset(_view_offset); set_view_offset(_view_offset);
#endif #endif
} else { } else {
// center view // center view
@ -457,18 +541,14 @@ void guiMouseFunc(int button, int updown, int x, int y)
_mVy = _mY; _mVy = _mY;
_Vx = x; _Vx = x;
_Vy = y; _Vy = y;
_quat[0] = curGuiQuat[0]; sgCopyVec4(_quat,curGuiQuat);
_quat[1] = curGuiQuat[1]; x = MOUSE_XSIZE/2;
_quat[2] = curGuiQuat[2]; y = MOUSE_YSIZE/2;
_quat[3] = curGuiQuat[3];
x = fgGetInt("/sim/startup/xsize")/2;
y = fgGetInt("/sim/startup/ysize")/2;
Quat0(); Quat0();
_view_offset = _view_offset = get_goal_view_offset();
globals->get_current_view()->get_goal_view_offset(); set_goal_view_offset(0.0);
globals->get_current_view()->set_goal_view_offset(0.0);
#ifdef NO_SMOOTH_MOUSE_VIEW #ifdef NO_SMOOTH_MOUSE_VIEW
globals->get_current_view()->set_view_offset(0.0); set_view_offset(0.0);
#endif #endif
} }
glutWarpPointer( x , y); glutWarpPointer( x , y);
@ -478,48 +558,55 @@ void guiMouseFunc(int button, int updown, int x, int y)
} }
} else if ( button == GLUT_RIGHT_BUTTON) { } else if ( button == GLUT_RIGHT_BUTTON) {
switch (mouse_mode) { switch (mouse_mode) {
case MOUSE_POINTER: case MOUSE_POINTER:
SG_LOG( SG_INPUT, SG_INFO, "Mouse in yoke mode" );
mouse_mode = MOUSE_YOKE; mouse_mode = MOUSE_YOKE;
mouse_joystick_control = 0; mouse_joystick_control = 0;
_savedX = x; _savedX = x;
_savedY = y; _savedY = y;
// start with zero point in center of screen // start with zero point in center of screen
_mX = fgGetInt("/sim/startup/xsize")/2; _mX = MOUSE_XSIZE/2;
_mY = fgGetInt("/sim/startup/ysize")/2; _mY = MOUSE_YSIZE/2;
// try to have the MOUSE_YOKE position // try to have the MOUSE_YOKE position
// reflect the current stick position // reflect the current stick position
offset = globals->get_controls()->get_aileron(); x = _mX - (int)(get_aileron() * aileron_sensitivity);
x = _mX - (int)(offset * aileron_sensitivity); y = _mY - (int)(get_elevator() * elevator_sensitivity);
offset = globals->get_controls()->get_elevator();
y = _mY - (int)(offset * elevator_sensitivity);
glutSetCursor(GLUT_CURSOR_CROSSHAIR); glutSetCursor(GLUT_CURSOR_CROSSHAIR);
SG_LOG( SG_INPUT, SG_INFO, "Mouse in yoke mode" );
break; break;
case MOUSE_YOKE: case MOUSE_YOKE:
SG_LOG( SG_INPUT, SG_INFO, "Mouse in view mode" );
mouse_mode = MOUSE_VIEW; mouse_mode = MOUSE_VIEW;
fgSetString("/sim/control-mode", "joystick"); 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; _mVtoggle = 0;
// #ifndef RESET_VIEW_ON_LEAVING_MOUSE_VIEW
Quat0(); Quat0();
build_rotmatrix(GuiQuat_mat, curGuiQuat); build_rotmatrix(GuiQuat_mat, curGuiQuat);
// #endif
glutSetCursor(GLUT_CURSOR_LEFT_RIGHT); glutSetCursor(GLUT_CURSOR_LEFT_RIGHT);
SG_LOG( SG_INPUT, SG_INFO, "Mouse in view mode" );
break; break;
case MOUSE_VIEW: case MOUSE_VIEW:
SG_LOG( SG_INPUT, SG_INFO, "Mouse in pointer mode" );
mouse_mode = MOUSE_POINTER; mouse_mode = MOUSE_POINTER;
x = _savedX; x = _savedX;
y = _savedY; y = _savedY;
#ifdef RESET_VIEW_ON_LEAVING_MOUSE_VIEW #ifdef RESET_VIEW_ON_LEAVING_MOUSE_VIEW
Quat0(); Quat0();
build_rotmatrix(GuiQuat_mat, curGuiQuat); 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 #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 // NO_SMOOTH_MOUSE_VIEW
#endif // RESET_VIEW_ON_LEAVING_MOUSE_VIEW #endif // RESET_VIEW_ON_LEAVING_MOUSE_VIEW
glutSetCursor(GLUT_CURSOR_INHERIT); glutSetCursor(GLUT_CURSOR_INHERIT);
@ -528,8 +615,6 @@ void guiMouseFunc(int button, int updown, int x, int y)
if(!gui_menu_on) if(!gui_menu_on)
TurnCursorOff(); TurnCursorOff();
#endif // WIN32_CURSOR_TWEAKS_OFF #endif // WIN32_CURSOR_TWEAKS_OFF
SG_LOG( SG_INPUT, SG_INFO, "Mouse in pointer mode" );
break; break;
} // end switch (mouse_mode) } // end switch (mouse_mode)
glutWarpPointer( x, y ); glutWarpPointer( x, y );

View file

@ -286,7 +286,8 @@ sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 vec, const char *title,
dialer_x = dialer_x + 170; dialer_x = dialer_x + 170;
/* pitch */ /* 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 */ /* radius */
HS2 = new FloatSlider ( slider_x, slider_y, slider_width, vec[2], Ztitle, 100.0f, 0.0f ); HS2 = new FloatSlider ( slider_x, slider_y, slider_width, vec[2], Ztitle, 100.0f, 0.0f );

View file

@ -452,6 +452,7 @@ bool fgSetPosFromAirportIDandHdg( const string& id, double tgt_hdg ) {
lat2=olat; lat2=olat;
lon2=olon; lon2=olon;
} }
fgSetDouble("/position/longitude-deg", lon2 ); fgSetDouble("/position/longitude-deg", lon2 );
fgSetDouble("/position/latitude-deg", lat2 ); fgSetDouble("/position/latitude-deg", lat2 );
fgSetDouble("/orientation/heading-deg", heading ); 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 // This is the top level init routine which calls all the other
// initialization routines. If you are adding a subsystem to flight // initialization routines. If you are adding a subsystem to flight
// gear, its initialization call should located in this routine. // gear, its initialization call should located in this routine.
@ -530,8 +607,7 @@ bool fgInitSubsystems( void ) {
SGPath mpath( globals->get_fg_root() ); SGPath mpath( globals->get_fg_root() );
mpath.append( "materials.xml" ); mpath.append( "materials.xml" );
if ( material_lib.load( mpath.str() ) ) { if ( ! material_lib.load( mpath.str() ) ) {
} else {
SG_LOG( SG_GENERAL, SG_ALERT, "Error loading material lib!" ); SG_LOG( SG_GENERAL, SG_ALERT, "Error loading material lib!" );
exit(-1); exit(-1);
} }
@ -562,43 +638,7 @@ bool fgInitSubsystems( void ) {
// Initialize the flight model subsystem. // Initialize the flight model subsystem.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
double dt = 1.0 / fgGetInt("/sim/model-hz"); fgInitFDM();
// 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();
// allocates structures so must happen before any of the flight // allocates structures so must happen before any of the flight
// model or control parameters are set // model or control parameters are set
@ -622,34 +662,7 @@ bool fgInitSubsystems( void ) {
// Initialize the view manager subsystem. // 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 */ fgInitView();
// 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());
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -786,6 +799,7 @@ bool fgInitSubsystems( void ) {
fgInitCommands(); fgInitCommands();
#ifdef ENABLE_AUDIO_SUPPORT
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Initialize the sound subsystem. // Initialize the sound subsystem.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -802,6 +816,7 @@ bool fgInitSubsystems( void ) {
globals->get_fx()->init(); globals->get_fx()->init();
globals->get_fx()->bind(); globals->get_fx()->bind();
#endif
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Initialize the radio stack subsystem. // Initialize the radio stack subsystem.
@ -843,12 +858,11 @@ bool fgInitSubsystems( void ) {
current_autopilot->init(); current_autopilot->init();
// initialize the gui parts of the autopilot // initialize the gui parts of the autopilot
NewTgtAirportInit();
fgAPAdjustInit(); fgAPAdjustInit();
NewTgtAirportInit();
NewHeadingInit(); NewHeadingInit();
NewAltitudeInit(); NewAltitudeInit();
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Initialize I/O subsystem. // Initialize I/O subsystem.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -930,71 +944,20 @@ void fgReInitSubsystems( void )
// Initialize the Scenery Management subsystem // Initialize the Scenery Management subsystem
scenery.init(); scenery.init();
// if( global_tile_mgr.init() ) { #if 0
// Load the local scenery data if( global_tile_mgr.init() ) {
Load the local scenery data
global_tile_mgr.update( longitude->getDoubleValue(), global_tile_mgr.update( longitude->getDoubleValue(),
latitude->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 { } else {
SG_LOG(SG_GENERAL, SG_ALERT, SG_LOG( SG_GENERAL, SG_ALERT, "Error in Tile Manager initialization!" );
"Unrecognized flight model '" << model
<< "', cannot init flight dynamics model.");
exit(-1);
}
} catch ( ... ) {
SG_LOG(SG_GENERAL, SG_ALERT, "FlightGear aborting\n\n");
exit(-1); exit(-1);
} }
#endif
// Initialize view parameters fgInitFDM();
FGViewerRPH *pilot_view =
(FGViewerRPH *)globals->get_viewmgr()->get_view( 0 );
pilot_view->set_view_offset( 0.0 ); fgInitView();
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 );
SG_LOG( SG_GENERAL, SG_DEBUG, " abs_view_pos = "
<< globals->get_current_view()->get_abs_view_pos());
globals->get_controls()->reset_all(); globals->get_controls()->reset_all();
current_autopilot->reset(); current_autopilot->reset();

View file

@ -114,6 +114,7 @@
#include <FDM/flight.hxx> #include <FDM/flight.hxx>
#include <FDM/ADA.hxx> #include <FDM/ADA.hxx>
#include <Scenery/tileentry.hxx> #include <Scenery/tileentry.hxx>
// Should already be inlcluded by gl.h if needed by your platform so // Should already be inlcluded by gl.h if needed by your platform so
// we shouldn't include this here. // we shouldn't include this here.
// #include <GL/glext.h> // #include <GL/glext.h>
@ -265,9 +266,9 @@ ssgEntity *fgFindNode( ssgEntity *node, const char *name ) {
ssgEntity *kid = ((ssgBranch*)node)->getKid(0); ssgEntity *kid = ((ssgBranch*)node)->getKid(0);
while ( kid != NULL ) { while ( kid != NULL ) {
ssgEntity *n = fgFindNode(kid, name); ssgEntity *n = fgFindNode(kid, name);
if (n != NULL) if ( n != NULL ) {
return n; return n;
}
kid = ((ssgBranch*)node)->getNextKid(); kid = ((ssgBranch*)node)->getNextKid();
} }
} }
@ -951,7 +952,7 @@ void fgUpdateTimeDepCalcs() {
// run Autopilot system // run Autopilot system
current_autopilot->run(); current_autopilot->run();
// update autopilot // update FDM
cur_fdm_state->update( 1 ); cur_fdm_state->update( 1 );
} }
FGSteam::update( multi_loop * fgGetInt("/sim/speed-up") ); 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/xsize", width);
fgSetInt("/sim/startup/ysize", height); fgSetInt("/sim/startup/ysize", height);
guiInitMouse(width, height);
ssgSetFOV( globals->get_current_view()->get_h_fov(), ssgSetFOV( globals->get_current_view()->get_h_fov(),
globals->get_current_view()->get_v_fov() ); globals->get_current_view()->get_v_fov() );
@ -1400,7 +1402,7 @@ int fgGlutInitEvents( void ) {
// draw the scene // draw the scene
glutDisplayFunc( fgRenderFrame ); glutDisplayFunc( fgRenderFrame );
return(1); return 1;
} }

View file

@ -86,9 +86,9 @@ class FGATC610x : public FGProtocol {
public: public:
inline FGATC610x() { } FGATC610x() { }
inline ~FGATC610x() { } ~FGATC610x() { }
bool open(); bool open();

View file

@ -12,6 +12,8 @@
#include <GL/glut.h> #include <GL/glut.h>
#include <GL/gl.h> #include <GL/gl.h>
#include <plib/sg.h>
#include <simgear/constants.h> #include <simgear/constants.h>
#include <simgear/sg_inlines.h> #include <simgear/sg_inlines.h>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
@ -27,7 +29,7 @@
extern ssgBranch *terrain; extern ssgBranch *terrain;
#if 0
// check to see if the intersection point is // check to see if the intersection point is
// actually inside this face // actually inside this face
static bool pointInTriangle( sgdVec3 point, sgdVec3 tri[3] ) 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 ] + t2 * mat[ 2 ][ 2 ] +
mat[ 3 ][ 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 Find the intersection of an infinite line with a leaf
@ -195,9 +312,9 @@ int FGHitList::IntersectLeaf( ssgLeaf *leaf, sgdMat4 m,
leaf->getTriangle( i, &i1, &i2, &i3 ); leaf->getTriangle( i, &i1, &i2, &i3 );
sgdVec3 tri[3]; sgdVec3 tri[3];
sgdXformPnt3( tri[0], leaf->getVertex( i1 ), m ); sgdSetVec3( tri[0], leaf->getVertex( i1 ) );
sgdXformPnt3( tri[1], leaf->getVertex( i2 ), m ); sgdSetVec3( tri[1], leaf->getVertex( i2 ) );
sgdXformPnt3( tri[2], leaf->getVertex( i3 ), m ); sgdSetVec3( tri[2], leaf->getVertex( i3 ) );
//avoid division by zero when two points are the same //avoid division by zero when two points are the same
if ( sgdEqualVec3(tri[0], tri[1]) || if ( sgdEqualVec3(tri[0], tri[1]) ||
@ -211,10 +328,18 @@ int FGHitList::IntersectLeaf( ssgLeaf *leaf, sgdMat4 m,
sgdVec3 point; sgdVec3 point;
if( sgdIsectInfLinePlane( point, orig, dir, plane ) ) { if( sgdIsectInfLinePlane( point, orig, dir, plane ) ) {
#if 0
if( pointInTriangle( point, tri ) ) { if( pointInTriangle( point, tri ) ) {
add(leaf,i,point,plane); add(leaf,i,point,plane);
num_hits++; 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; return num_hits;
@ -224,6 +349,14 @@ void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m,
sgdVec3 orig, sgdVec3 dir ) sgdVec3 orig, sgdVec3 dir )
{ {
sgSphere *bsphere; 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 ); for ( ssgEntity *kid = branch->getKid( 0 );
kid != NULL; kid != NULL;
kid = branch->getNextKid() ) kid = branch->getNextKid() )
@ -233,9 +366,7 @@ void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m,
sgVec3 fcenter; sgVec3 fcenter;
sgCopyVec3( fcenter, bsphere->getCenter() ); sgCopyVec3( fcenter, bsphere->getCenter() );
sgdVec3 center; sgdVec3 center;
center[0] = fcenter[0]; sgdSetVec3( center, fcenter );
center[1] = fcenter[1];
center[2] = fcenter[2];
sgdXformPnt3( center, m ) ; sgdXformPnt3( center, m ) ;
// watch out for overflow // watch out for overflow
if ( sgdClosestPointToLineDistSquared( center, orig, dir ) < if ( sgdClosestPointToLineDistSquared( center, orig, dir ) <
@ -254,7 +385,7 @@ void FGHitList::IntersectBranch( ssgBranch *branch, sgdMat4 m,
} }
IntersectBranch( (ssgBranch *)kid, m_new, orig, dir ); IntersectBranch( (ssgBranch *)kid, m_new, orig, dir );
} else if ( kid->isAKindOf( ssgTypeLeaf() ) ) { } else if ( kid->isAKindOf( ssgTypeLeaf() ) ) {
IntersectLeaf( (ssgLeaf *)kid, m, orig, dir ); IntersectLeaf( (ssgLeaf *)kid, m, _orig, _dir );
} }
} else { } else {
// end of the line for this branch // 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) { static void CurrentNormalInLocalPlane(sgVec3 dst, sgVec3 src) {
sgVec3 tmp; sgVec3 tmp;
sgSetVec3(tmp, src[0], src[1], src[2] ); sgSetVec3(tmp, src[0], src[1], src[2] );

View file

@ -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 // Associated function, assuming a wgs84 world with 0,0,0 at the
// center, find the current terrain intersection elevation for the // center, find the current terrain intersection elevation for the
// point specified. // point specified.