# include <config.h>
#endif
+#include <simgear/compiler.h>
+
#include <assert.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 <simgear/constants.h>
+#include <simgear/sg_inlines.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/misc/sg_path.hxx>
#include "auto_gui.hxx"
#include "newauto.hxx"
+SG_USING_STD(string);
+
#define mySlider puSlider
FG_PUSH_PUI_DIALOG( ApHeadingDialog );
}
-void NewHeadingInit(void)
+void NewHeadingInit()
{
// printf("NewHeadingInit\n");
char NewHeadingLabel[] = "Enter New Heading";
FG_PUSH_PUI_DIALOG( ApAltitudeDialog );
}
-void NewAltitudeInit(void)
+void NewAltitudeInit()
{
// printf("NewAltitudeInit\n");
char NewAltitudeLabel[] = "Enter New Altitude";
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() );
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() );
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() );
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() );
fgAPAdjust( self );
}
-void fgAPAdjust( puObject * ) {
+void fgAPAdjust( puObject *self ) {
TmpMaxRollValue = current_autopilot->get_MaxRoll();
TmpRollOutValue = current_autopilot->get_RollOut();
TmpMaxAileronValue = current_autopilot->get_MaxAileron();
}
// Done once at system initialization
-void fgAPAdjustInit( void ) {
+void fgAPAdjustInit() {
// printf("fgAPAdjustInit\n");
#define HORIZONTAL FALSE
globals->get_route()->clear();
}
-void NewTgtAirportInit(void)
+void NewTgtAirportInit()
{
SG_LOG( SG_AUTOPILOT, SG_INFO, " enter NewTgtAirportInit()" );
sprintf( NewTgtAirportId, "%s",
#ifndef _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
#define AP_CURRENT_HEADING -1
#include <stdio.h> // sprintf()
#include <simgear/constants.h>
+#include <simgear/sg_inlines.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/math/sg_random.h>
void FGAutopilot::MakeTargetHeadingStr( double bearing ) {
- if( bearing < 0. ) {
+ if ( bearing < 0. ) {
bearing += 360.;
} else if (bearing > 360. ) {
bearing -= 360.;
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 );
update_old_control_values();
- // Initialize GUI components of autopilot
- // NewTgtAirportInit();
- // fgAPAdjustInit() ;
- // NewHeadingInit();
- // NewAltitudeInit();
};
// 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();
// 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 ) {
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
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 {
void FGAutopilot::set_AltitudeMode( fgAutoAltitudeMode mode ) {
altitude_mode = mode;
- alt_error_accum = 0;
+ alt_error_accum = 0.0;
if ( altitude_mode == FG_ALTITUDE_LOCK ) {
// 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) {
// Set up our Dialog Boxes
ConfirmExitDialogInit();
NewAirportInit();
+
#ifdef FG_NETWORK_OLK
NewNetIdInit();
NewNetFGDInit();
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 );
// 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_
// 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
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;
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;
}
#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
}
#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
}
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);
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)
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);
}
}
}
// 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;
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;
_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
_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);
_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);
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 );
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 );
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;
lat2=olat;
lon2=olon;
}
+
fgSetDouble("/position/longitude-deg", lon2 );
fgSetDouble("/position/latitude-deg", lat2 );
fgSetDouble("/orientation/heading-deg", heading );
}
+// 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.
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);
}
// 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.
// 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();
////////////////////////////////////////////////////////////////////
fgInitCommands();
+#ifdef ENABLE_AUDIO_SUPPORT
////////////////////////////////////////////////////////////////////
// Initialize the sound subsystem.
////////////////////////////////////////////////////////////////////
globals->get_fx()->init();
globals->get_fx()->bind();
+#endif
////////////////////////////////////////////////////////////////////
// Initialize the radio stack subsystem.
current_autopilot->init();
// initialize the gui parts of the autopilot
+ fgAPAdjustInit();
NewTgtAirportInit();
- fgAPAdjustInit() ;
NewHeadingInit();
NewAltitudeInit();
-
////////////////////////////////////////////////////////////////////
// Initialize I/O subsystem.
////////////////////////////////////////////////////////////////////
// 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();
#include <FDM/flight.hxx>
#include <FDM/ADA.hxx>
#include <Scenery/tileentry.hxx>
+
// Should already be inlcluded by gl.h if needed by your platform so
// we shouldn't include this here.
// #include <GL/glext.h>
{ 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
// 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
// run Autopilot system
current_autopilot->run();
- // update autopilot
+ // update FDM
cur_fdm_state->update( 1 );
}
FGSteam::update( multi_loop * fgGetInt("/sim/speed-up") );
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() );
// draw the scene
glutDisplayFunc( fgRenderFrame );
- return(1);
+ return 1;
}
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") {
public:
- inline FGATC610x() { }
+ FGATC610x() { }
- inline ~FGATC610x() { }
+ ~FGATC610x() { }
bool open();
#include <GL/glut.h>
#include <GL/gl.h>
+#include <plib/sg.h>
+
#include <simgear/constants.h>
#include <simgear/sg_inlines.h>
#include <simgear/debug/logstream.hxx>
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] )
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
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]) ||
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;
}
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() )
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 ) <
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
}
+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] );
};
-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.