]> git.mxchange.org Git - flightgear.git/commitdiff
Centralized most view-management code in FGViewMgr. It's still a
authordavid <david>
Thu, 14 Mar 2002 00:29:20 +0000 (00:29 +0000)
committerdavid <david>
Thu, 14 Mar 2002 00:29:20 +0000 (00:29 +0000)
mess, but the mess is all in one place now.

src/Main/fg_commands.cxx
src/Main/fg_init.cxx
src/Main/fg_props.cxx
src/Main/fg_props.hxx
src/Main/globals.hxx
src/Main/main.cxx
src/Main/viewmgr.cxx
src/Main/viewmgr.hxx

index 76b0441fdd58aeb303b3f83d1b8b2e7a4f9c93a5..678a20a6b83861644c81370f5ec93f1e643d126f 100644 (file)
@@ -243,7 +243,7 @@ static bool
 do_view_cycle (const SGPropertyNode * arg, SGCommandState ** state)
 {
   globals->get_current_view()->set_view_offset(0.0);
-  globals->set_current_view(globals->get_viewmgr()->next_view());
+  globals->get_viewmgr()->next_view();
   if ( fgGetString("/sim/flight-model") == "ada" ) {
       globals->get_props()->setBoolValue( "/sim/hud/visibility", true );
       if ( globals->get_viewmgr()->get_current() == 1 ) {
index 9b4bd9233ba0aecee77f752965373b7cf9bbe340..132e3fdcc1d6cb9d7cc5cd1b2f268cabad188104 100644 (file)
@@ -588,32 +588,7 @@ void fgInitFDM() {
 
 // 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());
+  globals->get_viewmgr()->update(0);
 }
 
 
index 0b0ca687bfd0be78969d2afbfd2da7306941e7d2..357ab530a8ffd2927c550c3f92bc56a982de76d5 100644 (file)
@@ -44,7 +44,6 @@
 #include "globals.hxx"
 #include "fgfs.hxx"
 #include "fg_props.hxx"
-#include "viewmgr.hxx"
 
 #if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
 SG_USING_STD(istream);
@@ -57,67 +56,11 @@ static double getWindEast ();
 static double getWindDown ();
 #endif // FG_NEW_ENVIRONMENT
 
-// Allow the view to be set from two axes (i.e. a joystick hat)
-// This needs to be in FGViewer itself, somehow.
-static double axisLong = 0.0;
-static double axisLat = 0.0;
-
 static bool winding_ccw = true; // FIXME: temporary
 
 static bool fdm_data_logging = false; // FIXME: temporary
 
 
-/**
- * Utility function.
- */
-static inline void
-_set_view_from_axes ()
-{
-                               // Take no action when hat is centered
-  if ( ( axisLong <  0.01 ) &&
-       ( axisLong > -0.01 ) &&
-       ( axisLat  <  0.01 ) &&
-       ( axisLat  > -0.01 )
-     )
-    return;
-
-  double viewDir = 999;
-
-  /* Do all the quick and easy cases */
-  if (axisLong < 0) {          // Longitudinal axis forward
-    if (axisLat == axisLong)
-      viewDir = 45;
-    else if (axisLat == - axisLong)
-      viewDir = 315;
-    else if (axisLat == 0)
-      viewDir = 0;
-  } else if (axisLong > 0) {   // Longitudinal axis backward
-    if (axisLat == - axisLong)
-      viewDir = 135;
-    else if (axisLat == axisLong)
-      viewDir = 225;
-    else if (axisLat == 0)
-      viewDir = 180;
-  } else if (axisLong == 0) {  // Longitudinal axis neutral
-    if (axisLat < 0)
-      viewDir = 90;
-    else if (axisLat > 0)
-      viewDir = 270;
-    else return; /* And assertion failure maybe? */
-  }
-
-  /* Do all the difficult cases */
-  if ( viewDir > 900 )
-    viewDir = SGD_RADIANS_TO_DEGREES * atan2 ( -axisLat, -axisLong );
-  if ( viewDir < -1 ) viewDir += 360;
-
-//  SG_LOG(SG_INPUT, SG_ALERT, "Joystick Lat=" << axisLat << "   and Long="
-//     << axisLong << "  gave angle=" << viewDir );
-
-  globals->get_current_view()->set_goal_view_offset(viewDir*SGD_DEGREES_TO_RADIANS);
-//   globals->get_current_view()->set_view_offset(viewDir*SGD_DEGREES_TO_RADIANS);
-}
-
 \f
 ////////////////////////////////////////////////////////////////////////
 // Default property bindings (not yet handled by any module).
@@ -317,143 +260,6 @@ setAircraftDir (string dir)
 }
 
 
-/**
- * Get the current view offset in degrees.
- */
-static double
-getViewOffset ()
-{
-  return (globals->get_current_view()
-         ->get_view_offset() * SGD_RADIANS_TO_DEGREES);
-}
-
-
-static void
-setViewOffset (double offset)
-{
-  globals->get_current_view()->set_view_offset(offset * SGD_DEGREES_TO_RADIANS);
-}
-
-static double
-getGoalViewOffset ()
-{
-  return (globals->get_current_view()
-         ->get_goal_view_offset() * SGD_RADIANS_TO_DEGREES);
-}
-
-static void
-setGoalViewOffset (double offset)
-{
-    while ( offset < 0 ) {
-       offset += 360.0;
-    }
-    while ( offset > 360.0 ) {
-       offset -= 360.0;
-    }
-    // Snap to center if we are close
-    if ( fabs(offset) < 1.0 ||  fabs(offset) > 359.0 ) {
-       offset = 0.0;
-    }
-
-    globals->get_current_view()
-       ->set_goal_view_offset(offset * SGD_DEGREES_TO_RADIANS);
-}
-
-/**
- * Get the current view tilt in degrees.
- */
-static double
-getViewTilt ()
-{
-  return (globals->get_current_view()
-         ->get_view_tilt() * SGD_RADIANS_TO_DEGREES);
-}
-
-
-static void
-setViewTilt (double tilt)
-{
-  globals->get_current_view()->set_view_tilt(tilt * SGD_DEGREES_TO_RADIANS);
-}
-
-static double
-getGoalViewTilt ()
-{
-  return (globals->get_current_view()
-         ->get_goal_view_tilt() * SGD_RADIANS_TO_DEGREES);
-}
-
-static void
-setGoalViewTilt (double tilt)
-{
-    while ( tilt < 0 ) {
-       tilt += 360.0;
-    }
-    while ( tilt > 360.0 ) {
-       tilt -= 360.0;
-    }
-    // Snap to center if we are close
-    if ( fabs(tilt) < 1.0 ||  fabs(tilt) > 359.0 ) {
-       tilt = 0.0;
-    }
-
-    globals->get_current_view()
-       ->set_goal_view_tilt(tilt * SGD_DEGREES_TO_RADIANS);
-}
-
-
-/**
- * Pilot position offset from CG.
- */
-static float
-getPilotPositionXOffset ()
-{
-  FGViewer * pilot_view = globals->get_viewmgr()->get_view(0);
-  float * offset = pilot_view->get_pilot_offset();
-  return offset[0];
-}
-
-static void
-setPilotPositionXOffset (float x)
-{
-  FGViewer * pilot_view = globals->get_viewmgr()->get_view(0);
-  float * offset = pilot_view->get_pilot_offset();
-  pilot_view->set_pilot_offset(x, offset[1], offset[2]);
-}
-
-static float
-getPilotPositionYOffset ()
-{
-  FGViewer * pilot_view = globals->get_viewmgr()->get_view(0);
-  float * offset = pilot_view->get_pilot_offset();
-  return offset[1];
-}
-
-static void
-setPilotPositionYOffset (float y)
-{
-  FGViewer * pilot_view = globals->get_viewmgr()->get_view(0);
-  float * offset = pilot_view->get_pilot_offset();
-  pilot_view->set_pilot_offset(offset[0], y, offset[2]);
-}
-
-static float
-getPilotPositionZOffset ()
-{
-  FGViewer * pilot_view = globals->get_viewmgr()->get_view(0);
-  float * offset = pilot_view->get_pilot_offset();
-  return offset[2];
-}
-
-static void
-setPilotPositionZOffset (float z)
-{
-  FGViewer * pilot_view = globals->get_viewmgr()->get_view(0);
-  float * offset = pilot_view->get_pilot_offset();
-  pilot_view->set_pilot_offset(offset[0], offset[1], z);
-}
-
-
 /**
  * Return the number of milliseconds elapsed since simulation started.
  */
@@ -686,20 +492,6 @@ setWindDown (double speed)
 
 #endif // FG_NEW_ENVIRONMENT
 
-static double
-getFOV ()
-{
-  return globals->get_current_view()->get_fov();
-}
-
-static void
-setFOV (double fov)
-{
-  if ( fov < 180 ) {
-      globals->get_current_view()->set_fov( fov );
-  }
-}
-
 static long
 getWarp ()
 {
@@ -724,18 +516,6 @@ setWarpDelta (long delta)
   globals->set_warp_delta(delta);
 }
 
-static void
-setViewAxisLong (double axis)
-{
-  axisLong = axis;
-}
-
-static void
-setViewAxisLat (double axis)
-{
-  axisLat = axis;
-}
-
 static bool
 getWindingCCW ()
 {
@@ -802,22 +582,7 @@ fgInitProps ()
   fgTie("/sim/logging/classes", getLoggingClasses, setLoggingClasses);
   // fgTie("/sim/freeze", getFreeze, setFreeze);
   fgTie("/sim/aircraft-dir", getAircraftDir, setAircraftDir);
-  fgTie("/sim/view/offset-deg", getViewOffset, setViewOffset, false);
-  fgSetArchivable("/sim/view/offset-deg");
-  fgTie("/sim/view/goal-offset-deg", getGoalViewOffset, setGoalViewOffset, false);
-  fgTie("/sim/view/tilt-deg", getViewTilt, setViewTilt, false);
-  fgSetArchivable("/sim/view/tilt-deg");
-  fgTie("/sim/view/goal-tilt-deg", getGoalViewTilt, setGoalViewTilt, false);
-  fgSetArchivable("/sim/view/goal-offset-deg");
-  fgTie("/sim/view/pilot/x-offset-m",
-       getPilotPositionXOffset, setPilotPositionXOffset);
-  fgSetArchivable("/sim/view/pilot/x-offset-m");
-  fgTie("/sim/view/pilot/y-offset-m",
-       getPilotPositionYOffset, setPilotPositionYOffset);
-  fgSetArchivable("/sim/view/pilot/y-offset-m");
-  fgTie("/sim/view/pilot/z-offset-m",
-       getPilotPositionZOffset, setPilotPositionZOffset);
-  fgSetArchivable("/sim/view/pilot/z-offset-m");
+
   fgTie("/sim/time/elapsed-ms", getElapsedTime_ms);
   fgTie("/sim/time/gmt", getDateString, setDateString);
   fgSetArchivable("/sim/time/gmt");
@@ -842,13 +607,8 @@ fgInitProps ()
   fgTie("/environment/magnetic-variation-deg", getMagVar);
   fgTie("/environment/magnetic-dip-deg", getMagDip);
 
-                               // View
-  fgTie("/sim/field-of-view", getFOV, setFOV);
-  fgSetArchivable("/sim/field-of-view");
   fgTie("/sim/time/warp", getWarp, setWarp, false);
   fgTie("/sim/time/warp-delta", getWarpDelta, setWarpDelta);
-  fgTie("/sim/view/axes/long", (double(*)())0, setViewAxisLong);
-  fgTie("/sim/view/axes/lat", (double(*)())0, setViewAxisLat);
 
                                // Misc. Temporary junk.
   fgTie("/sim/temp/winding-ccw", getWindingCCW, setWindingCCW, false);
@@ -861,7 +621,6 @@ fgInitProps ()
 void
 fgUpdateProps ()
 {
-  _set_view_from_axes();
 }
 
 
index a21c438c5c378269df425cf6fdeb03b95461b384..3a612cdb203c9735d434e79123737b772c940e37 100644 (file)
@@ -451,140 +451,6 @@ fgUntie (const string &name)
 }
 
 
-                               // Templates cause ambiguity here
-
-/**
- * Tie a property to an external bool variable.
- *
- * The property's value will automatically mirror the variable's
- * value, and vice-versa, until the property is untied.
- *
- * @param name The property name to tie (full path).
- * @param pointer A pointer to the variable.
- * @param useDefault true if any existing property value should be
- *        copied to the variable; false if the variable should not
- *        be modified; defaults to true.
- */
-inline void
-fgTie (const string &name, bool *pointer, bool useDefault = true)
-{
-  if (!globals->get_props()->tie(name, SGRawValuePointer<bool>(pointer),
-                                useDefault))
-    SG_LOG(SG_GENERAL, SG_WARN,
-          "Failed to tie property " << name << " to a pointer");
-}
-
-
-/**
- * Tie a property to an external int variable.
- *
- * The property's value will automatically mirror the variable's
- * value, and vice-versa, until the property is untied.
- *
- * @param name The property name to tie (full path).
- * @param pointer A pointer to the variable.
- * @param useDefault true if any existing property value should be
- *        copied to the variable; false if the variable should not
- *        be modified; defaults to true.
- */
-inline void
-fgTie (const string &name, int *pointer, bool useDefault = true)
-{
-  if (!globals->get_props()->tie(name, SGRawValuePointer<int>(pointer),
-                                useDefault))
-    SG_LOG(SG_GENERAL, SG_WARN,
-          "Failed to tie property " << name << " to a pointer");
-}
-
-
-/**
- * Tie a property to an external long variable.
- *
- * The property's value will automatically mirror the variable's
- * value, and vice-versa, until the property is untied.
- *
- * @param name The property name to tie (full path).
- * @param pointer A pointer to the variable.
- * @param useDefault true if any existing property value should be
- *        copied to the variable; false if the variable should not
- *        be modified; defaults to true.
- */
-inline void
-fgTie (const string &name, long *pointer, bool useDefault = true)
-{
-  if (!globals->get_props()->tie(name, SGRawValuePointer<long>(pointer),
-                                useDefault))
-    SG_LOG(SG_GENERAL, SG_WARN,
-          "Failed to tie property " << name << " to a pointer");
-}
-
-
-/**
- * Tie a property to an external float variable.
- *
- * The property's value will automatically mirror the variable's
- * value, and vice-versa, until the property is untied.
- *
- * @param name The property name to tie (full path).
- * @param pointer A pointer to the variable.
- * @param useDefault true if any existing property value should be
- *        copied to the variable; false if the variable should not
- *        be modified; defaults to true.
- */
-inline void
-fgTie (const string &name, float *pointer, bool useDefault = true)
-{
-  if (!globals->get_props()->tie(name, SGRawValuePointer<float>(pointer),
-                                useDefault))
-    SG_LOG(SG_GENERAL, SG_WARN,
-          "Failed to tie property " << name << " to a pointer");
-}
-
-
-/**
- * Tie a property to an external double variable.
- *
- * The property's value will automatically mirror the variable's
- * value, and vice-versa, until the property is untied.
- *
- * @param name The property name to tie (full path).
- * @param pointer A pointer to the variable.
- * @param useDefault true if any existing property value should be
- *        copied to the variable; false if the variable should not
- *        be modified; defaults to true.
- */
-inline void
-fgTie (const string &name, double *pointer, bool useDefault = true)
-{
-  if (!globals->get_props()->tie(name, SGRawValuePointer<double>(pointer),
-                                useDefault))
-    SG_LOG(SG_GENERAL, SG_WARN,
-          "Failed to tie property " << name << " to a pointer");
-}
-
-
-/**
- * Tie a property to an external string variable.
- *
- * The property's value will automatically mirror the variable's
- * value, and vice-versa, until the property is untied.
- *
- * @param name The property name to tie (full path).
- * @param pointer A pointer to the variable.
- * @param useDefault true if any existing property value should be
- *        copied to the variable; false if the variable should not
- *        be modified; defaults to true.
- */
-inline void
-fgTie (const string &name, string *pointer, bool useDefault = true)
-{
-  if (!globals->get_props()->tie(name, SGRawValuePointer<string>(pointer),
-                                useDefault))
-    SG_LOG(SG_GENERAL, SG_WARN,
-          "Failed to tie property " << name << " to a pointer");
-}
-
-
 /**
  * Tie a property to a pair of simple functions.
  *
index 46daa721f9591434b250408db5538595511eb72b..52d58e45105623a06de9d4302ff725d414f446ae 100644 (file)
@@ -37,6 +37,8 @@
 #include <simgear/misc/commands.hxx>
 #include <simgear/misc/props.hxx>
 
+#include "viewmgr.hxx"
+
 SG_USING_STD( vector );
 SG_USING_STD( string );
 
@@ -51,7 +53,6 @@ class FGControls;
 class FGSoundMgr;
 class FGAutopilot;
 class FGFX;
-class FGViewMgr;
 class FGViewer;
 class FGATCMgr;
 class FGATCDisplay;
@@ -125,7 +126,6 @@ private:
 
     // viewer manager
     FGViewMgr *viewmgr;
-    FGViewer *current_view;
 
     // properties
     SGPropertyNode *props;
@@ -215,8 +215,9 @@ public:
 
     inline FGViewMgr *get_viewmgr() const { return viewmgr; }
     inline void set_viewmgr( FGViewMgr *vm ) { viewmgr = vm; }
-    inline FGViewer *get_current_view() const { return current_view; }
-    inline void set_current_view( FGViewer *v ) { current_view = v; }
+    inline FGViewer *get_current_view() const {
+      return viewmgr->get_current_view();
+    }
 
     inline SGPropertyNode *get_props () { return props; }
     inline void set_props( SGPropertyNode *n ) { props = n; }
index 6f01224754242edcc4b00d77931f9aeb107b3b17..caad35736833102bece2b7a65bf02e0ea4f353d6 100644 (file)
@@ -87,7 +87,6 @@
 
 #include <FDM/UIUCModel/uiuc_aircraftdir.h>
 #include <GUI/gui.h>
-#include <GUI/sgVec3Slider.hxx>
 // #include <Joystick/joystick.hxx>
 #ifdef FG_NETWORK_OLK
 #include <NetworkOLK/network.h>
@@ -446,51 +445,6 @@ void fgRenderFrame( void ) {
        // calculate our current position in cartesian space
        scenery.set_center( scenery.get_next_center() );
 
-       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() );
-
-        if (fgGetString("/sim/flight-model") == "ada") {
-            //+ve x is aft, +ve z is up (see viewer.hxx)
-            pilot_view->set_pilot_offset( -5.0, 0.0, 1.0 ); 
-       }
-
-       FGViewerLookAt *chase_view =
-           (FGViewerLookAt *)globals->get_viewmgr()->get_view( 1 );
-
-       sgVec3 po;              // chase view pilot_offset
-       sgVec3 wup;             // chase view world up
-       sgSetVec3( po, 0.0, 0.0, 100.0 );
-       sgCopyVec3( wup, pilot_view->get_world_up() );
-       sgMat4 CXFM;            // chase view + pilot offset xform
-       sgMakeRotMat4( CXFM,
-                      chase_view->get_view_offset() * SGD_RADIANS_TO_DEGREES -
-                      cur_fdm_state->get_Psi() * SGD_RADIANS_TO_DEGREES,
-                      wup );
-       sgVec3 npo;             // new pilot offset after rotation
-        sgVec3 *pPO = PilotOffsetGet();
-       sgXformVec3( po, *pPO, pilot_view->get_UP() );
-       sgXformVec3( npo, po, CXFM );
-
-       chase_view->set_geod_view_pos( longitude->getDoubleValue()
-                                        * SGD_DEGREES_TO_RADIANS, 
-                                      latitude->getDoubleValue()
-                                        * SGD_DEGREES_TO_RADIANS,
-                                      altitude->getDoubleValue()
-                                        * SG_FEET_TO_METER );
-       chase_view->set_pilot_offset( npo[0], npo[1], npo[2] );
-       chase_view->set_view_forward( pilot_view->get_view_pos() ); 
-       chase_view->set_view_up( wup );
-
        // update view port
        fgReshape( fgGetInt("/sim/startup/xsize"),
                   fgGetInt("/sim/startup/ysize") );
@@ -870,7 +824,7 @@ void fgUpdateTimeDepCalcs() {
     }
 
     // update the view angle
-    globals->get_current_view()->update(multi_loop);
+    globals->get_viewmgr()->update(multi_loop);
 
     l->UpdateAdjFog();
 
@@ -1384,19 +1338,12 @@ int mainLoop( int argc, char **argv ) {
 
     FGViewMgr *viewmgr = new FGViewMgr;
     globals->set_viewmgr( viewmgr );
-
-    FGViewerRPH *pv = new FGViewerRPH;
-    globals->get_viewmgr()->add_view( pv );
-
-    FGViewerLookAt *chase = new FGViewerLookAt;
-    globals->get_viewmgr()->add_view( chase );
+    viewmgr->init();
+    viewmgr->bind();
 
     string_list *col = new string_list;
     globals->set_channel_options_list( col );
 
-    // set current view to 0 (first) which is our main pilot view
-    globals->set_current_view( globals->get_viewmgr()->get_view( 0 ) );
-
     // Scan the config file(s) and command line options to see if
     // fg_root was specified (ignore all other options for now)
     fgInitFGRoot(argc, argv);
index 531f61334d00f3805393fe6caadaf5835fe56b07..b6b5ba502ebeadde7a08d346344b9a7234442bdf 100644 (file)
 //
 // $Id$
 
+#include <plib/sg.h>
+
+#include <GUI/sgVec3Slider.hxx>        // FIXME: this should NOT be needed
 
 #include "viewmgr.hxx"
+#include "fg_props.hxx"
 
 
 // Constructor
 FGViewMgr::FGViewMgr( void ) :
-    current( 0 )
+  axis_long(0),
+  axis_lat(0),
+  current(0)
 {
 }
 
@@ -34,3 +40,325 @@ FGViewMgr::FGViewMgr( void ) :
 // Destructor
 FGViewMgr::~FGViewMgr( void ) {
 }
+
+void
+FGViewMgr::init ()
+{
+  add_view(new FGViewerRPH);
+  add_view(new FGViewerLookAt);
+}
+
+typedef double (FGViewMgr::*double_getter)() const;
+
+void
+FGViewMgr::bind ()
+{
+  fgTie("/sim/view/offset-deg", this,
+       &FGViewMgr::getViewOffset_deg, &FGViewMgr::setViewOffset_deg);
+  fgSetArchivable("/sim/view/offset-deg");
+  fgTie("/sim/view/goal-offset-deg", this,
+       &FGViewMgr::getGoalViewOffset_deg, &FGViewMgr::setGoalViewOffset_deg);
+  fgSetArchivable("/sim/view/goal-offset-deg");
+  fgTie("/sim/view/tilt-deg", this,
+       &FGViewMgr::getViewTilt_deg, &FGViewMgr::setViewTilt_deg);
+  fgSetArchivable("/sim/view/tilt-deg");
+  fgTie("/sim/view/goal-tilt-deg", this,
+       &FGViewMgr::getGoalViewTilt_deg, &FGViewMgr::setGoalViewTilt_deg);
+  fgSetArchivable("/sim/view/goal-tilt-deg");
+  fgTie("/sim/view/pilot/x-offset-m", this,
+       &FGViewMgr::getPilotXOffset_m, &FGViewMgr::setPilotXOffset_m);
+  fgSetArchivable("/sim/view/pilot/x-offset-m");
+  fgTie("/sim/view/pilot/y-offset-m", this,
+       &FGViewMgr::getPilotYOffset_m, &FGViewMgr::setPilotYOffset_m);
+  fgSetArchivable("/sim/view/pilot/y-offset-m");
+  fgTie("/sim/view/pilot/z-offset-m", this,
+       &FGViewMgr::getPilotZOffset_m, &FGViewMgr::setPilotZOffset_m);
+  fgSetArchivable("/sim/view/pilot/z-offset-m");
+  fgTie("/sim/field-of-view", this,
+       &FGViewMgr::getFOV_deg, &FGViewMgr::setFOV_deg);
+  fgSetArchivable("/sim/field-of-view");
+  fgTie("/sim/view/axes/long", this,
+       (double_getter)0, &FGViewMgr::setViewAxisLong);
+  fgTie("/sim/view/axes/lat", this,
+       (double_getter)0, &FGViewMgr::setViewAxisLat);
+}
+
+void
+FGViewMgr::unbind ()
+{
+  fgUntie("/sim/view/offset-deg");
+  fgUntie("/sim/view/goal-offset-deg");
+  fgUntie("/sim/view/tilt-deg");
+  fgUntie("/sim/view/goal-tilt-deg");
+  fgUntie("/sim/view/pilot/x-offset-m");
+  fgUntie("/sim/view/pilot/y-offset-m");
+  fgUntie("/sim/view/pilot/z-offset-m");
+  fgUntie("/sim/field-of-view");
+  fgUntie("/sim/view/axes/long");
+  fgUntie("/sim/view/axes/lat");
+}
+
+void
+FGViewMgr::update (int dt)
+{
+  FGViewer * view = get_current_view();
+  if (view == 0)
+    return;
+
+                               // Grab some values we'll need.
+  double lon_rad = fgGetDouble("/position/longitude-deg")
+    * SGD_DEGREES_TO_RADIANS;
+  double lat_rad = fgGetDouble("/position/latitude-deg")
+    * SGD_DEGREES_TO_RADIANS;
+  double alt_m = fgGetDouble("/position/altitude-ft")
+    * SG_FEET_TO_METER;
+  double roll_rad = fgGetDouble("/orientation/roll-deg")
+    * SGD_DEGREES_TO_RADIANS;
+  double pitch_rad = fgGetDouble("/orientation/pitch-deg")
+    * SGD_DEGREES_TO_RADIANS;
+  double heading_rad = fgGetDouble("/orientation/heading-deg")
+    * SGD_DEGREES_TO_RADIANS;
+
+                               // Set up the pilot view
+  FGViewerRPH *pilot_view = (FGViewerRPH *)get_view( 0 );
+  pilot_view ->set_geod_view_pos(lon_rad, lat_rad, alt_m);
+  pilot_view->set_rph(roll_rad, pitch_rad, heading_rad);
+  if (fgGetString("/sim/flight-model") == "ada") {
+    //+ve x is aft, +ve z is up (see viewer.hxx)
+    pilot_view->set_pilot_offset( -5.0, 0.0, 1.0 ); 
+  }
+
+                               // Set up the chase view
+
+                               // FIXME: the matrix math belongs in
+                               // the viewer, not here.
+  FGViewerLookAt *chase_view = (FGViewerLookAt *)get_view( 1 );
+
+  sgVec3 po;           // chase view pilot_offset
+  sgVec3 wup;          // chase view world up
+  sgSetVec3( po, 0.0, 0.0, 100.0 );
+  sgCopyVec3( wup, pilot_view->get_world_up() );
+  sgMat4 CXFM;         // chase view + pilot offset xform
+  sgMakeRotMat4( CXFM,
+                chase_view->get_view_offset() * SGD_RADIANS_TO_DEGREES -
+                heading_rad * SGD_RADIANS_TO_DEGREES,
+                wup );
+  sgVec3 npo;          // new pilot offset after rotation
+  sgVec3 *pPO = PilotOffsetGet();
+  sgXformVec3( po, *pPO, pilot_view->get_UP() );
+  sgXformVec3( npo, po, CXFM );
+
+  chase_view->set_geod_view_pos(lon_rad, lat_rad, alt_m);
+  chase_view->set_pilot_offset( npo[0], npo[1], npo[2] );
+  chase_view->set_view_forward( pilot_view->get_view_pos() ); 
+  chase_view->set_view_up( wup );
+
+                               // Update the current view
+  do_axes();
+  view->update(dt);
+}
+
+double
+FGViewMgr::getViewOffset_deg () const
+{
+  const FGViewer * view = get_current_view();
+  return (view == 0 ? 0 : view->get_view_offset() * SGD_RADIANS_TO_DEGREES);
+}
+
+void
+FGViewMgr::setViewOffset_deg (double offset)
+{
+  FGViewer * view = get_current_view();
+  if (view != 0)
+    view->set_view_offset(offset * SGD_DEGREES_TO_RADIANS);
+  std::cout << "View offset is now " << offset << std::endl;
+}
+
+double
+FGViewMgr::getGoalViewOffset_deg () const
+{
+  const FGViewer * view = get_current_view();
+  return (view == 0 ? 0 : view->get_goal_view_offset() * SGD_RADIANS_TO_DEGREES);
+}
+
+void
+FGViewMgr::setGoalViewOffset_deg (double offset)
+{
+  FGViewer * view = get_current_view();
+  if (view != 0)
+    view->set_goal_view_offset(offset * SGD_DEGREES_TO_RADIANS);
+  std::cout << "Goal view offset is now " << offset << std::endl;
+}
+
+double
+FGViewMgr::getViewTilt_deg () const
+{
+  const FGViewer * view = get_current_view();
+  return (view == 0 ? 0 : view->get_view_tilt() * SGD_RADIANS_TO_DEGREES);
+}
+
+void
+FGViewMgr::setViewTilt_deg (double tilt)
+{
+  FGViewer * view = get_current_view();
+  if (view != 0)
+    view->set_view_tilt(tilt * SGD_DEGREES_TO_RADIANS);
+}
+
+double
+FGViewMgr::getGoalViewTilt_deg () const
+{
+  const FGViewer * view = get_current_view();
+  return (view == 0 ? 0 : view->get_goal_view_tilt() * SGD_RADIANS_TO_DEGREES);
+}
+
+void
+FGViewMgr::setGoalViewTilt_deg (double tilt)
+{
+  FGViewer * view = get_current_view();
+  if (view != 0)
+    view->set_goal_view_tilt(tilt * SGD_DEGREES_TO_RADIANS);
+}
+
+double
+FGViewMgr::getPilotXOffset_m () const
+{
+                               // FIXME: hard-coded pilot view position
+  const FGViewer * pilot_view = get_view(0);
+  if (pilot_view != 0) {
+    float * offset = ((FGViewer *)pilot_view)->get_pilot_offset();
+    return offset[0];
+  } else {
+    return 0;
+  }
+}
+
+void
+FGViewMgr::setPilotXOffset_m (double x)
+{
+                               // FIXME: hard-coded pilot view position
+  FGViewer * pilot_view = get_view(0);
+  if (pilot_view != 0) {
+    float * offset = pilot_view->get_pilot_offset();
+    pilot_view->set_pilot_offset(x, offset[1], offset[2]);
+  }
+}
+
+double
+FGViewMgr::getPilotYOffset_m () const
+{
+                               // FIXME: hard-coded pilot view position
+  const FGViewer * pilot_view = get_view(0);
+  if (pilot_view != 0) {
+    float * offset = ((FGViewer *)pilot_view)->get_pilot_offset();
+    return offset[1];
+  } else {
+    return 0;
+  }
+}
+
+void
+FGViewMgr::setPilotYOffset_m (double y)
+{
+                               // FIXME: hard-coded pilot view position
+  FGViewer * pilot_view = get_view(0);
+  if (pilot_view != 0) {
+    float * offset = pilot_view->get_pilot_offset();
+    pilot_view->set_pilot_offset(offset[0], y, offset[2]);
+  }
+}
+
+double
+FGViewMgr::getPilotZOffset_m () const
+{
+                               // FIXME: hard-coded pilot view position
+  const FGViewer * pilot_view = get_view(0);
+  if (pilot_view != 0) {
+    float * offset = ((FGViewer *)pilot_view)->get_pilot_offset();
+    return offset[2];
+  } else {
+    return 0;
+  }
+}
+
+void
+FGViewMgr::setPilotZOffset_m (double z)
+{
+                               // FIXME: hard-coded pilot view position
+  FGViewer * pilot_view = get_view(0);
+  if (pilot_view != 0) {
+    float * offset = pilot_view->get_pilot_offset();
+    pilot_view->set_pilot_offset(offset[0], offset[1], z);
+  }
+}
+
+double
+FGViewMgr::getFOV_deg () const
+{
+  const FGViewer * view = get_current_view();
+  return (view == 0 ? 0 : view->get_fov());
+}
+
+void
+FGViewMgr::setFOV_deg (double fov)
+{
+  FGViewer * view = get_current_view();
+  if (view != 0)
+    view->set_fov(fov);
+}
+
+void
+FGViewMgr::setViewAxisLong (double axis)
+{
+  axis_long = axis;
+}
+
+void
+FGViewMgr::setViewAxisLat (double axis)
+{
+  axis_lat = axis;
+}
+
+void
+FGViewMgr::do_axes ()
+{
+                               // Take no action when hat is centered
+  if ( ( axis_long <  0.01 ) &&
+       ( axis_long > -0.01 ) &&
+       ( axis_lat  <  0.01 ) &&
+       ( axis_lat  > -0.01 )
+     )
+    return;
+
+  double viewDir = 999;
+
+  /* Do all the quick and easy cases */
+  if (axis_long < 0) {         // Longitudinal axis forward
+    if (axis_lat == axis_long)
+      viewDir = 45;
+    else if (axis_lat == - axis_long)
+      viewDir = 315;
+    else if (axis_lat == 0)
+      viewDir = 0;
+  } else if (axis_long > 0) {  // Longitudinal axis backward
+    if (axis_lat == - axis_long)
+      viewDir = 135;
+    else if (axis_lat == axis_long)
+      viewDir = 225;
+    else if (axis_lat == 0)
+      viewDir = 180;
+  } else if (axis_long == 0) { // Longitudinal axis neutral
+    if (axis_lat < 0)
+      viewDir = 90;
+    else if (axis_lat > 0)
+      viewDir = 270;
+    else return; /* And assertion failure maybe? */
+  }
+
+                               // Do all the difficult cases
+  if ( viewDir > 900 )
+    viewDir = SGD_RADIANS_TO_DEGREES * atan2 ( -axis_lat, -axis_long );
+  if ( viewDir < -1 ) viewDir += 360;
+
+  get_current_view()->set_goal_view_offset(viewDir*SGD_DEGREES_TO_RADIANS);
+}
index 9969fae5f1b14e7f7fbf9ee4b7460017521cd382..6e9b76298a9e02bee181dfaabec203af0951bc43 100644 (file)
@@ -38,6 +38,7 @@
 
 #include <vector>
 
+#include "fgfs.hxx"
 #include "viewer_lookat.hxx"
 #include "viewer_rph.hxx"
 
@@ -45,14 +46,8 @@ SG_USING_STD(vector);
 
 
 // Define a structure containing view information
-class FGViewMgr {
-
-private:
-
-    typedef vector < FGViewer * > viewer_list;
-    viewer_list views;
-
-    int current;
+class FGViewMgr : public FGSubsystem
+{
 
 public:
 
@@ -62,6 +57,11 @@ public:
     // Destructor
     ~FGViewMgr( void );
 
+    virtual void init ();
+    virtual void bind ();
+    virtual void unbind ();
+    virtual void update (int dt);
+
     // getters
     inline int size() const { return views.size(); }
     inline int get_current() const { return current; }
@@ -72,11 +72,23 @@ public:
            return NULL;
        }
     }
+    inline const FGViewer *get_current_view() const {
+       if ( current < (int)views.size() ) {
+           return views[current];
+       } else {
+           return NULL;
+       }
+    }
     inline FGViewer *get_view( int i ) {
        if ( i < 0 ) { i = 0; }
        if ( i >= (int)views.size() ) { i = views.size() - 1; }
        return views[i];
     }
+    inline const FGViewer *get_view( int i ) const {
+       if ( i < 0 ) { i = 0; }
+       if ( i >= (int)views.size() ) { i = views.size() - 1; }
+       return views[i];
+    }
     inline FGViewer *next_view() {
        ++current;
        if ( current >= (int)views.size() ) {
@@ -98,6 +110,38 @@ public:
     inline void add_view( FGViewer * v ) {
        views.push_back(v);
     }
+
+private:
+
+    double axis_long;
+    double axis_lat;
+
+    void do_axes ();
+
+    double getViewOffset_deg () const;
+    void setViewOffset_deg (double offset);
+    double getGoalViewOffset_deg () const;
+    void setGoalViewOffset_deg (double offset);
+    double getViewTilt_deg () const;
+    void setViewTilt_deg (double tilt);
+    double getGoalViewTilt_deg () const;
+    void setGoalViewTilt_deg (double tilt);
+    double getPilotXOffset_m () const;
+    void setPilotXOffset_m (double x);
+    double getPilotYOffset_m () const;
+    void setPilotYOffset_m (double y);
+    double getPilotZOffset_m () const;
+    void setPilotZOffset_m (double z);
+    double getFOV_deg () const;
+    void setFOV_deg (double fov);
+    void setViewAxisLong (double axis);
+    void setViewAxisLat (double axis);
+
+    typedef vector < FGViewer * > viewer_list;
+    viewer_list views;
+
+    int current;
+
 };