]> git.mxchange.org Git - flightgear.git/commitdiff
Rename Viewer/viewer.cxx to view
authorJames Turner <zakalawe@mac.com>
Mon, 25 Jan 2016 23:17:17 +0000 (17:17 -0600)
committerJames Turner <zakalawe@mac.com>
Wed, 17 Feb 2016 21:25:39 +0000 (21:25 +0000)
- keep class and file names in sync.

18 files changed:
src/AIModel/AIEscort.cxx
src/AIModel/AIGroundVehicle.cxx
src/Cockpit/panel.cxx
src/Instrumentation/HUD/HUD.cxx
src/Instrumentation/HUD/HUD_ladder.cxx
src/Instrumentation/HUD/HUD_runway.cxx
src/Main/fg_commands.cxx
src/Main/options.cxx
src/Model/acmodel.cxx
src/Model/panelnode.cxx
src/Time/light.cxx
src/Viewer/CMakeLists.txt
src/Viewer/renderer.cxx
src/Viewer/view.cxx [new file with mode: 0644]
src/Viewer/view.hxx [new file with mode: 0644]
src/Viewer/viewer.cxx [deleted file]
src/Viewer/viewer.hxx [deleted file]
src/Viewer/viewmgr.cxx

index c2067ae1a353f82dfbc8ff6dfeccf2c650cfe11b..b4662b7081b63ceab65928de2dba5c51097e65f7 100644 (file)
@@ -33,7 +33,7 @@
 #include <cmath>
 #include <Main/util.hxx>
 #include <Main/globals.hxx>
-#include <Viewer/viewer.hxx>
+#include <Viewer/view.hxx>
 
 #include <Scenery/scenery.hxx>
 
index 2ef662e09dc8eaf3eaea2515b408e6b04efb4de0..da72f905a12740119d0f81381f629cfc6f6d1cd9 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <simgear/sg_inlines.h>
 
-#include <Viewer/viewer.hxx>
+#include <Viewer/view.hxx>
 #include <Scenery/scenery.hxx>
 #include <Airports/dynamics.hxx>
 #include <Main/globals.hxx>
index dd2c6c1541deacee49cede39626b2dadac0f6750..18b8fe78b563f69781165780724cb29e0254aab8 100644 (file)
@@ -59,7 +59,7 @@
 #include <Main/globals.hxx>
 #include <Main/fg_props.hxx>
 #include <Viewer/viewmgr.hxx>
-#include <Viewer/viewer.hxx>
+#include <Viewer/view.hxx>
 #include <Time/light.hxx>
 #include <GUI/FGFontCache.hxx> 
 #include <Instrumentation/dclgps.hxx>
index 9063412558c6f377b9eb03008a18df17a0e4a925..66300afc5071a68c1a6750dd6ef7db17984063f4 100644 (file)
@@ -39,7 +39,7 @@
 #include <Main/globals.hxx>
 #include <Main/fg_props.hxx>
 #include <Viewer/viewmgr.hxx>
-#include <Viewer/viewer.hxx>
+#include <Viewer/view.hxx>
 #include <GUI/FGFontCache.hxx>
 #include <GUI/gui.h> // for guiErrorMessage
 
index 92a39f68e4791bbd57cd3b9049978b18ffd030cb..6371da41d0f7590b585f6efc012d5dcfd17c319a 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <sstream>
 #include <simgear/math/SGGeometry.hxx>
-#include <Viewer/viewer.hxx>
+#include <Viewer/view.hxx>
 
 #include "HUD.hxx"
 #include "HUD_private.hxx"
index 6fae692d10eb6ff86c9a1ff52632db57057b85f1..743e5df584ca34b4700999d3ab748d9f947ba5bb 100644 (file)
@@ -34,7 +34,7 @@
 #include <FDM/flight.hxx>
 #include <Environment/environment.hxx>
 #include <Environment/environment_mgr.hxx>
-#include <Viewer/viewer.hxx>
+#include <Viewer/view.hxx>
 #include <Viewer/viewmgr.hxx>
 #include <Airports/airport.hxx>
 
index a7a5945dc473c4e836fc09895f6e2eda0e93301b..1e93a0b7b70e6cd32a12381c525c1646e5ab3f25 100644 (file)
@@ -37,7 +37,7 @@
 #include <Airports/xmlloader.hxx>
 #include <Network/HTTPClient.hxx>
 #include <Viewer/viewmgr.hxx>
-#include <Viewer/viewer.hxx>
+#include <Viewer/view.hxx>
 #include <Environment/presets.hxx>
 #include <Navaids/NavDataCache.hxx>
 
index 97d9cc8d243926d64277b5ed15942d4191ac0e24..3c412ca6806abd738f0e970d3ef3e74ceee35da6 100644 (file)
@@ -68,7 +68,7 @@
 #include "util.hxx"
 #include "main.hxx"
 #include "locale.hxx"
-#include <Viewer/viewer.hxx>
+#include <Viewer/view.hxx>
 #include <Viewer/viewmgr.hxx>
 #include <Environment/presets.hxx>
 #include <Network/http/httpd.hxx>
index 37ef66fd08e8f5c5d91eeb6149df201d95edcb99..f17dd661af73cadce17d314d21a52bcf7b26b39d 100644 (file)
@@ -22,7 +22,7 @@
 #include <Main/fg_props.hxx>
 #include <Viewer/renderer.hxx>
 #include <Viewer/viewmgr.hxx>
-#include <Viewer/viewer.hxx>
+#include <Viewer/view.hxx>
 #include <Scenery/scenery.hxx>
 #include <Sound/fg_fx.hxx>
 
index 6399133f330e731e0285572442c276abd449bc5a..0c725d4e4a4090b9e94b5553281750c43dd9dd88 100644 (file)
@@ -25,7 +25,7 @@
 #include <Main/fg_os.hxx>
 #include <Cockpit/panel.hxx>
 #include <Cockpit/panel_io.hxx>
-#include "Viewer/viewer.hxx"
+#include "Viewer/view.hxx"
 #include "Viewer/viewmgr.hxx"
 
 using std::vector;
index c037657b0d353ecba9a17a3c41662b2881453570..8600372ce0257a092830247d036583b701b6b122 100644 (file)
@@ -43,7 +43,7 @@
 #include <Main/globals.hxx>
 #include <Main/fg_props.hxx>
 #include <Viewer/renderer.hxx>
-#include <Viewer/viewer.hxx>
+#include <Viewer/view.hxx>
 
 #include "light.hxx"
 #include "sunsolver.hxx"
index d517c72012f1a1d2f09c13f969c1a944f77b0b63..7ed0aa2ba6e16434f3e31415f67059fbe431acbf 100644 (file)
@@ -10,7 +10,7 @@ set(SOURCES
        renderer.cxx
        renderingpipeline.cxx
        splash.cxx
-       viewer.cxx
+       view.cxx
        viewmgr.cxx
        )
 
@@ -23,7 +23,7 @@ set(HEADERS
        renderer.hxx
        renderingpipeline.hxx
        splash.hxx
-       viewer.hxx
+       view.hxx
        viewmgr.hxx
        )
 
index 270ea178e62538cf23846dca35dffff74bb12272..552a880c8e36099e8c05ae80abaf3924ef588bde 100644 (file)
 #include <Environment/ephemeris.hxx>
 
 //#include <Main/main.hxx>
-#include "viewer.hxx"
+#include "view.hxx"
 #include "viewmgr.hxx"
 #include "splash.hxx"
 #include "renderer.hxx"
diff --git a/src/Viewer/view.cxx b/src/Viewer/view.cxx
new file mode 100644 (file)
index 0000000..dbdc11f
--- /dev/null
@@ -0,0 +1,1162 @@
+// view.cxx -- class for managing a view in the flightgear world.
+//
+// Written by Curtis Olson, started August 1997.
+//                          overhaul started October 2000.
+//   partially rewritten by Jim Wilson jim@kelcomaine.com using interface
+//                          by David Megginson March 2002
+//
+// Copyright (C) 1997 - 2000  Curtis L. Olson  - http://www.flightgear.org/~curt
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+// $Id$
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "view.hxx"
+
+#include <simgear/compiler.h>
+#include <cassert>
+
+#include <simgear/debug/logstream.hxx>
+#include <simgear/constants.h>
+#include <simgear/scene/model/placement.hxx>
+#include <simgear/scene/util/OsgMath.hxx>
+
+#include <Main/fg_props.hxx>
+#include <Main/globals.hxx>
+#include "CameraGroup.hxx"
+
+using namespace flightgear;
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGViewer.
+////////////////////////////////////////////////////////////////////////
+
+// Constructor...
+View::View( ViewType Type, bool from_model, int from_model_index,
+                    bool at_model, int at_model_index,
+                    double damp_roll, double damp_pitch, double damp_heading,
+                    double x_offset_m, double y_offset_m, double z_offset_m,
+                    double heading_offset_deg, double pitch_offset_deg,
+                    double roll_offset_deg,
+                    double fov_deg, double aspect_ratio_multiplier,
+                    double target_x_offset_m, double target_y_offset_m,
+                    double target_z_offset_m, double near_m, bool internal ):
+    _dirty(true),
+    _roll_deg(0),
+    _pitch_deg(0),
+    _heading_deg(0),
+    _target_roll_deg(0),
+    _target_pitch_deg(0),
+    _target_heading_deg(0),
+    _scaling_type(FG_SCALING_MAX)
+{
+    _absolute_view_pos = SGVec3d(0, 0, 0);
+    _type = Type;
+    _from_model = from_model;
+    _from_model_index = from_model_index;
+    _at_model = at_model;
+    _at_model_index = at_model_index;
+
+    _internal = internal;
+
+    _dampFactor = SGVec3d::zeros();
+    _dampOutput = SGVec3d::zeros();
+    _dampTarget = SGVec3d::zeros();
+
+    if (damp_roll > 0.0)
+      _dampFactor[0] = 1.0 / pow(10.0, fabs(damp_roll));
+    if (damp_pitch > 0.0)
+      _dampFactor[1] = 1.0 / pow(10.0, fabs(damp_pitch));
+    if (damp_heading > 0.0)
+      _dampFactor[2] = 1.0 / pow(10.0, fabs(damp_heading));
+
+    _offset_m.x() = x_offset_m;
+    _offset_m.y() = y_offset_m;
+    _offset_m.z() = z_offset_m;
+    _configOffset_m = _offset_m;
+
+    _heading_offset_deg = heading_offset_deg;
+    _pitch_offset_deg = pitch_offset_deg;
+    _roll_offset_deg = roll_offset_deg;
+    _goal_heading_offset_deg = heading_offset_deg;
+    _goal_pitch_offset_deg = pitch_offset_deg;
+    _goal_roll_offset_deg = roll_offset_deg;
+
+    _configHeadingOffsetDeg = heading_offset_deg;
+    _configPitchOffsetDeg = pitch_offset_deg;
+    _configRollOffsetDeg = roll_offset_deg;
+
+    if (fov_deg > 0) {
+      _fov_deg = fov_deg;
+    } else {
+      _fov_deg = 55;
+    }
+
+    _configFOV_deg = _fov_deg;
+
+    _aspect_ratio_multiplier = aspect_ratio_multiplier;
+    _target_offset_m.x() = target_x_offset_m;
+    _target_offset_m.y() = target_y_offset_m;
+    _target_offset_m.z() = target_z_offset_m;
+    _configTargetOffset_m = _target_offset_m;
+
+    _ground_level_nearplane_m = near_m;
+    // a reasonable guess for init, so that the math doesn't blow up
+}
+
+View* View::createFromProperties(SGPropertyNode_ptr config)
+{
+    double aspect_ratio_multiplier
+        = fgGetDouble("/sim/current-view/aspect-ratio-multiplier");
+
+    // find out if this is an internal view (e.g. in cockpit, low near plane)
+    // FIXME : should be a child of config
+    bool internal = config->getParent()->getBoolValue("internal", false);
+
+
+    // FIXME:
+    // this is assumed to be an aircraft model...we will need to read
+    // model-from-type as well.
+
+    // find out if this is a model we are looking from...
+    bool from_model = config->getBoolValue("from-model");
+    int from_model_index = config->getIntValue("from-model-idx");
+
+    double x_offset_m = config->getDoubleValue("x-offset-m");
+    double y_offset_m = config->getDoubleValue("y-offset-m");
+    double z_offset_m = config->getDoubleValue("z-offset-m");
+
+    double heading_offset_deg = config->getDoubleValue("heading-offset-deg");
+  //  config->setDoubleValue("heading-offset-deg", heading_offset_deg);
+    double pitch_offset_deg = config->getDoubleValue("pitch-offset-deg");
+  //  config->setDoubleValue("pitch-offset-deg", pitch_offset_deg);
+    double roll_offset_deg = config->getDoubleValue("roll-offset-deg");
+   // config->setDoubleValue("roll-offset-deg", roll_offset_deg);
+
+    double fov_deg = config->getDoubleValue("default-field-of-view-deg");
+    double near_m = config->getDoubleValue("ground-level-nearplane-m");
+
+    View* v = 0;
+    // supporting two types "lookat" = 1 and "lookfrom" = 0
+    const char *type = config->getParent()->getStringValue("type");
+    if (!strcmp(type, "lookat")) {
+        bool at_model = config->getBoolValue("at-model");
+        int at_model_index = config->getIntValue("at-model-idx");
+
+        double damp_roll = config->getDoubleValue("at-model-roll-damping");
+        double damp_pitch = config->getDoubleValue("at-model-pitch-damping");
+        double damp_heading = config->getDoubleValue("at-model-heading-damping");
+
+        double target_x_offset_m = config->getDoubleValue("target-x-offset-m");
+        double target_y_offset_m = config->getDoubleValue("target-y-offset-m");
+        double target_z_offset_m = config->getDoubleValue("target-z-offset-m");
+
+        v = new View ( FG_LOOKAT, from_model, from_model_index,
+                           at_model, at_model_index,
+                           damp_roll, damp_pitch, damp_heading,
+                           x_offset_m, y_offset_m,z_offset_m,
+                           heading_offset_deg, pitch_offset_deg,
+                           roll_offset_deg, fov_deg, aspect_ratio_multiplier,
+                           target_x_offset_m, target_y_offset_m,
+                         target_z_offset_m, near_m, internal );
+        if (!from_model) {
+            v->_targetProperties.init(config, "target-");
+        }
+    } else {
+        v = new View ( FG_LOOKFROM, from_model, from_model_index,
+                       false, 0, 0.0, 0.0, 0.0,
+                       x_offset_m, y_offset_m, z_offset_m,
+                       heading_offset_deg, pitch_offset_deg,
+                       roll_offset_deg, fov_deg, aspect_ratio_multiplier,
+                         0, 0, 0, near_m, internal );
+    }
+
+    if (!from_model) {
+        v->_eyeProperties.init(config, "eye-");
+    }
+
+    v->_name = config->getParent()->getStringValue("name");
+    v->_typeString = type;
+    v->_configHeadingOffsetDeg = config->getDoubleValue("default-heading-offset-deg");
+
+    return v;
+}
+
+
+// Destructor
+View::~View( void )
+{
+    _tiedProperties.Untie();
+}
+
+void
+View::init ()
+{
+}
+
+void
+View::bind ()
+{
+    _tiedProperties.setRoot(fgGetNode("/sim/current-view", true));
+    _tiedProperties.Tie("heading-offset-deg", this,
+                         &View::getHeadingOffset_deg,
+                         &View::setHeadingOffset_deg_property,
+                        false /* do not set current property value */);
+
+     fgSetArchivable("/sim/current-view/heading-offset-deg");
+
+    _tiedProperties.Tie("goal-heading-offset-deg", this,
+                        &View::getGoalHeadingOffset_deg,
+                        &View::setGoalHeadingOffset_deg,
+                        false /* do not set current property value */);
+
+    fgSetArchivable("/sim/current-view/goal-heading-offset-deg");
+
+    _tiedProperties.Tie("pitch-offset-deg", this,
+                        &View::getPitchOffset_deg,
+                        &View::setPitchOffset_deg_property,
+                        false /* do not set current property value */);
+    fgSetArchivable("/sim/current-view/pitch-offset-deg");
+    _tiedProperties.Tie("goal-pitch-offset-deg", this,
+                        &View::getGoalPitchOffset_deg,
+                        &View::setGoalPitchOffset_deg,
+                        false /* do not set current property value */);
+    fgSetArchivable("/sim/current-view/goal-pitch-offset-deg");
+    _tiedProperties.Tie("roll-offset-deg", this,
+                        &View::getRollOffset_deg,
+                        &View::setRollOffset_deg_property,
+                        false /* do not set current property value */);
+    fgSetArchivable("/sim/current-view/roll-offset-deg");
+    _tiedProperties.Tie("goal-roll-offset-deg", this,
+                        &View::getGoalRollOffset_deg,
+                        &View::setGoalRollOffset_deg,
+                        false /* do not set current property value */);
+    fgSetArchivable("/sim/current-view/goal-roll-offset-deg");
+
+
+    _tiedProperties.Tie("field-of-view", this,
+                        &View::get_fov, &View::set_fov,
+                        false);
+    fgSetArchivable("/sim/current-view/field-of-view");
+
+
+    _tiedProperties.Tie("aspect-ratio-multiplier", this,
+                        &View::get_aspect_ratio_multiplier,
+                        &View::set_aspect_ratio_multiplier,
+                        false);
+
+    _tiedProperties.Tie("ground-level-nearplane-m", this,
+                        &View::getNear_m, &View::setNear_m, false);
+    fgSetArchivable("/sim/current-view/ground-level-nearplane-m");
+
+
+    _tiedProperties.Tie("viewer-lon-deg", this, &View::getLon_deg);
+    _tiedProperties.Tie("viewer-lat-deg", this, &View::getLat_deg);
+    _tiedProperties.Tie("viewer-elev-ft", this, &View::getElev_ft);
+
+    _tiedProperties.Tie("x-offset-m", this, &View::getXOffset_m,
+                        &View::setXOffset_m, false);
+    _tiedProperties.Tie("y-offset-m", this, &View::getYOffset_m,
+                        &View::setYOffset_m, false);
+    _tiedProperties.Tie("z-offset-m", this, &View::getZOffset_m,
+                        &View::setZOffset_m, false);
+
+    _tiedProperties.Tie("target-x-offset-m", this, &View::getTargetXOffset_m,
+                        &View::setTargetXOffset_m, false);
+    _tiedProperties.Tie("target-y-offset-m", this, &View::getTargetYOffset_m,
+                        &View::setTargetYOffset_m, false);
+    _tiedProperties.Tie("target-z-offset-m", this, &View::getTargetZOffset_m,
+                        &View::setTargetZOffset_m, false);
+
+// expose various quaternions under the debug/ subtree
+    _tiedProperties.Tie("debug/orientation-w", this, &View::getOrientation_w);
+    _tiedProperties.Tie("debug/orientation-x", this, &View::getOrientation_x);
+    _tiedProperties.Tie("debug/orientation-y", this, &View::getOrientation_y);
+    _tiedProperties.Tie("debug/orientation-z", this, &View::getOrientation_z);
+
+    _tiedProperties.Tie("debug/orientation_offset-w", this,
+                        &View::getOrOffset_w);
+    _tiedProperties.Tie("debug/orientation_offset-x", this,
+                        &View::getOrOffset_x);
+    _tiedProperties.Tie("debug/orientation_offset-y", this,
+                        &View::getOrOffset_y);
+    _tiedProperties.Tie("debug/orientation_offset-z", this,
+                        &View::getOrOffset_z);
+
+    _tiedProperties.Tie("debug/frame-w", this, &View::getFrame_w);
+    _tiedProperties.Tie("debug/frame-x", this, &View::getFrame_x);
+    _tiedProperties.Tie("debug/frame-y", this, &View::getFrame_y);
+    _tiedProperties.Tie("debug/frame-z", this, &View::getFrame_z);
+
+
+// expose the raw (OpenGL) orientation to the property tree,
+// for the sound-manager
+    _tiedProperties.Tie("raw-orientation", 0, this, &View::getRawOrientation_w);
+    _tiedProperties.Tie("raw-orientation", 1, this, &View::getRawOrientation_x);
+    _tiedProperties.Tie("raw-orientation", 2, this, &View::getRawOrientation_y);
+    _tiedProperties.Tie("raw-orientation", 3, this, &View::getRawOrientation_z);
+
+    _tiedProperties.Tie("viewer-x-m", this, &View::getAbsolutePosition_x);
+    _tiedProperties.Tie("viewer-y-m", this, &View::getAbsolutePosition_y);
+    _tiedProperties.Tie("viewer-z-m", this, &View::getAbsolutePosition_z);
+
+// following config properties are exposed on current-view but don't change,
+// so we can simply copy them here.
+    _tiedProperties.getRoot()->setStringValue("name", _name);
+    _tiedProperties.getRoot()->setStringValue("type", _typeString);
+    _tiedProperties.getRoot()->setBoolValue("internal", _internal);
+
+    SGPropertyNode_ptr config = _tiedProperties.getRoot()->getChild("config", 0, true);
+    config->setBoolValue("from-model", _from_model);
+    config->setDoubleValue("heading-offset-deg", _configHeadingOffsetDeg);
+    config->setDoubleValue("pitch-offset-deg", _configPitchOffsetDeg);
+    config->setDoubleValue("roll-offset-deg", _configRollOffsetDeg);
+    config->setDoubleValue("default-field-of-view-deg", _configFOV_deg);
+}
+
+void
+View::unbind ()
+{
+    _tiedProperties.Untie();
+}
+
+void View::resetOffsetsAndFOV()
+{
+    _target_offset_m = _configTargetOffset_m;
+    _offset_m = _configOffset_m;
+    _pitch_offset_deg = _configPitchOffsetDeg;
+    _heading_offset_deg = _configHeadingOffsetDeg;
+    _roll_offset_deg = _configRollOffsetDeg;
+    _fov_deg = _configFOV_deg;
+}
+
+void
+View::setType ( int type )
+{
+  if (type == 0)
+    _type = FG_LOOKFROM;
+  if (type == 1)
+    _type = FG_LOOKAT;
+}
+
+void
+View::setInternal ( bool internal )
+{
+  _internal = internal;
+}
+
+void
+View::setPosition (const SGGeod& geod)
+{
+  _dirty = true;
+    _position = geod;
+}
+
+void
+View::setTargetPosition (const SGGeod& geod)
+{
+  _dirty = true;
+    _target = geod;
+}
+
+void
+View::setRoll_deg (double roll_deg)
+{
+  _dirty = true;
+  _roll_deg = roll_deg;
+}
+
+void
+View::setPitch_deg (double pitch_deg)
+{
+  _dirty = true;
+  _pitch_deg = pitch_deg;
+}
+
+void
+View::setHeading_deg (double heading_deg)
+{
+  _dirty = true;
+  _heading_deg = heading_deg;
+}
+
+void
+View::setOrientation (double roll_deg, double pitch_deg, double heading_deg)
+{
+  _dirty = true;
+  _roll_deg = roll_deg;
+  _pitch_deg = pitch_deg;
+  _heading_deg = heading_deg;
+}
+
+void
+View::setTargetRoll_deg (double target_roll_deg)
+{
+  _dirty = true;
+  _target_roll_deg = target_roll_deg;
+}
+
+void
+View::setTargetPitch_deg (double target_pitch_deg)
+{
+  _dirty = true;
+  _target_pitch_deg = target_pitch_deg;
+}
+
+void
+View::setTargetHeading_deg (double target_heading_deg)
+{
+  _dirty = true;
+  _target_heading_deg = target_heading_deg;
+}
+
+void
+View::setTargetOrientation (double target_roll_deg, double target_pitch_deg, double target_heading_deg)
+{
+  _dirty = true;
+  _target_roll_deg = target_roll_deg;
+  _target_pitch_deg = target_pitch_deg;
+  _target_heading_deg = target_heading_deg;
+}
+
+void
+View::setXOffset_m (double x_offset_m)
+{
+  _dirty = true;
+  _offset_m.x() = x_offset_m;
+}
+
+void
+View::setYOffset_m (double y_offset_m)
+{
+  _dirty = true;
+  _offset_m.y() = y_offset_m;
+}
+
+void
+View::setZOffset_m (double z_offset_m)
+{
+  _dirty = true;
+  _offset_m.z() = z_offset_m;
+}
+
+void
+View::setTargetXOffset_m (double target_x_offset_m)
+{
+  _dirty = true;
+  _target_offset_m.x() = target_x_offset_m;
+}
+
+void
+View::setTargetYOffset_m (double target_y_offset_m)
+{
+  _dirty = true;
+  _target_offset_m.y() = target_y_offset_m;
+}
+
+void
+View::setTargetZOffset_m (double target_z_offset_m)
+{
+  _dirty = true;
+  _target_offset_m.z() = target_z_offset_m;
+}
+
+void
+View::setPositionOffsets (double x_offset_m, double y_offset_m, double z_offset_m)
+{
+  _dirty = true;
+  _offset_m.x() = x_offset_m;
+  _offset_m.y() = y_offset_m;
+  _offset_m.z() = z_offset_m;
+}
+
+void
+View::setRollOffset_deg (double roll_offset_deg)
+{
+  _dirty = true;
+  _roll_offset_deg = roll_offset_deg;
+}
+
+void
+View::setPitchOffset_deg (double pitch_offset_deg)
+{
+  _dirty = true;
+  _pitch_offset_deg = pitch_offset_deg;
+}
+
+void
+View::setHeadingOffset_deg (double heading_offset_deg)
+{
+  _dirty = true;
+  if (_at_model && (_offset_m.x() == 0.0)&&(_offset_m.z() == 0.0))
+  {
+      /* avoid optical effects (e.g. rotating sky) when "looking at" with
+       * heading offsets x==z==0 (view heading cannot change). */
+      _heading_offset_deg = 0.0;
+  }
+  else
+      _heading_offset_deg = heading_offset_deg;
+}
+
+void
+View::setHeadingOffset_deg_property (double heading_offset_deg)
+{
+    setHeadingOffset_deg(heading_offset_deg);
+    setGoalHeadingOffset_deg(heading_offset_deg);
+}
+
+void
+View::setPitchOffset_deg_property (double pitch_offset_deg)
+{
+    setPitchOffset_deg(pitch_offset_deg);
+    setGoalPitchOffset_deg(pitch_offset_deg);
+}
+
+void
+View::setRollOffset_deg_property (double roll_offset_deg)
+{
+    setRollOffset_deg(roll_offset_deg);
+    setGoalRollOffset_deg(roll_offset_deg);
+}
+
+void
+View::setGoalRollOffset_deg (double goal_roll_offset_deg)
+{
+  _dirty = true;
+  _goal_roll_offset_deg = goal_roll_offset_deg;
+}
+
+void
+View::setGoalPitchOffset_deg (double goal_pitch_offset_deg)
+{
+  _dirty = true;
+  _goal_pitch_offset_deg = goal_pitch_offset_deg;
+  /* The angle is set to 1/1000th of a degree from the poles to avoid the
+   * singularity where the azimuthal angle becomes undefined, inducing optical
+   * artefacts.  The arbitrary angle offset is visually unnoticeable while
+   * avoiding any possible floating point truncation artefacts. */
+  if ( _goal_pitch_offset_deg < -89.999 ) {
+    _goal_pitch_offset_deg = -89.999;
+  }
+  if ( _goal_pitch_offset_deg > 89.999 ) {
+    _goal_pitch_offset_deg = 89.999;
+  }
+
+}
+
+void
+View::setGoalHeadingOffset_deg (double goal_heading_offset_deg)
+{
+  _dirty = true;
+  if (_at_model && (_offset_m.x() == 0.0)&&(_offset_m.z() == 0.0))
+  {
+      /* avoid optical effects (e.g. rotating sky) when "looking at" with
+       * heading offsets x==z==0 (view heading cannot change). */
+      _goal_heading_offset_deg = 0.0;
+      return;
+  }
+
+  _goal_heading_offset_deg = goal_heading_offset_deg;
+  while ( _goal_heading_offset_deg < 0.0 ) {
+    _goal_heading_offset_deg += 360;
+  }
+  while ( _goal_heading_offset_deg > 360 ) {
+    _goal_heading_offset_deg -= 360;
+  }
+}
+
+void
+View::setOrientationOffsets (double roll_offset_deg, double pitch_offset_deg, double heading_offset_deg)
+{
+  _dirty = true;
+  _roll_offset_deg = roll_offset_deg;
+  _pitch_offset_deg = pitch_offset_deg;
+  _heading_offset_deg = heading_offset_deg;
+}
+
+// recalc() is done every time one of the setters is called (making the
+// cached data "dirty") on the next "get".  It calculates all the outputs
+// for viewer.
+void
+View::recalc ()
+{
+  if (_type == FG_LOOKFROM) {
+    recalcLookFrom();
+  } else {
+    recalcLookAt();
+  }
+
+  set_clean();
+}
+
+// recalculate for LookFrom view type...
+void
+View::recalcLookFrom ()
+{
+  // Update location data ...
+  if ( _from_model ) {
+    _position = globals->get_aircraft_position();
+    globals->get_aircraft_orientation(_heading_deg, _pitch_deg, _roll_deg);
+  }
+
+  double head = _heading_deg;
+  double pitch = _pitch_deg;
+  double roll = _roll_deg;
+  if ( !_from_model ) {
+    // update from our own data...
+    setDampTarget(roll, pitch, head);
+    getDampOutput(roll, pitch, head);
+  }
+
+  // The rotation rotating from the earth centerd frame to
+  // the horizontal local frame
+  SGQuatd hlOr = SGQuatd::fromLonLat(_position);
+
+  // The rotation from the horizontal local frame to the basic view orientation
+  SGQuatd hlToBody = SGQuatd::fromYawPitchRollDeg(head, pitch, roll);
+
+  // The rotation offset, don't know why heading is negative here ...
+  mViewOffsetOr
+      = SGQuatd::fromYawPitchRollDeg(-_heading_offset_deg, _pitch_offset_deg,
+                                     _roll_offset_deg);
+
+  // Compute the eyepoints orientation and position
+  // wrt the earth centered frame - that is global coorinates
+  SGQuatd ec2body = hlOr*hlToBody;
+
+  // The cartesian position of the basic view coordinate
+  SGVec3d position = SGVec3d::fromGeod(_position);
+
+  // This is rotates the x-forward, y-right, z-down coordinate system the where
+  // simulation runs into the OpenGL camera system with x-right, y-up, z-back.
+  SGQuatd q(-0.5, -0.5, 0.5, 0.5);
+
+  _absolute_view_pos = position + (ec2body*q).backTransform(_offset_m);
+  mViewOrientation = ec2body*mViewOffsetOr*q;
+}
+
+void
+View::recalcLookAt ()
+{
+  // The geodetic position of our target to look at
+  if ( _at_model ) {
+    _target = globals->get_aircraft_position();
+    globals->get_aircraft_orientation(_target_heading_deg,
+                                      _target_pitch_deg,
+                                      _target_roll_deg);
+  } else {
+    // if not model then calculate our own target position...
+    setDampTarget(_target_roll_deg, _target_pitch_deg, _target_heading_deg);
+    getDampOutput(_target_roll_deg, _target_pitch_deg, _target_heading_deg);
+  }
+
+  SGQuatd geodTargetOr = SGQuatd::fromYawPitchRollDeg(_target_heading_deg,
+                                                   _target_pitch_deg,
+                                                   _target_roll_deg);
+  SGQuatd geodTargetHlOr = SGQuatd::fromLonLat(_target);
+
+
+  if ( _from_model ) {
+    _position = globals->get_aircraft_position();
+    globals->get_aircraft_orientation(_heading_deg, _pitch_deg, _roll_deg);
+  } else {
+    // update from our own data, just the rotation here...
+    setDampTarget(_roll_deg, _pitch_deg, _heading_deg);
+    getDampOutput(_roll_deg, _pitch_deg, _heading_deg);
+  }
+  SGQuatd geodEyeOr = SGQuatd::fromYawPitchRollDeg(_heading_deg, _pitch_deg, _roll_deg);
+  SGQuatd geodEyeHlOr = SGQuatd::fromLonLat(_position);
+
+  // the rotation offset, don't know why heading is negative here ...
+  mViewOffsetOr =
+    SGQuatd::fromYawPitchRollDeg(-_heading_offset_deg + 180, _pitch_offset_deg,
+                                 _roll_offset_deg);
+
+  // Offsets to the eye position
+  SGVec3d eyeOff(-_offset_m.z(), _offset_m.x(), -_offset_m.y());
+  SGQuatd ec2eye = geodEyeHlOr*geodEyeOr;
+  SGVec3d eyeCart = SGVec3d::fromGeod(_position);
+  eyeCart += (ec2eye*mViewOffsetOr).backTransform(eyeOff);
+
+  SGVec3d atCart = SGVec3d::fromGeod(_target);
+
+  // add target offsets to at_position...
+  SGVec3d target_pos_off(-_target_offset_m.z(), _target_offset_m.x(),
+                         -_target_offset_m.y());
+  target_pos_off = (geodTargetHlOr*geodTargetOr).backTransform(target_pos_off);
+  atCart += target_pos_off;
+  eyeCart += target_pos_off;
+
+  // Compute the eyepoints orientation and position
+  // wrt the earth centered frame - that is global coorinates
+  _absolute_view_pos = eyeCart;
+
+  // the view direction
+  SGVec3d dir = normalize(atCart - eyeCart);
+  // the up directon
+  SGVec3d up = ec2eye.backTransform(SGVec3d(0, 0, -1));
+  // rotate -dir to the 2-th unit vector
+  // rotate up to 1-th unit vector
+  // Note that this matches the OpenGL camera coordinate system
+  // with x-right, y-up, z-back.
+  mViewOrientation = SGQuatd::fromRotateTo(-dir, 2, up, 1);
+}
+
+void
+View::setDampTarget(double roll, double pitch, double heading)
+{
+  _dampTarget = SGVec3d(roll, pitch, heading);
+}
+
+void
+View::getDampOutput(double& roll, double& pitch, double& heading)
+{
+  roll = _dampOutput[0];
+  pitch = _dampOutput[1];
+  heading = _dampOutput[2];
+}
+
+
+void
+View::updateDampOutput(double dt)
+{
+  static View *last_view = 0;
+  if ((last_view != this) || (dt > 1.0)) {
+    _dampOutput = _dampTarget;
+    last_view = this;
+    return;
+  }
+
+  const double interval = 0.01;
+  while (dt > interval) {
+
+    for (unsigned int i=0; i<3; ++i) {
+      if (_dampFactor[i] <= 0.0) {
+        // axis is un-damped, set output to target directly
+        _dampOutput[i] = _dampTarget[i];
+        continue;
+      }
+
+      double d = _dampOutput[i] - _dampTarget[i];
+      if (d > 180.0) {
+        _dampOutput[i] -= 360.0;
+      } else if (d < -180.0) {
+        _dampOutput[i] += 360.0;
+      }
+
+      _dampOutput[i] = (_dampTarget[i] * _dampFactor[i]) +
+        (_dampOutput[i] * (1.0 - _dampFactor[i]));
+    } // of axis iteration
+
+    dt -= interval;
+  } // of dt subdivision by interval
+}
+
+double
+View::get_h_fov()
+{
+    double aspectRatio = get_aspect_ratio();
+    switch (_scaling_type) {
+    case FG_SCALING_WIDTH:  // h_fov == fov
+       return _fov_deg;
+    case FG_SCALING_MAX:
+       if (aspectRatio < 1.0) {
+           // h_fov == fov
+           return _fov_deg;
+       } else {
+           // v_fov == fov
+           return
+                atan(tan(_fov_deg/2 * SG_DEGREES_TO_RADIANS)
+                     / (aspectRatio*_aspect_ratio_multiplier))
+                * SG_RADIANS_TO_DEGREES * 2;
+       }
+    default:
+       assert(false);
+    }
+    return 0.0;
+}
+
+
+
+double
+View::get_v_fov()
+{
+    double aspectRatio = get_aspect_ratio();
+    switch (_scaling_type) {
+    case FG_SCALING_WIDTH:  // h_fov == fov
+       return
+            atan(tan(_fov_deg/2 * SG_DEGREES_TO_RADIANS)
+                 * (aspectRatio*_aspect_ratio_multiplier))
+            * SG_RADIANS_TO_DEGREES * 2;
+    case FG_SCALING_MAX:
+       if (aspectRatio < 1.0) {
+           // h_fov == fov
+           return
+                atan(tan(_fov_deg/2 * SG_DEGREES_TO_RADIANS)
+                     * (aspectRatio*_aspect_ratio_multiplier))
+                * SG_RADIANS_TO_DEGREES * 2;
+       } else {
+           // v_fov == fov
+           return _fov_deg;
+       }
+    default:
+       assert(false);
+    }
+    return 0.0;
+}
+
+void
+View::updateData()
+{
+    if (!_from_model) {
+        SGGeod pos = _eyeProperties.position();
+        SGVec3d att = _eyeProperties.attitude();
+        setPosition(pos);
+        setOrientation(att[2], att[1], att[0]);
+    } else {
+        set_dirty();
+    }
+
+    // if lookat (type 1) then get target data...
+    if (getType() == FG_LOOKAT) {
+        if (!_from_model) {
+            SGGeod pos = _targetProperties.position();
+            SGVec3d att = _targetProperties.attitude();
+            setTargetPosition(pos);
+            setTargetOrientation(att[2], att[1], att[0]);
+        } else {
+            set_dirty();
+        }
+    }
+}
+
+void
+View::update (double dt)
+{
+    updateData();
+  updateDampOutput(dt);
+
+  int i;
+  int dt_ms = int(dt * 1000);
+  for ( i = 0; i < dt_ms; i++ ) {
+    if ( fabs( _goal_heading_offset_deg - _heading_offset_deg) < 1 ) {
+      setHeadingOffset_deg( _goal_heading_offset_deg );
+      break;
+    } else {
+      // move current_view.headingoffset towards
+      // current_view.goal_view_offset
+      if ( _goal_heading_offset_deg > _heading_offset_deg )
+       {
+         if ( _goal_heading_offset_deg - _heading_offset_deg < 180 ){
+           incHeadingOffset_deg( 0.5 );
+         } else {
+           incHeadingOffset_deg( -0.5 );
+         }
+       } else {
+         if ( _heading_offset_deg - _goal_heading_offset_deg < 180 ){
+           incHeadingOffset_deg( -0.5 );
+         } else {
+           incHeadingOffset_deg( 0.5 );
+         }
+       }
+      if ( _heading_offset_deg > 360 ) {
+       incHeadingOffset_deg( -360 );
+      } else if ( _heading_offset_deg < 0 ) {
+       incHeadingOffset_deg( 360 );
+      }
+    }
+  }
+
+  for ( i = 0; i < dt_ms; i++ ) {
+    if ( fabs( _goal_pitch_offset_deg - _pitch_offset_deg ) < 1 ) {
+      setPitchOffset_deg( _goal_pitch_offset_deg );
+      break;
+    } else {
+      // move current_view.pitch_offset_deg towards
+      // current_view.goal_pitch_offset
+      if ( _goal_pitch_offset_deg > _pitch_offset_deg )
+       {
+         incPitchOffset_deg( 1.0 );
+       } else {
+           incPitchOffset_deg( -1.0 );
+       }
+      if ( _pitch_offset_deg > 90 ) {
+       setPitchOffset_deg(90);
+      } else if ( _pitch_offset_deg < -90 ) {
+       setPitchOffset_deg( -90 );
+      }
+    }
+  }
+
+
+  for ( i = 0; i < dt_ms; i++ ) {
+    if ( fabs( _goal_roll_offset_deg - _roll_offset_deg ) < 1 ) {
+      setRollOffset_deg( _goal_roll_offset_deg );
+      break;
+    } else {
+      // move current_view.roll_offset_deg towards
+      // current_view.goal_roll_offset
+      if ( _goal_roll_offset_deg > _roll_offset_deg )
+       {
+         incRollOffset_deg( 1.0 );
+       } else {
+           incRollOffset_deg( -1.0 );
+       }
+      if ( _roll_offset_deg > 90 ) {
+       setRollOffset_deg(90);
+      } else if ( _roll_offset_deg < -90 ) {
+       setRollOffset_deg( -90 );
+      }
+    }
+  }
+  recalc();
+}
+
+double View::getAbsolutePosition_x() const
+{
+    return _absolute_view_pos.x();
+}
+
+double View::getAbsolutePosition_y() const
+{
+    return _absolute_view_pos.y();
+}
+
+double View::getAbsolutePosition_z() const
+{
+    return _absolute_view_pos.z();
+}
+
+double View::getRawOrientation_w() const
+{
+    return mViewOrientation.w();
+}
+
+double View::getRawOrientation_x() const
+{
+    return mViewOrientation.x();
+}
+
+double View::getRawOrientation_y() const
+{
+    return mViewOrientation.y();
+}
+
+double View::getRawOrientation_z() const
+{
+    return mViewOrientation.z();
+}
+
+// This takes the conventional aviation XYZ body system
+// i.e.  x=forward, y=starboard, z=bottom
+// which is widely used in FGFS
+// and rotates it into the OpenGL camera system
+// i.e. Xprime=starboard, Yprime=top, Zprime=aft.
+static const SGQuatd fsb2sta()
+{
+    return SGQuatd(-0.5, -0.5, 0.5, 0.5);
+}
+
+// reference frame orientation.
+// This is the view orientation you get when you have no
+// view offset, i.e. the offset operator is the identity.
+//
+// For example, in the familiar "cockpit lookfrom" view,
+// the reference frame is equal to the aircraft attitude,
+// i.e. it is the view looking towards 12:00 straight ahead.
+//
+// FIXME:  Somebody needs to figure out what is the reference
+// frame view for the other view modes.
+//
+// Conceptually, this quat represents a rotation relative
+// to the ECEF reference orientation, as described at
+//    http://www.av8n.com/physics/coords.htm#sec-orientation
+//
+// See the NOTE concerning reference orientations, below.
+//
+// The components of this quat are expressed in
+// the conventional aviation basis set,
+// i.e.  x=forward, y=starboard, z=bottom
+double View::getFrame_w() const
+{
+    return ((mViewOrientation*conj(fsb2sta())*conj(mViewOffsetOr))).w();
+}
+
+double View::getFrame_x() const
+{
+    return ((mViewOrientation*conj(fsb2sta())*conj(mViewOffsetOr))).x();
+}
+
+double View::getFrame_y() const
+{
+    return ((mViewOrientation*conj(fsb2sta())*conj(mViewOffsetOr))).y();
+}
+
+double View::getFrame_z() const
+{
+    return ((mViewOrientation*conj(fsb2sta())*conj(mViewOffsetOr))).z();
+}
+
+
+// view offset.
+// This rotation takes you from the aforementioned
+// reference frame view orientation to whatever
+// actual current view orientation is.
+//
+// The components of this quaternion are expressed in
+// the conventional aviation basis set,
+// i.e.  x=forward, y=starboard, z=bottom
+double View::getOrOffset_w() const{
+    return mViewOffsetOr.w();
+}
+double View::getOrOffset_x() const{
+    return mViewOffsetOr.x();
+}
+double View::getOrOffset_y() const{
+    return mViewOffsetOr.y();
+}
+double View::getOrOffset_z() const{
+    return mViewOffsetOr.z();
+}
+
+
+// current view orientation.
+// This is a rotation relative to the earth-centered (ec)
+// reference frame.
+//
+// NOTE: Here we remove a factor of fsb2sta so that
+// the components of this quat are displayed using the
+// conventional ECEF basis set.  This is *not* the way
+// the view orientation is stored in the views[] array,
+// but is easier for non-graphics hackers to understand.
+// If we did not remove this factor of fsb2sta here and
+// in getCurrentViewFrame, that would be equivalent to
+// the following peculiar reference orientation:
+// Suppose you are over the Gulf of Guinea, at (lat,lon) = (0,0).
+// Then the reference frame orientation can be achieved via:
+//    -- The aircraft X-axis (nose) headed south.
+//    -- The aircraft Y-axis (starboard wingtip) pointing up.
+//    -- The aircraft Z-axis (belly) pointing west.
+// To say the same thing in other words, and perhaps more to the
+// point:  If we use the OpenGL camera orientation conventions,
+// i.e. Xprime=starboard, Yprime=top, Zprime=aft, then the
+// aforementioned peculiar reference orientation at (lat,lon)
+//  = (0,0) can be described as:
+//    -- aircraft Xprime axis (starboard) pointed up
+//    -- aircraft Yprime axis (top) pointed east
+//    -- aircraft Zprime axis (aft) pointed north
+// meaning the OpenGL axes are aligned with the ECEF axes.
+double View::getOrientation_w() const{
+    return (mViewOrientation * conj(fsb2sta())).w();
+}
+double View::getOrientation_x() const{
+    return (mViewOrientation * conj(fsb2sta())).x();
+}
+double View::getOrientation_y() const{
+    return (mViewOrientation * conj(fsb2sta())).y();
+}
+double View::getOrientation_z() const{
+    return (mViewOrientation * conj(fsb2sta())).z();
+}
+
+double View::get_aspect_ratio() const
+{
+    return flightgear::CameraGroup::getDefault()->getMasterAspectRatio();
+}
+
+double View::getLon_deg() const
+{
+    return _position.getLongitudeDeg();
+}
+
+double View::getLat_deg() const
+{
+    return _position.getLatitudeDeg();
+}
+
+double View::getElev_ft() const
+{
+    return _position.getElevationFt();
+}
+
+View::PositionAttitudeProperties::PositionAttitudeProperties()
+{
+}
+
+View::PositionAttitudeProperties::~PositionAttitudeProperties()
+{
+}
+
+void View::PositionAttitudeProperties::init(SGPropertyNode_ptr parent, const std::string& prefix)
+{
+    _lonPathProp = parent->getNode(prefix + "lon-deg-path", true);
+    _latPathProp = parent->getNode(prefix + "lat-deg-path", true);
+    _altPathProp = parent->getNode(prefix + "alt-ft-path", true);
+    _headingPathProp = parent->getNode(prefix + "heading-deg-path", true);
+    _pitchPathProp = parent->getNode(prefix + "pitch-deg-path", true);
+    _rollPathProp = parent->getNode(prefix + "roll-deg-path", true);
+
+    // update the real properties now
+    valueChanged(NULL);
+
+    _lonPathProp->addChangeListener(this);
+    _latPathProp->addChangeListener(this);
+    _altPathProp->addChangeListener(this);
+    _headingPathProp->addChangeListener(this);
+    _pitchPathProp->addChangeListener(this);
+    _rollPathProp->addChangeListener(this);
+}
+
+void View::PositionAttitudeProperties::valueChanged(SGPropertyNode* node)
+{
+    _lonProp = resolvePathProperty(_lonPathProp);
+    _latProp = resolvePathProperty(_latPathProp);
+    _altProp = resolvePathProperty(_altPathProp);
+    _headingProp = resolvePathProperty(_headingPathProp);
+    _pitchProp = resolvePathProperty(_pitchPathProp);
+    _rollProp = resolvePathProperty(_rollPathProp);
+}
+
+SGPropertyNode_ptr View::PositionAttitudeProperties::resolvePathProperty(SGPropertyNode_ptr p)
+{
+    if (!p)
+        return SGPropertyNode_ptr();
+
+    std::string path = p->getStringValue();
+    if (path.empty())
+        return SGPropertyNode_ptr();
+
+    return fgGetNode(path, true);
+}
+
+SGGeod View::PositionAttitudeProperties::position() const
+{
+    double lon = _lonProp ? _lonProp->getDoubleValue() : 0.0;
+    double lat = _latProp ? _latProp->getDoubleValue() : 0.0;
+    double alt = _altProp ? _altProp->getDoubleValue() : 0.0;
+    return SGGeod::fromDegFt(lon, lat, alt);
+}
+
+SGVec3d View::PositionAttitudeProperties::attitude() const
+{
+    double heading = _headingProp ? _headingProp->getDoubleValue() : 0.0;
+    double pitch = _pitchProp ? _pitchProp->getDoubleValue() : 0.0;
+    double roll = _rollProp ? _rollProp->getDoubleValue() : 0.0;
+    return SGVec3d(heading, pitch, roll);
+}
diff --git a/src/Viewer/view.hxx b/src/Viewer/view.hxx
new file mode 100644 (file)
index 0000000..773909b
--- /dev/null
@@ -0,0 +1,453 @@
+// view.hxx -- class for managing a view in the flightgear world.
+//
+// Written by Curtis Olson, started August 1997.
+//                          overhaul started October 2000.
+//   partially rewritten by Jim Wilson jim@kelcomaine.com using interface
+//                          by David Megginson March 2002
+//
+// Copyright (C) 1997 - 2000  Curtis L. Olson  - http://www.flightgear.org/~curt
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+// $Id$
+
+
+#ifndef _VIEWER_HXX
+#define _VIEWER_HXX                                
+
+
+#include <simgear/compiler.h>
+#include <simgear/constants.h>
+
+#include <simgear/props/props.hxx>
+#include <simgear/props/tiedpropertylist.hxx>
+#include <simgear/structure/subsystem_mgr.hxx>
+#include <simgear/math/SGMath.hxx>
+
+#define FG_FOV_MIN 0.1
+#define FG_FOV_MAX 179.9
+
+namespace flightgear
+{
+
+// Define a structure containing view information
+class View : public SGSubsystem {
+
+public:
+
+    enum ScalingType {  // nominal Field Of View actually applies to ...
+       FG_SCALING_WIDTH,       // window width
+       FG_SCALING_MAX          // max(width, height)
+       // FG_SCALING_G_MEAN,      // geometric_mean(width, height)
+       // FG_SCALING_INDEPENDENT  // whole screen
+    };
+
+    enum ViewType {
+        FG_LOOKFROM = 0,
+        FG_LOOKAT = 1
+    };
+
+    static View* createFromProperties(SGPropertyNode_ptr props);
+
+    // Destructor
+    virtual ~View();
+
+    //////////////////////////////////////////////////////////////////////
+    // Part 1: standard SGSubsystem implementation.
+    //////////////////////////////////////////////////////////////////////
+
+    virtual void init ();
+    virtual void bind ();
+    virtual void unbind ();
+    virtual void update (double dt);
+
+
+    //////////////////////////////////////////////////////////////////////
+    // Part 2: user settings.
+    //////////////////////////////////////////////////////////////////////
+
+    void resetOffsetsAndFOV();
+
+    ViewType getType() const { return _type; }
+    void setType( int type );
+
+    bool getInternal() const { return _internal; }
+    void setInternal( bool internal );
+
+    // Reference geodetic position of view from position...
+    //   These are the actual aircraft position (pilot in
+    //   pilot view, model in model view).
+    //   FIXME: the model view position (ie target positions) 
+    //   should be in the model class.
+
+
+    const SGGeod& getPosition() const { return _position; }
+
+    // Reference geodetic target position...
+    const SGGeod& getTargetPosition() const { return _target; }
+
+
+
+    // Position offsets from reference
+    //   These offsets position they "eye" in the scene according to a given
+    //   location.  For example in pilot view they are used to position the 
+    //   head inside the aircraft.
+    //   Note that in pilot view these are applied "before" the orientation 
+    //   rotations (see below) so that the orientation rotations have the 
+    //   effect of the pilot staying in his seat and "looking out" in 
+    //   different directions.
+    //   In chase view these are applied "after" the application of the 
+    //   orientation rotations listed below.  This has the effect of the 
+    //   eye moving around and "looking at" the object (model) from 
+    //   different angles.
+    SGVec3d getOffset_m () const { return _offset_m; }
+    double getXOffset_m () const { return _offset_m.x(); }
+    double getYOffset_m () const { return _offset_m.y(); }
+    double getZOffset_m () const { return _offset_m.z(); }
+    double getTargetXOffset_m () const { return _target_offset_m.x(); }
+    double getTargetYOffset_m () const { return _target_offset_m.y(); }
+    double getTargetZOffset_m () const { return _target_offset_m.z(); }
+    void setXOffset_m (double x_offset_m);
+    void setYOffset_m (double y_offset_m);
+    void setZOffset_m (double z_offset_m);
+    void setTargetXOffset_m (double x_offset_m);
+    void setTargetYOffset_m (double y_offset_m);
+    void setTargetZOffset_m (double z_offset_m);
+    void setPositionOffsets (double x_offset_m,
+                                    double y_offset_m,
+                                    double z_offset_m);
+
+    // Reference orientation rotations...
+    //   These are rotations that represent the plane attitude effect on
+    //   the view (in Pilot view).  IE The view frustrum rotates as the plane
+    //   turns, pitches, and rolls.
+    //   In model view (lookat/chaseview) these end up changing the angle that
+    //   the eye is looking at the ojbect (ie the model).
+    //   FIXME: the FGModel class should have its own version of these so that
+    //   it can generate it's own model rotations.
+    double getHeading_deg () const {return _heading_deg; }
+
+
+    // Orientation offsets rotations from reference orientation.
+    // Goal settings are for smooth transition from prior
+    // offset when changing view direction.
+    //   These offsets are in ADDITION to the orientation rotations listed
+    //   above.
+    //   In pilot view they are applied after the position offsets in order to
+    //   give the effect of the pilot looking around.
+    //   In lookat view they are applied before the position offsets so that
+    //   the effect is the eye moving around looking at the object (ie the model)
+    //   from different angles.
+    double getRollOffset_deg () const { return _roll_offset_deg; }
+    double getPitchOffset_deg () const { return _pitch_offset_deg; }
+    double getHeadingOffset_deg () const { return _heading_offset_deg; }
+
+    void setGoalHeadingOffset_deg (double goal_heading_offset_deg);
+    void setHeadingOffset_deg (double heading_offset_deg);
+
+    //////////////////////////////////////////////////////////////////////
+    // Part 3: output vectors and matrices in FlightGear coordinates.
+    //////////////////////////////////////////////////////////////////////
+
+    // Vectors and positions...
+
+    const SGVec3d& get_view_pos() { if ( _dirty ) { recalc(); } return _absolute_view_pos; }
+    const SGVec3d& getViewPosition() { if ( _dirty ) { recalc(); } return _absolute_view_pos; }
+    const SGQuatd& getViewOrientation() { if ( _dirty ) { recalc(); } return mViewOrientation; }
+    const SGQuatd& getViewOrientationOffset() { if ( _dirty ) { recalc(); } return mViewOffsetOr; }
+
+    //////////////////////////////////////////////////////////////////////
+    // Part 4: View and frustrum data setters and getters
+    //////////////////////////////////////////////////////////////////////
+
+    double get_fov() const { return _fov_deg; }
+    double get_h_fov();    // Get horizontal fov, in degrees.
+    double get_v_fov();    // Get vertical fov, in degrees.
+
+    // this is currently just a wrapper for the default CameraGroups' aspect
+    double get_aspect_ratio() const;
+
+    //////////////////////////////////////////////////////////////////////
+    // Part 5: misc setters and getters
+    //////////////////////////////////////////////////////////////////////
+
+    void set_dirty() { _dirty = true; }
+
+private:
+
+    // Constructor
+    View( ViewType Type, bool from_model, int from_model_index,
+         bool at_model, int at_model_index,
+         double damp_roll, double damp_pitch, double damp_heading,
+         double x_offset_m, double y_offset_m, double z_offset_m,
+         double heading_offset_deg, double pitch_offset_deg,
+         double roll_offset_deg,
+         double fov_deg, double aspect_ratio_multiplier,
+         double target_x_offset_m, double target_y_offset_m,
+         double target_z_offset_m, double near_m, bool internal );
+
+    void set_clean() { _dirty = false; }
+    void updateData();
+
+    void setHeadingOffset_deg_property (double heading_offset_deg);
+    void setPitchOffset_deg_property(double pitch_offset_deg);
+    void setRollOffset_deg_property(double roll_offset_deg);
+
+    void setPosition (const SGGeod& geod);
+    void setTargetPosition (const SGGeod& geod);
+
+    double getAbsolutePosition_x() const;
+    double getAbsolutePosition_y() const;
+    double getAbsolutePosition_z() const;
+
+    double getRawOrientation_w() const;
+    double getRawOrientation_x() const;
+    double getRawOrientation_y() const;
+    double getRawOrientation_z() const;
+
+    // quaternion accessors, for debugging:
+    double getFrame_w() const;
+    double getFrame_x() const;
+    double getFrame_y() const;
+    double getFrame_z() const;
+
+    double getOrientation_w() const;
+    double getOrientation_x() const;
+    double getOrientation_y() const;
+    double getOrientation_z() const;
+
+    double getOrOffset_w() const;
+    double getOrOffset_x() const;
+    double getOrOffset_y() const;
+    double getOrOffset_z() const;
+
+    double getLon_deg() const;
+    double getLat_deg() const;
+    double getElev_ft() const;
+
+    // Reference orientation rotations...
+    //   These are rotations that represent the plane attitude effect on
+    //   the view (in Pilot view).  IE The view frustrum rotates as the plane
+    //   turns, pitches, and rolls.
+    //   In model view (lookat/chaseview) these end up changing the angle that
+    //   the eye is looking at the ojbect (ie the model).
+    //   FIXME: the FGModel class should have its own version of these so that
+    //   it can generate it's own model rotations.
+    double getRoll_deg () const { return _roll_deg; }
+    double getPitch_deg () const {return _pitch_deg; }
+    void setRoll_deg (double roll_deg);
+    void setPitch_deg (double pitch_deg);
+    void setHeading_deg (double heading_deg);
+    void setOrientation (double roll_deg, double pitch_deg, double heading_deg);
+    double getTargetRoll_deg () const { return _target_roll_deg; }
+    double getTargetPitch_deg () const {return _target_pitch_deg; }
+    double getTargetHeading_deg () const {return _target_heading_deg; }
+    void setTargetRoll_deg (double roll_deg);
+    void setTargetPitch_deg (double pitch_deg);
+    void setTargetHeading_deg (double heading_deg);
+    void setTargetOrientation (double roll_deg, double pitch_deg, double heading_deg);
+
+
+
+
+    // Orientation offsets rotations from reference orientation.
+    // Goal settings are for smooth transition from prior
+    // offset when changing view direction.
+    //   These offsets are in ADDITION to the orientation rotations listed
+    //   above.
+    //   In pilot view they are applied after the position offsets in order to
+    //   give the effect of the pilot looking around.
+    //   In lookat view they are applied before the position offsets so that
+    //   the effect is the eye moving around looking at the object (ie the model)
+    //   from different angles.
+    double getGoalRollOffset_deg () const { return _goal_roll_offset_deg; }
+    double getGoalPitchOffset_deg () const { return _goal_pitch_offset_deg; }
+    double getGoalHeadingOffset_deg () const {return _goal_heading_offset_deg; }
+    void setRollOffset_deg (double roll_offset_deg);
+    void setPitchOffset_deg (double pitch_offset_deg);
+    void setGoalRollOffset_deg (double goal_roll_offset_deg);
+    void setGoalPitchOffset_deg (double goal_pitch_offset_deg);
+    void setOrientationOffsets (double roll_offset_deg,
+                                double heading_offset_deg,
+                                double pitch_offset_deg);
+    
+    void set_aspect_ratio_multiplier( double m ) {
+        _aspect_ratio_multiplier = m;
+    }
+    double get_aspect_ratio_multiplier() const {
+        return _aspect_ratio_multiplier;
+    }
+
+    double getNear_m () const { return _ground_level_nearplane_m; }
+    void setNear_m (double near_m) {
+        _ground_level_nearplane_m = near_m;
+    }
+
+    void set_fov( double fov_deg ) {
+        _fov_deg = fov_deg;
+    }
+
+    //////////////////////////////////////////////////////////////////
+    // private data                                                 //
+    //////////////////////////////////////////////////////////////////
+
+    std::string _name, _typeString;
+    
+    // flag forcing a recalc of derived view parameters
+    bool _dirty;
+
+    simgear::TiedPropertyList _tiedProperties;
+
+    SGQuatd mViewOrientation;
+    SGQuatd mViewOffsetOr;
+    SGVec3d _absolute_view_pos;
+
+    SGGeod _position;
+    SGGeod _target;
+
+    double _roll_deg;
+    double _pitch_deg;
+    double _heading_deg;
+    double _target_roll_deg;
+    double _target_pitch_deg;
+    double _target_heading_deg;
+
+    double _configRollOffsetDeg,
+        _configHeadingOffsetDeg,
+        _configPitchOffsetDeg;
+
+    SGVec3d _dampTarget; ///< current target value we are damping towards
+    SGVec3d _dampOutput; ///< current output of damping filter
+    SGVec3d _dampFactor; ///< weighting of the damping filter
+    
+    // Position offsets from FDM origin.  The X axis is positive
+    // out the tail, Y is out the right wing, and Z is positive up.
+    // distance in meters
+    SGVec3d _offset_m;
+    SGVec3d _configOffset_m;
+
+    // Target offsets from FDM origin (for "lookat" targets) The X
+    // axis is positive out the tail, Y is out the right wing, and Z
+    // is positive up.  distance in meters
+    SGVec3d _target_offset_m;
+    SGVec3d _configTargetOffset_m;
+
+    // orientation offsets from reference (_goal* are for smoothed transitions)
+    double _roll_offset_deg;
+    double _pitch_offset_deg;
+    double _heading_offset_deg;
+    double _goal_roll_offset_deg;
+    double _goal_pitch_offset_deg;
+    double _goal_heading_offset_deg;
+
+    // used to set nearplane when at ground level for this view
+    double _ground_level_nearplane_m;
+
+    ViewType _type;
+    ScalingType _scaling_type;
+
+    // internal view (e.g. cockpit) flag
+    bool _internal;
+
+    // view is looking from a model
+    bool _from_model;
+    int _from_model_index;  // number of model (for multi model)
+
+    // view is looking at a model
+    bool _at_model;
+    int _at_model_index;  // number of model (for multi model)
+
+    // the nominal field of view (angle, in degrees)
+    double _fov_deg;
+    double _configFOV_deg;
+    // default = 1.0, this value is user configurable and is
+    // multiplied into the aspect_ratio to get the actual vertical fov
+    double _aspect_ratio_multiplier;
+
+    class PositionAttitudeProperties : public SGPropertyChangeListener
+    {
+    public:
+        PositionAttitudeProperties();
+        
+        void init(SGPropertyNode_ptr parent, const std::string& prefix);
+
+        virtual ~PositionAttitudeProperties();
+
+        SGGeod position() const;
+        SGVec3d attitude() const; // as heading pitch roll
+
+    protected:
+        virtual void valueChanged(SGPropertyNode* prop);
+
+    private:
+// disable copy
+        PositionAttitudeProperties(const PositionAttitudeProperties&);
+
+        SGPropertyNode_ptr resolvePathProperty(SGPropertyNode_ptr p);
+
+        SGPropertyNode_ptr _lonProp,
+            _latProp,
+            _altProp,
+            _headingProp,
+            _pitchProp,
+            _rollProp;
+        SGPropertyNode_ptr _lonPathProp,
+            _latPathProp,
+            _altPathProp,
+            _headingPathProp,
+            _pitchPathProp,
+            _rollPathProp;
+    };
+
+    PositionAttitudeProperties _eyeProperties;
+    PositionAttitudeProperties _targetProperties;
+
+    //////////////////////////////////////////////////////////////////
+    // private functions                                            //
+    //////////////////////////////////////////////////////////////////
+
+    void recalc ();
+    void recalcLookFrom();
+    void recalcLookAt();
+
+    void setDampTarget(double h, double p, double r);
+    void getDampOutput(double& roll, double& pitch, double& heading);
+    
+    void updateDampOutput(double dt);
+    
+    // add to _heading_offset_deg
+    inline void incHeadingOffset_deg( double amt ) {
+       set_dirty();
+       _heading_offset_deg += amt;
+    }
+
+    // add to _pitch_offset_deg
+    inline void incPitchOffset_deg( double amt ) {
+       set_dirty();
+       _pitch_offset_deg += amt;
+    }
+
+    // add to _roll_offset_deg
+    inline void incRollOffset_deg( double amt ) {
+       set_dirty();
+       _roll_offset_deg += amt;
+    }
+
+}; // of class View
+
+} // of namespace flightgear
+
+
+#endif // _VIEWER_HXX
diff --git a/src/Viewer/viewer.cxx b/src/Viewer/viewer.cxx
deleted file mode 100644 (file)
index 3679a26..0000000
+++ /dev/null
@@ -1,1162 +0,0 @@
-// viewer.cxx -- class for managing a viewer in the flightgear world.
-//
-// Written by Curtis Olson, started August 1997.
-//                          overhaul started October 2000.
-//   partially rewritten by Jim Wilson jim@kelcomaine.com using interface
-//                          by David Megginson March 2002
-//
-// Copyright (C) 1997 - 2000  Curtis L. Olson  - http://www.flightgear.org/~curt
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-//
-// $Id$
-
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#include "viewer.hxx"
-
-#include <simgear/compiler.h>
-#include <cassert>
-
-#include <simgear/debug/logstream.hxx>
-#include <simgear/constants.h>
-#include <simgear/scene/model/placement.hxx>
-#include <simgear/scene/util/OsgMath.hxx>
-
-#include <Main/fg_props.hxx>
-#include <Main/globals.hxx>
-#include "CameraGroup.hxx"
-
-using namespace flightgear;
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of FGViewer.
-////////////////////////////////////////////////////////////////////////
-
-// Constructor...
-View::View( ViewType Type, bool from_model, int from_model_index,
-                    bool at_model, int at_model_index,
-                    double damp_roll, double damp_pitch, double damp_heading,
-                    double x_offset_m, double y_offset_m, double z_offset_m,
-                    double heading_offset_deg, double pitch_offset_deg,
-                    double roll_offset_deg,
-                    double fov_deg, double aspect_ratio_multiplier,
-                    double target_x_offset_m, double target_y_offset_m,
-                    double target_z_offset_m, double near_m, bool internal ):
-    _dirty(true),
-    _roll_deg(0),
-    _pitch_deg(0),
-    _heading_deg(0),
-    _target_roll_deg(0),
-    _target_pitch_deg(0),
-    _target_heading_deg(0),
-    _scaling_type(FG_SCALING_MAX)
-{
-    _absolute_view_pos = SGVec3d(0, 0, 0);
-    _type = Type;
-    _from_model = from_model;
-    _from_model_index = from_model_index;
-    _at_model = at_model;
-    _at_model_index = at_model_index;
-
-    _internal = internal;
-
-    _dampFactor = SGVec3d::zeros();
-    _dampOutput = SGVec3d::zeros();
-    _dampTarget = SGVec3d::zeros();
-
-    if (damp_roll > 0.0)
-      _dampFactor[0] = 1.0 / pow(10.0, fabs(damp_roll));
-    if (damp_pitch > 0.0)
-      _dampFactor[1] = 1.0 / pow(10.0, fabs(damp_pitch));
-    if (damp_heading > 0.0)
-      _dampFactor[2] = 1.0 / pow(10.0, fabs(damp_heading));
-
-    _offset_m.x() = x_offset_m;
-    _offset_m.y() = y_offset_m;
-    _offset_m.z() = z_offset_m;
-    _configOffset_m = _offset_m;
-
-    _heading_offset_deg = heading_offset_deg;
-    _pitch_offset_deg = pitch_offset_deg;
-    _roll_offset_deg = roll_offset_deg;
-    _goal_heading_offset_deg = heading_offset_deg;
-    _goal_pitch_offset_deg = pitch_offset_deg;
-    _goal_roll_offset_deg = roll_offset_deg;
-
-    _configHeadingOffsetDeg = heading_offset_deg;
-    _configPitchOffsetDeg = pitch_offset_deg;
-    _configRollOffsetDeg = roll_offset_deg;
-
-    if (fov_deg > 0) {
-      _fov_deg = fov_deg;
-    } else {
-      _fov_deg = 55;
-    }
-
-    _configFOV_deg = _fov_deg;
-
-    _aspect_ratio_multiplier = aspect_ratio_multiplier;
-    _target_offset_m.x() = target_x_offset_m;
-    _target_offset_m.y() = target_y_offset_m;
-    _target_offset_m.z() = target_z_offset_m;
-    _configTargetOffset_m = _target_offset_m;
-
-    _ground_level_nearplane_m = near_m;
-    // a reasonable guess for init, so that the math doesn't blow up
-}
-
-View* View::createFromProperties(SGPropertyNode_ptr config)
-{
-    double aspect_ratio_multiplier
-        = fgGetDouble("/sim/current-view/aspect-ratio-multiplier");
-
-    // find out if this is an internal view (e.g. in cockpit, low near plane)
-    // FIXME : should be a child of config
-    bool internal = config->getParent()->getBoolValue("internal", false);
-
-
-    // FIXME:
-    // this is assumed to be an aircraft model...we will need to read
-    // model-from-type as well.
-
-    // find out if this is a model we are looking from...
-    bool from_model = config->getBoolValue("from-model");
-    int from_model_index = config->getIntValue("from-model-idx");
-
-    double x_offset_m = config->getDoubleValue("x-offset-m");
-    double y_offset_m = config->getDoubleValue("y-offset-m");
-    double z_offset_m = config->getDoubleValue("z-offset-m");
-
-    double heading_offset_deg = config->getDoubleValue("heading-offset-deg");
-  //  config->setDoubleValue("heading-offset-deg", heading_offset_deg);
-    double pitch_offset_deg = config->getDoubleValue("pitch-offset-deg");
-  //  config->setDoubleValue("pitch-offset-deg", pitch_offset_deg);
-    double roll_offset_deg = config->getDoubleValue("roll-offset-deg");
-   // config->setDoubleValue("roll-offset-deg", roll_offset_deg);
-
-    double fov_deg = config->getDoubleValue("default-field-of-view-deg");
-    double near_m = config->getDoubleValue("ground-level-nearplane-m");
-
-    View* v = 0;
-    // supporting two types "lookat" = 1 and "lookfrom" = 0
-    const char *type = config->getParent()->getStringValue("type");
-    if (!strcmp(type, "lookat")) {
-        bool at_model = config->getBoolValue("at-model");
-        int at_model_index = config->getIntValue("at-model-idx");
-
-        double damp_roll = config->getDoubleValue("at-model-roll-damping");
-        double damp_pitch = config->getDoubleValue("at-model-pitch-damping");
-        double damp_heading = config->getDoubleValue("at-model-heading-damping");
-
-        double target_x_offset_m = config->getDoubleValue("target-x-offset-m");
-        double target_y_offset_m = config->getDoubleValue("target-y-offset-m");
-        double target_z_offset_m = config->getDoubleValue("target-z-offset-m");
-
-        v = new View ( FG_LOOKAT, from_model, from_model_index,
-                           at_model, at_model_index,
-                           damp_roll, damp_pitch, damp_heading,
-                           x_offset_m, y_offset_m,z_offset_m,
-                           heading_offset_deg, pitch_offset_deg,
-                           roll_offset_deg, fov_deg, aspect_ratio_multiplier,
-                           target_x_offset_m, target_y_offset_m,
-                         target_z_offset_m, near_m, internal );
-        if (!from_model) {
-            v->_targetProperties.init(config, "target-");
-        }
-    } else {
-        v = new View ( FG_LOOKFROM, from_model, from_model_index,
-                       false, 0, 0.0, 0.0, 0.0,
-                       x_offset_m, y_offset_m, z_offset_m,
-                       heading_offset_deg, pitch_offset_deg,
-                       roll_offset_deg, fov_deg, aspect_ratio_multiplier,
-                         0, 0, 0, near_m, internal );
-    }
-
-    if (!from_model) {
-        v->_eyeProperties.init(config, "eye-");
-    }
-
-    v->_name = config->getParent()->getStringValue("name");
-    v->_typeString = type;
-    v->_configHeadingOffsetDeg = config->getDoubleValue("default-heading-offset-deg");
-
-    return v;
-}
-
-
-// Destructor
-View::~View( void )
-{
-    _tiedProperties.Untie();
-}
-
-void
-View::init ()
-{
-}
-
-void
-View::bind ()
-{
-    _tiedProperties.setRoot(fgGetNode("/sim/current-view", true));
-    _tiedProperties.Tie("heading-offset-deg", this,
-                         &View::getHeadingOffset_deg,
-                         &View::setHeadingOffset_deg_property,
-                        false /* do not set current property value */);
-
-     fgSetArchivable("/sim/current-view/heading-offset-deg");
-
-    _tiedProperties.Tie("goal-heading-offset-deg", this,
-                        &View::getGoalHeadingOffset_deg,
-                        &View::setGoalHeadingOffset_deg,
-                        false /* do not set current property value */);
-
-    fgSetArchivable("/sim/current-view/goal-heading-offset-deg");
-
-    _tiedProperties.Tie("pitch-offset-deg", this,
-                        &View::getPitchOffset_deg,
-                        &View::setPitchOffset_deg_property,
-                        false /* do not set current property value */);
-    fgSetArchivable("/sim/current-view/pitch-offset-deg");
-    _tiedProperties.Tie("goal-pitch-offset-deg", this,
-                        &View::getGoalPitchOffset_deg,
-                        &View::setGoalPitchOffset_deg,
-                        false /* do not set current property value */);
-    fgSetArchivable("/sim/current-view/goal-pitch-offset-deg");
-    _tiedProperties.Tie("roll-offset-deg", this,
-                        &View::getRollOffset_deg,
-                        &View::setRollOffset_deg_property,
-                        false /* do not set current property value */);
-    fgSetArchivable("/sim/current-view/roll-offset-deg");
-    _tiedProperties.Tie("goal-roll-offset-deg", this,
-                        &View::getGoalRollOffset_deg,
-                        &View::setGoalRollOffset_deg,
-                        false /* do not set current property value */);
-    fgSetArchivable("/sim/current-view/goal-roll-offset-deg");
-
-
-    _tiedProperties.Tie("field-of-view", this,
-                        &View::get_fov, &View::set_fov,
-                        false);
-    fgSetArchivable("/sim/current-view/field-of-view");
-
-
-    _tiedProperties.Tie("aspect-ratio-multiplier", this,
-                        &View::get_aspect_ratio_multiplier,
-                        &View::set_aspect_ratio_multiplier,
-                        false);
-
-    _tiedProperties.Tie("ground-level-nearplane-m", this,
-                        &View::getNear_m, &View::setNear_m, false);
-    fgSetArchivable("/sim/current-view/ground-level-nearplane-m");
-
-
-    _tiedProperties.Tie("viewer-lon-deg", this, &View::getLon_deg);
-    _tiedProperties.Tie("viewer-lat-deg", this, &View::getLat_deg);
-    _tiedProperties.Tie("viewer-elev-ft", this, &View::getElev_ft);
-
-    _tiedProperties.Tie("x-offset-m", this, &View::getXOffset_m,
-                        &View::setXOffset_m, false);
-    _tiedProperties.Tie("y-offset-m", this, &View::getYOffset_m,
-                        &View::setYOffset_m, false);
-    _tiedProperties.Tie("z-offset-m", this, &View::getZOffset_m,
-                        &View::setZOffset_m, false);
-
-    _tiedProperties.Tie("target-x-offset-m", this, &View::getTargetXOffset_m,
-                        &View::setTargetXOffset_m, false);
-    _tiedProperties.Tie("target-y-offset-m", this, &View::getTargetYOffset_m,
-                        &View::setTargetYOffset_m, false);
-    _tiedProperties.Tie("target-z-offset-m", this, &View::getTargetZOffset_m,
-                        &View::setTargetZOffset_m, false);
-
-// expose various quaternions under the debug/ subtree
-    _tiedProperties.Tie("debug/orientation-w", this, &View::getOrientation_w);
-    _tiedProperties.Tie("debug/orientation-x", this, &View::getOrientation_x);
-    _tiedProperties.Tie("debug/orientation-y", this, &View::getOrientation_y);
-    _tiedProperties.Tie("debug/orientation-z", this, &View::getOrientation_z);
-
-    _tiedProperties.Tie("debug/orientation_offset-w", this,
-                        &View::getOrOffset_w);
-    _tiedProperties.Tie("debug/orientation_offset-x", this,
-                        &View::getOrOffset_x);
-    _tiedProperties.Tie("debug/orientation_offset-y", this,
-                        &View::getOrOffset_y);
-    _tiedProperties.Tie("debug/orientation_offset-z", this,
-                        &View::getOrOffset_z);
-
-    _tiedProperties.Tie("debug/frame-w", this, &View::getFrame_w);
-    _tiedProperties.Tie("debug/frame-x", this, &View::getFrame_x);
-    _tiedProperties.Tie("debug/frame-y", this, &View::getFrame_y);
-    _tiedProperties.Tie("debug/frame-z", this, &View::getFrame_z);
-
-
-// expose the raw (OpenGL) orientation to the property tree,
-// for the sound-manager
-    _tiedProperties.Tie("raw-orientation", 0, this, &View::getRawOrientation_w);
-    _tiedProperties.Tie("raw-orientation", 1, this, &View::getRawOrientation_x);
-    _tiedProperties.Tie("raw-orientation", 2, this, &View::getRawOrientation_y);
-    _tiedProperties.Tie("raw-orientation", 3, this, &View::getRawOrientation_z);
-
-    _tiedProperties.Tie("viewer-x-m", this, &View::getAbsolutePosition_x);
-    _tiedProperties.Tie("viewer-y-m", this, &View::getAbsolutePosition_y);
-    _tiedProperties.Tie("viewer-z-m", this, &View::getAbsolutePosition_z);
-
-// following config properties are exposed on current-view but don't change,
-// so we can simply copy them here.
-    _tiedProperties.getRoot()->setStringValue("name", _name);
-    _tiedProperties.getRoot()->setStringValue("type", _typeString);
-    _tiedProperties.getRoot()->setBoolValue("internal", _internal);
-
-    SGPropertyNode_ptr config = _tiedProperties.getRoot()->getChild("config", 0, true);
-    config->setBoolValue("from-model", _from_model);
-    config->setDoubleValue("heading-offset-deg", _configHeadingOffsetDeg);
-    config->setDoubleValue("pitch-offset-deg", _configPitchOffsetDeg);
-    config->setDoubleValue("roll-offset-deg", _configRollOffsetDeg);
-    config->setDoubleValue("default-field-of-view-deg", _configFOV_deg);
-}
-
-void
-View::unbind ()
-{
-    _tiedProperties.Untie();
-}
-
-void View::resetOffsetsAndFOV()
-{
-    _target_offset_m = _configTargetOffset_m;
-    _offset_m = _configOffset_m;
-    _pitch_offset_deg = _configPitchOffsetDeg;
-    _heading_offset_deg = _configHeadingOffsetDeg;
-    _roll_offset_deg = _configRollOffsetDeg;
-    _fov_deg = _configFOV_deg;
-}
-
-void
-View::setType ( int type )
-{
-  if (type == 0)
-    _type = FG_LOOKFROM;
-  if (type == 1)
-    _type = FG_LOOKAT;
-}
-
-void
-View::setInternal ( bool internal )
-{
-  _internal = internal;
-}
-
-void
-View::setPosition (const SGGeod& geod)
-{
-  _dirty = true;
-    _position = geod;
-}
-
-void
-View::setTargetPosition (const SGGeod& geod)
-{
-  _dirty = true;
-    _target = geod;
-}
-
-void
-View::setRoll_deg (double roll_deg)
-{
-  _dirty = true;
-  _roll_deg = roll_deg;
-}
-
-void
-View::setPitch_deg (double pitch_deg)
-{
-  _dirty = true;
-  _pitch_deg = pitch_deg;
-}
-
-void
-View::setHeading_deg (double heading_deg)
-{
-  _dirty = true;
-  _heading_deg = heading_deg;
-}
-
-void
-View::setOrientation (double roll_deg, double pitch_deg, double heading_deg)
-{
-  _dirty = true;
-  _roll_deg = roll_deg;
-  _pitch_deg = pitch_deg;
-  _heading_deg = heading_deg;
-}
-
-void
-View::setTargetRoll_deg (double target_roll_deg)
-{
-  _dirty = true;
-  _target_roll_deg = target_roll_deg;
-}
-
-void
-View::setTargetPitch_deg (double target_pitch_deg)
-{
-  _dirty = true;
-  _target_pitch_deg = target_pitch_deg;
-}
-
-void
-View::setTargetHeading_deg (double target_heading_deg)
-{
-  _dirty = true;
-  _target_heading_deg = target_heading_deg;
-}
-
-void
-View::setTargetOrientation (double target_roll_deg, double target_pitch_deg, double target_heading_deg)
-{
-  _dirty = true;
-  _target_roll_deg = target_roll_deg;
-  _target_pitch_deg = target_pitch_deg;
-  _target_heading_deg = target_heading_deg;
-}
-
-void
-View::setXOffset_m (double x_offset_m)
-{
-  _dirty = true;
-  _offset_m.x() = x_offset_m;
-}
-
-void
-View::setYOffset_m (double y_offset_m)
-{
-  _dirty = true;
-  _offset_m.y() = y_offset_m;
-}
-
-void
-View::setZOffset_m (double z_offset_m)
-{
-  _dirty = true;
-  _offset_m.z() = z_offset_m;
-}
-
-void
-View::setTargetXOffset_m (double target_x_offset_m)
-{
-  _dirty = true;
-  _target_offset_m.x() = target_x_offset_m;
-}
-
-void
-View::setTargetYOffset_m (double target_y_offset_m)
-{
-  _dirty = true;
-  _target_offset_m.y() = target_y_offset_m;
-}
-
-void
-View::setTargetZOffset_m (double target_z_offset_m)
-{
-  _dirty = true;
-  _target_offset_m.z() = target_z_offset_m;
-}
-
-void
-View::setPositionOffsets (double x_offset_m, double y_offset_m, double z_offset_m)
-{
-  _dirty = true;
-  _offset_m.x() = x_offset_m;
-  _offset_m.y() = y_offset_m;
-  _offset_m.z() = z_offset_m;
-}
-
-void
-View::setRollOffset_deg (double roll_offset_deg)
-{
-  _dirty = true;
-  _roll_offset_deg = roll_offset_deg;
-}
-
-void
-View::setPitchOffset_deg (double pitch_offset_deg)
-{
-  _dirty = true;
-  _pitch_offset_deg = pitch_offset_deg;
-}
-
-void
-View::setHeadingOffset_deg (double heading_offset_deg)
-{
-  _dirty = true;
-  if (_at_model && (_offset_m.x() == 0.0)&&(_offset_m.z() == 0.0))
-  {
-      /* avoid optical effects (e.g. rotating sky) when "looking at" with
-       * heading offsets x==z==0 (view heading cannot change). */
-      _heading_offset_deg = 0.0;
-  }
-  else
-      _heading_offset_deg = heading_offset_deg;
-}
-
-void
-View::setHeadingOffset_deg_property (double heading_offset_deg)
-{
-    setHeadingOffset_deg(heading_offset_deg);
-    setGoalHeadingOffset_deg(heading_offset_deg);
-}
-
-void
-View::setPitchOffset_deg_property (double pitch_offset_deg)
-{
-    setPitchOffset_deg(pitch_offset_deg);
-    setGoalPitchOffset_deg(pitch_offset_deg);
-}
-
-void
-View::setRollOffset_deg_property (double roll_offset_deg)
-{
-    setRollOffset_deg(roll_offset_deg);
-    setGoalRollOffset_deg(roll_offset_deg);
-}
-
-void
-View::setGoalRollOffset_deg (double goal_roll_offset_deg)
-{
-  _dirty = true;
-  _goal_roll_offset_deg = goal_roll_offset_deg;
-}
-
-void
-View::setGoalPitchOffset_deg (double goal_pitch_offset_deg)
-{
-  _dirty = true;
-  _goal_pitch_offset_deg = goal_pitch_offset_deg;
-  /* The angle is set to 1/1000th of a degree from the poles to avoid the
-   * singularity where the azimuthal angle becomes undefined, inducing optical
-   * artefacts.  The arbitrary angle offset is visually unnoticeable while
-   * avoiding any possible floating point truncation artefacts. */
-  if ( _goal_pitch_offset_deg < -89.999 ) {
-    _goal_pitch_offset_deg = -89.999;
-  }
-  if ( _goal_pitch_offset_deg > 89.999 ) {
-    _goal_pitch_offset_deg = 89.999;
-  }
-
-}
-
-void
-View::setGoalHeadingOffset_deg (double goal_heading_offset_deg)
-{
-  _dirty = true;
-  if (_at_model && (_offset_m.x() == 0.0)&&(_offset_m.z() == 0.0))
-  {
-      /* avoid optical effects (e.g. rotating sky) when "looking at" with
-       * heading offsets x==z==0 (view heading cannot change). */
-      _goal_heading_offset_deg = 0.0;
-      return;
-  }
-
-  _goal_heading_offset_deg = goal_heading_offset_deg;
-  while ( _goal_heading_offset_deg < 0.0 ) {
-    _goal_heading_offset_deg += 360;
-  }
-  while ( _goal_heading_offset_deg > 360 ) {
-    _goal_heading_offset_deg -= 360;
-  }
-}
-
-void
-View::setOrientationOffsets (double roll_offset_deg, double pitch_offset_deg, double heading_offset_deg)
-{
-  _dirty = true;
-  _roll_offset_deg = roll_offset_deg;
-  _pitch_offset_deg = pitch_offset_deg;
-  _heading_offset_deg = heading_offset_deg;
-}
-
-// recalc() is done every time one of the setters is called (making the
-// cached data "dirty") on the next "get".  It calculates all the outputs
-// for viewer.
-void
-View::recalc ()
-{
-  if (_type == FG_LOOKFROM) {
-    recalcLookFrom();
-  } else {
-    recalcLookAt();
-  }
-
-  set_clean();
-}
-
-// recalculate for LookFrom view type...
-void
-View::recalcLookFrom ()
-{
-  // Update location data ...
-  if ( _from_model ) {
-    _position = globals->get_aircraft_position();
-    globals->get_aircraft_orientation(_heading_deg, _pitch_deg, _roll_deg);
-  }
-
-  double head = _heading_deg;
-  double pitch = _pitch_deg;
-  double roll = _roll_deg;
-  if ( !_from_model ) {
-    // update from our own data...
-    setDampTarget(roll, pitch, head);
-    getDampOutput(roll, pitch, head);
-  }
-
-  // The rotation rotating from the earth centerd frame to
-  // the horizontal local frame
-  SGQuatd hlOr = SGQuatd::fromLonLat(_position);
-
-  // The rotation from the horizontal local frame to the basic view orientation
-  SGQuatd hlToBody = SGQuatd::fromYawPitchRollDeg(head, pitch, roll);
-
-  // The rotation offset, don't know why heading is negative here ...
-  mViewOffsetOr
-      = SGQuatd::fromYawPitchRollDeg(-_heading_offset_deg, _pitch_offset_deg,
-                                     _roll_offset_deg);
-
-  // Compute the eyepoints orientation and position
-  // wrt the earth centered frame - that is global coorinates
-  SGQuatd ec2body = hlOr*hlToBody;
-
-  // The cartesian position of the basic view coordinate
-  SGVec3d position = SGVec3d::fromGeod(_position);
-
-  // This is rotates the x-forward, y-right, z-down coordinate system the where
-  // simulation runs into the OpenGL camera system with x-right, y-up, z-back.
-  SGQuatd q(-0.5, -0.5, 0.5, 0.5);
-
-  _absolute_view_pos = position + (ec2body*q).backTransform(_offset_m);
-  mViewOrientation = ec2body*mViewOffsetOr*q;
-}
-
-void
-View::recalcLookAt ()
-{
-  // The geodetic position of our target to look at
-  if ( _at_model ) {
-    _target = globals->get_aircraft_position();
-    globals->get_aircraft_orientation(_target_heading_deg,
-                                      _target_pitch_deg,
-                                      _target_roll_deg);
-  } else {
-    // if not model then calculate our own target position...
-    setDampTarget(_target_roll_deg, _target_pitch_deg, _target_heading_deg);
-    getDampOutput(_target_roll_deg, _target_pitch_deg, _target_heading_deg);
-  }
-
-  SGQuatd geodTargetOr = SGQuatd::fromYawPitchRollDeg(_target_heading_deg,
-                                                   _target_pitch_deg,
-                                                   _target_roll_deg);
-  SGQuatd geodTargetHlOr = SGQuatd::fromLonLat(_target);
-
-
-  if ( _from_model ) {
-    _position = globals->get_aircraft_position();
-    globals->get_aircraft_orientation(_heading_deg, _pitch_deg, _roll_deg);
-  } else {
-    // update from our own data, just the rotation here...
-    setDampTarget(_roll_deg, _pitch_deg, _heading_deg);
-    getDampOutput(_roll_deg, _pitch_deg, _heading_deg);
-  }
-  SGQuatd geodEyeOr = SGQuatd::fromYawPitchRollDeg(_heading_deg, _pitch_deg, _roll_deg);
-  SGQuatd geodEyeHlOr = SGQuatd::fromLonLat(_position);
-
-  // the rotation offset, don't know why heading is negative here ...
-  mViewOffsetOr =
-    SGQuatd::fromYawPitchRollDeg(-_heading_offset_deg + 180, _pitch_offset_deg,
-                                 _roll_offset_deg);
-
-  // Offsets to the eye position
-  SGVec3d eyeOff(-_offset_m.z(), _offset_m.x(), -_offset_m.y());
-  SGQuatd ec2eye = geodEyeHlOr*geodEyeOr;
-  SGVec3d eyeCart = SGVec3d::fromGeod(_position);
-  eyeCart += (ec2eye*mViewOffsetOr).backTransform(eyeOff);
-
-  SGVec3d atCart = SGVec3d::fromGeod(_target);
-
-  // add target offsets to at_position...
-  SGVec3d target_pos_off(-_target_offset_m.z(), _target_offset_m.x(),
-                         -_target_offset_m.y());
-  target_pos_off = (geodTargetHlOr*geodTargetOr).backTransform(target_pos_off);
-  atCart += target_pos_off;
-  eyeCart += target_pos_off;
-
-  // Compute the eyepoints orientation and position
-  // wrt the earth centered frame - that is global coorinates
-  _absolute_view_pos = eyeCart;
-
-  // the view direction
-  SGVec3d dir = normalize(atCart - eyeCart);
-  // the up directon
-  SGVec3d up = ec2eye.backTransform(SGVec3d(0, 0, -1));
-  // rotate -dir to the 2-th unit vector
-  // rotate up to 1-th unit vector
-  // Note that this matches the OpenGL camera coordinate system
-  // with x-right, y-up, z-back.
-  mViewOrientation = SGQuatd::fromRotateTo(-dir, 2, up, 1);
-}
-
-void
-View::setDampTarget(double roll, double pitch, double heading)
-{
-  _dampTarget = SGVec3d(roll, pitch, heading);
-}
-
-void
-View::getDampOutput(double& roll, double& pitch, double& heading)
-{
-  roll = _dampOutput[0];
-  pitch = _dampOutput[1];
-  heading = _dampOutput[2];
-}
-
-
-void
-View::updateDampOutput(double dt)
-{
-  static View *last_view = 0;
-  if ((last_view != this) || (dt > 1.0)) {
-    _dampOutput = _dampTarget;
-    last_view = this;
-    return;
-  }
-
-  const double interval = 0.01;
-  while (dt > interval) {
-
-    for (unsigned int i=0; i<3; ++i) {
-      if (_dampFactor[i] <= 0.0) {
-        // axis is un-damped, set output to target directly
-        _dampOutput[i] = _dampTarget[i];
-        continue;
-      }
-
-      double d = _dampOutput[i] - _dampTarget[i];
-      if (d > 180.0) {
-        _dampOutput[i] -= 360.0;
-      } else if (d < -180.0) {
-        _dampOutput[i] += 360.0;
-      }
-
-      _dampOutput[i] = (_dampTarget[i] * _dampFactor[i]) +
-        (_dampOutput[i] * (1.0 - _dampFactor[i]));
-    } // of axis iteration
-
-    dt -= interval;
-  } // of dt subdivision by interval
-}
-
-double
-View::get_h_fov()
-{
-    double aspectRatio = get_aspect_ratio();
-    switch (_scaling_type) {
-    case FG_SCALING_WIDTH:  // h_fov == fov
-       return _fov_deg;
-    case FG_SCALING_MAX:
-       if (aspectRatio < 1.0) {
-           // h_fov == fov
-           return _fov_deg;
-       } else {
-           // v_fov == fov
-           return
-                atan(tan(_fov_deg/2 * SG_DEGREES_TO_RADIANS)
-                     / (aspectRatio*_aspect_ratio_multiplier))
-                * SG_RADIANS_TO_DEGREES * 2;
-       }
-    default:
-       assert(false);
-    }
-    return 0.0;
-}
-
-
-
-double
-View::get_v_fov()
-{
-    double aspectRatio = get_aspect_ratio();
-    switch (_scaling_type) {
-    case FG_SCALING_WIDTH:  // h_fov == fov
-       return
-            atan(tan(_fov_deg/2 * SG_DEGREES_TO_RADIANS)
-                 * (aspectRatio*_aspect_ratio_multiplier))
-            * SG_RADIANS_TO_DEGREES * 2;
-    case FG_SCALING_MAX:
-       if (aspectRatio < 1.0) {
-           // h_fov == fov
-           return
-                atan(tan(_fov_deg/2 * SG_DEGREES_TO_RADIANS)
-                     * (aspectRatio*_aspect_ratio_multiplier))
-                * SG_RADIANS_TO_DEGREES * 2;
-       } else {
-           // v_fov == fov
-           return _fov_deg;
-       }
-    default:
-       assert(false);
-    }
-    return 0.0;
-}
-
-void
-View::updateData()
-{
-    if (!_from_model) {
-        SGGeod pos = _eyeProperties.position();
-        SGVec3d att = _eyeProperties.attitude();
-        setPosition(pos);
-        setOrientation(att[2], att[1], att[0]);
-    } else {
-        set_dirty();
-    }
-
-    // if lookat (type 1) then get target data...
-    if (getType() == FG_LOOKAT) {
-        if (!_from_model) {
-            SGGeod pos = _targetProperties.position();
-            SGVec3d att = _targetProperties.attitude();
-            setTargetPosition(pos);
-            setTargetOrientation(att[2], att[1], att[0]);
-        } else {
-            set_dirty();
-        }
-    }
-}
-
-void
-View::update (double dt)
-{
-    updateData();
-  updateDampOutput(dt);
-
-  int i;
-  int dt_ms = int(dt * 1000);
-  for ( i = 0; i < dt_ms; i++ ) {
-    if ( fabs( _goal_heading_offset_deg - _heading_offset_deg) < 1 ) {
-      setHeadingOffset_deg( _goal_heading_offset_deg );
-      break;
-    } else {
-      // move current_view.headingoffset towards
-      // current_view.goal_view_offset
-      if ( _goal_heading_offset_deg > _heading_offset_deg )
-       {
-         if ( _goal_heading_offset_deg - _heading_offset_deg < 180 ){
-           incHeadingOffset_deg( 0.5 );
-         } else {
-           incHeadingOffset_deg( -0.5 );
-         }
-       } else {
-         if ( _heading_offset_deg - _goal_heading_offset_deg < 180 ){
-           incHeadingOffset_deg( -0.5 );
-         } else {
-           incHeadingOffset_deg( 0.5 );
-         }
-       }
-      if ( _heading_offset_deg > 360 ) {
-       incHeadingOffset_deg( -360 );
-      } else if ( _heading_offset_deg < 0 ) {
-       incHeadingOffset_deg( 360 );
-      }
-    }
-  }
-
-  for ( i = 0; i < dt_ms; i++ ) {
-    if ( fabs( _goal_pitch_offset_deg - _pitch_offset_deg ) < 1 ) {
-      setPitchOffset_deg( _goal_pitch_offset_deg );
-      break;
-    } else {
-      // move current_view.pitch_offset_deg towards
-      // current_view.goal_pitch_offset
-      if ( _goal_pitch_offset_deg > _pitch_offset_deg )
-       {
-         incPitchOffset_deg( 1.0 );
-       } else {
-           incPitchOffset_deg( -1.0 );
-       }
-      if ( _pitch_offset_deg > 90 ) {
-       setPitchOffset_deg(90);
-      } else if ( _pitch_offset_deg < -90 ) {
-       setPitchOffset_deg( -90 );
-      }
-    }
-  }
-
-
-  for ( i = 0; i < dt_ms; i++ ) {
-    if ( fabs( _goal_roll_offset_deg - _roll_offset_deg ) < 1 ) {
-      setRollOffset_deg( _goal_roll_offset_deg );
-      break;
-    } else {
-      // move current_view.roll_offset_deg towards
-      // current_view.goal_roll_offset
-      if ( _goal_roll_offset_deg > _roll_offset_deg )
-       {
-         incRollOffset_deg( 1.0 );
-       } else {
-           incRollOffset_deg( -1.0 );
-       }
-      if ( _roll_offset_deg > 90 ) {
-       setRollOffset_deg(90);
-      } else if ( _roll_offset_deg < -90 ) {
-       setRollOffset_deg( -90 );
-      }
-    }
-  }
-  recalc();
-}
-
-double View::getAbsolutePosition_x() const
-{
-    return _absolute_view_pos.x();
-}
-
-double View::getAbsolutePosition_y() const
-{
-    return _absolute_view_pos.y();
-}
-
-double View::getAbsolutePosition_z() const
-{
-    return _absolute_view_pos.z();
-}
-
-double View::getRawOrientation_w() const
-{
-    return mViewOrientation.w();
-}
-
-double View::getRawOrientation_x() const
-{
-    return mViewOrientation.x();
-}
-
-double View::getRawOrientation_y() const
-{
-    return mViewOrientation.y();
-}
-
-double View::getRawOrientation_z() const
-{
-    return mViewOrientation.z();
-}
-
-// This takes the conventional aviation XYZ body system
-// i.e.  x=forward, y=starboard, z=bottom
-// which is widely used in FGFS
-// and rotates it into the OpenGL camera system
-// i.e. Xprime=starboard, Yprime=top, Zprime=aft.
-static const SGQuatd fsb2sta()
-{
-    return SGQuatd(-0.5, -0.5, 0.5, 0.5);
-}
-
-// reference frame orientation.
-// This is the view orientation you get when you have no
-// view offset, i.e. the offset operator is the identity.
-//
-// For example, in the familiar "cockpit lookfrom" view,
-// the reference frame is equal to the aircraft attitude,
-// i.e. it is the view looking towards 12:00 straight ahead.
-//
-// FIXME:  Somebody needs to figure out what is the reference
-// frame view for the other view modes.
-//
-// Conceptually, this quat represents a rotation relative
-// to the ECEF reference orientation, as described at
-//    http://www.av8n.com/physics/coords.htm#sec-orientation
-//
-// See the NOTE concerning reference orientations, below.
-//
-// The components of this quat are expressed in
-// the conventional aviation basis set,
-// i.e.  x=forward, y=starboard, z=bottom
-double View::getFrame_w() const
-{
-    return ((mViewOrientation*conj(fsb2sta())*conj(mViewOffsetOr))).w();
-}
-
-double View::getFrame_x() const
-{
-    return ((mViewOrientation*conj(fsb2sta())*conj(mViewOffsetOr))).x();
-}
-
-double View::getFrame_y() const
-{
-    return ((mViewOrientation*conj(fsb2sta())*conj(mViewOffsetOr))).y();
-}
-
-double View::getFrame_z() const
-{
-    return ((mViewOrientation*conj(fsb2sta())*conj(mViewOffsetOr))).z();
-}
-
-
-// view offset.
-// This rotation takes you from the aforementioned
-// reference frame view orientation to whatever
-// actual current view orientation is.
-//
-// The components of this quaternion are expressed in
-// the conventional aviation basis set,
-// i.e.  x=forward, y=starboard, z=bottom
-double View::getOrOffset_w() const{
-    return mViewOffsetOr.w();
-}
-double View::getOrOffset_x() const{
-    return mViewOffsetOr.x();
-}
-double View::getOrOffset_y() const{
-    return mViewOffsetOr.y();
-}
-double View::getOrOffset_z() const{
-    return mViewOffsetOr.z();
-}
-
-
-// current view orientation.
-// This is a rotation relative to the earth-centered (ec)
-// reference frame.
-//
-// NOTE: Here we remove a factor of fsb2sta so that
-// the components of this quat are displayed using the
-// conventional ECEF basis set.  This is *not* the way
-// the view orientation is stored in the views[] array,
-// but is easier for non-graphics hackers to understand.
-// If we did not remove this factor of fsb2sta here and
-// in getCurrentViewFrame, that would be equivalent to
-// the following peculiar reference orientation:
-// Suppose you are over the Gulf of Guinea, at (lat,lon) = (0,0).
-// Then the reference frame orientation can be achieved via:
-//    -- The aircraft X-axis (nose) headed south.
-//    -- The aircraft Y-axis (starboard wingtip) pointing up.
-//    -- The aircraft Z-axis (belly) pointing west.
-// To say the same thing in other words, and perhaps more to the
-// point:  If we use the OpenGL camera orientation conventions,
-// i.e. Xprime=starboard, Yprime=top, Zprime=aft, then the
-// aforementioned peculiar reference orientation at (lat,lon)
-//  = (0,0) can be described as:
-//    -- aircraft Xprime axis (starboard) pointed up
-//    -- aircraft Yprime axis (top) pointed east
-//    -- aircraft Zprime axis (aft) pointed north
-// meaning the OpenGL axes are aligned with the ECEF axes.
-double View::getOrientation_w() const{
-    return (mViewOrientation * conj(fsb2sta())).w();
-}
-double View::getOrientation_x() const{
-    return (mViewOrientation * conj(fsb2sta())).x();
-}
-double View::getOrientation_y() const{
-    return (mViewOrientation * conj(fsb2sta())).y();
-}
-double View::getOrientation_z() const{
-    return (mViewOrientation * conj(fsb2sta())).z();
-}
-
-double View::get_aspect_ratio() const
-{
-    return flightgear::CameraGroup::getDefault()->getMasterAspectRatio();
-}
-
-double View::getLon_deg() const
-{
-    return _position.getLongitudeDeg();
-}
-
-double View::getLat_deg() const
-{
-    return _position.getLatitudeDeg();
-}
-
-double View::getElev_ft() const
-{
-    return _position.getElevationFt();
-}
-
-View::PositionAttitudeProperties::PositionAttitudeProperties()
-{
-}
-
-View::PositionAttitudeProperties::~PositionAttitudeProperties()
-{
-}
-
-void View::PositionAttitudeProperties::init(SGPropertyNode_ptr parent, const std::string& prefix)
-{
-    _lonPathProp = parent->getNode(prefix + "lon-deg-path", true);
-    _latPathProp = parent->getNode(prefix + "lat-deg-path", true);
-    _altPathProp = parent->getNode(prefix + "alt-ft-path", true);
-    _headingPathProp = parent->getNode(prefix + "heading-deg-path", true);
-    _pitchPathProp = parent->getNode(prefix + "pitch-deg-path", true);
-    _rollPathProp = parent->getNode(prefix + "roll-deg-path", true);
-
-    // update the real properties now
-    valueChanged(NULL);
-
-    _lonPathProp->addChangeListener(this);
-    _latPathProp->addChangeListener(this);
-    _altPathProp->addChangeListener(this);
-    _headingPathProp->addChangeListener(this);
-    _pitchPathProp->addChangeListener(this);
-    _rollPathProp->addChangeListener(this);
-}
-
-void View::PositionAttitudeProperties::valueChanged(SGPropertyNode* node)
-{
-    _lonProp = resolvePathProperty(_lonPathProp);
-    _latProp = resolvePathProperty(_latPathProp);
-    _altProp = resolvePathProperty(_altPathProp);
-    _headingProp = resolvePathProperty(_headingPathProp);
-    _pitchProp = resolvePathProperty(_pitchPathProp);
-    _rollProp = resolvePathProperty(_rollPathProp);
-}
-
-SGPropertyNode_ptr View::PositionAttitudeProperties::resolvePathProperty(SGPropertyNode_ptr p)
-{
-    if (!p)
-        return SGPropertyNode_ptr();
-
-    std::string path = p->getStringValue();
-    if (path.empty())
-        return SGPropertyNode_ptr();
-
-    return fgGetNode(path, true);
-}
-
-SGGeod View::PositionAttitudeProperties::position() const
-{
-    double lon = _lonProp ? _lonProp->getDoubleValue() : 0.0;
-    double lat = _latProp ? _latProp->getDoubleValue() : 0.0;
-    double alt = _altProp ? _altProp->getDoubleValue() : 0.0;
-    return SGGeod::fromDegFt(lon, lat, alt);
-}
-
-SGVec3d View::PositionAttitudeProperties::attitude() const
-{
-    double heading = _headingProp ? _headingProp->getDoubleValue() : 0.0;
-    double pitch = _pitchProp ? _pitchProp->getDoubleValue() : 0.0;
-    double roll = _rollProp ? _rollProp->getDoubleValue() : 0.0;
-    return SGVec3d(heading, pitch, roll);
-}
diff --git a/src/Viewer/viewer.hxx b/src/Viewer/viewer.hxx
deleted file mode 100644 (file)
index a215ac8..0000000
+++ /dev/null
@@ -1,453 +0,0 @@
-// viewer.hxx -- class for managing a viewer in the flightgear world.
-//
-// Written by Curtis Olson, started August 1997.
-//                          overhaul started October 2000.
-//   partially rewritten by Jim Wilson jim@kelcomaine.com using interface
-//                          by David Megginson March 2002
-//
-// Copyright (C) 1997 - 2000  Curtis L. Olson  - http://www.flightgear.org/~curt
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-//
-// $Id$
-
-
-#ifndef _VIEWER_HXX
-#define _VIEWER_HXX                                
-
-
-#include <simgear/compiler.h>
-#include <simgear/constants.h>
-
-#include <simgear/props/props.hxx>
-#include <simgear/props/tiedpropertylist.hxx>
-#include <simgear/structure/subsystem_mgr.hxx>
-#include <simgear/math/SGMath.hxx>
-
-#define FG_FOV_MIN 0.1
-#define FG_FOV_MAX 179.9
-
-namespace flightgear
-{
-
-// Define a structure containing view information
-class View : public SGSubsystem {
-
-public:
-
-    enum ScalingType {  // nominal Field Of View actually applies to ...
-       FG_SCALING_WIDTH,       // window width
-       FG_SCALING_MAX          // max(width, height)
-       // FG_SCALING_G_MEAN,      // geometric_mean(width, height)
-       // FG_SCALING_INDEPENDENT  // whole screen
-    };
-
-    enum ViewType {
-        FG_LOOKFROM = 0,
-        FG_LOOKAT = 1
-    };
-
-    static View* createFromProperties(SGPropertyNode_ptr props);
-
-    // Destructor
-    virtual ~View();
-
-    //////////////////////////////////////////////////////////////////////
-    // Part 1: standard SGSubsystem implementation.
-    //////////////////////////////////////////////////////////////////////
-
-    virtual void init ();
-    virtual void bind ();
-    virtual void unbind ();
-    virtual void update (double dt);
-
-
-    //////////////////////////////////////////////////////////////////////
-    // Part 2: user settings.
-    //////////////////////////////////////////////////////////////////////
-
-    void resetOffsetsAndFOV();
-
-    ViewType getType() const { return _type; }
-    void setType( int type );
-
-    bool getInternal() const { return _internal; }
-    void setInternal( bool internal );
-
-    // Reference geodetic position of view from position...
-    //   These are the actual aircraft position (pilot in
-    //   pilot view, model in model view).
-    //   FIXME: the model view position (ie target positions) 
-    //   should be in the model class.
-
-
-    const SGGeod& getPosition() const { return _position; }
-
-    // Reference geodetic target position...
-    const SGGeod& getTargetPosition() const { return _target; }
-
-
-
-    // Position offsets from reference
-    //   These offsets position they "eye" in the scene according to a given
-    //   location.  For example in pilot view they are used to position the 
-    //   head inside the aircraft.
-    //   Note that in pilot view these are applied "before" the orientation 
-    //   rotations (see below) so that the orientation rotations have the 
-    //   effect of the pilot staying in his seat and "looking out" in 
-    //   different directions.
-    //   In chase view these are applied "after" the application of the 
-    //   orientation rotations listed below.  This has the effect of the 
-    //   eye moving around and "looking at" the object (model) from 
-    //   different angles.
-    SGVec3d getOffset_m () const { return _offset_m; }
-    double getXOffset_m () const { return _offset_m.x(); }
-    double getYOffset_m () const { return _offset_m.y(); }
-    double getZOffset_m () const { return _offset_m.z(); }
-    double getTargetXOffset_m () const { return _target_offset_m.x(); }
-    double getTargetYOffset_m () const { return _target_offset_m.y(); }
-    double getTargetZOffset_m () const { return _target_offset_m.z(); }
-    void setXOffset_m (double x_offset_m);
-    void setYOffset_m (double y_offset_m);
-    void setZOffset_m (double z_offset_m);
-    void setTargetXOffset_m (double x_offset_m);
-    void setTargetYOffset_m (double y_offset_m);
-    void setTargetZOffset_m (double z_offset_m);
-    void setPositionOffsets (double x_offset_m,
-                                    double y_offset_m,
-                                    double z_offset_m);
-
-    // Reference orientation rotations...
-    //   These are rotations that represent the plane attitude effect on
-    //   the view (in Pilot view).  IE The view frustrum rotates as the plane
-    //   turns, pitches, and rolls.
-    //   In model view (lookat/chaseview) these end up changing the angle that
-    //   the eye is looking at the ojbect (ie the model).
-    //   FIXME: the FGModel class should have its own version of these so that
-    //   it can generate it's own model rotations.
-    double getHeading_deg () const {return _heading_deg; }
-
-
-    // Orientation offsets rotations from reference orientation.
-    // Goal settings are for smooth transition from prior
-    // offset when changing view direction.
-    //   These offsets are in ADDITION to the orientation rotations listed
-    //   above.
-    //   In pilot view they are applied after the position offsets in order to
-    //   give the effect of the pilot looking around.
-    //   In lookat view they are applied before the position offsets so that
-    //   the effect is the eye moving around looking at the object (ie the model)
-    //   from different angles.
-    double getRollOffset_deg () const { return _roll_offset_deg; }
-    double getPitchOffset_deg () const { return _pitch_offset_deg; }
-    double getHeadingOffset_deg () const { return _heading_offset_deg; }
-
-    void setGoalHeadingOffset_deg (double goal_heading_offset_deg);
-    void setHeadingOffset_deg (double heading_offset_deg);
-
-    //////////////////////////////////////////////////////////////////////
-    // Part 3: output vectors and matrices in FlightGear coordinates.
-    //////////////////////////////////////////////////////////////////////
-
-    // Vectors and positions...
-
-    const SGVec3d& get_view_pos() { if ( _dirty ) { recalc(); } return _absolute_view_pos; }
-    const SGVec3d& getViewPosition() { if ( _dirty ) { recalc(); } return _absolute_view_pos; }
-    const SGQuatd& getViewOrientation() { if ( _dirty ) { recalc(); } return mViewOrientation; }
-    const SGQuatd& getViewOrientationOffset() { if ( _dirty ) { recalc(); } return mViewOffsetOr; }
-
-    //////////////////////////////////////////////////////////////////////
-    // Part 4: View and frustrum data setters and getters
-    //////////////////////////////////////////////////////////////////////
-
-    double get_fov() const { return _fov_deg; }
-    double get_h_fov();    // Get horizontal fov, in degrees.
-    double get_v_fov();    // Get vertical fov, in degrees.
-
-    // this is currently just a wrapper for the default CameraGroups' aspect
-    double get_aspect_ratio() const;
-
-    //////////////////////////////////////////////////////////////////////
-    // Part 5: misc setters and getters
-    //////////////////////////////////////////////////////////////////////
-
-    void set_dirty() { _dirty = true; }
-
-private:
-
-    // Constructor
-    View( ViewType Type, bool from_model, int from_model_index,
-         bool at_model, int at_model_index,
-         double damp_roll, double damp_pitch, double damp_heading,
-         double x_offset_m, double y_offset_m, double z_offset_m,
-         double heading_offset_deg, double pitch_offset_deg,
-         double roll_offset_deg,
-         double fov_deg, double aspect_ratio_multiplier,
-         double target_x_offset_m, double target_y_offset_m,
-         double target_z_offset_m, double near_m, bool internal );
-
-    void set_clean() { _dirty = false; }
-    void updateData();
-
-    void setHeadingOffset_deg_property (double heading_offset_deg);
-    void setPitchOffset_deg_property(double pitch_offset_deg);
-    void setRollOffset_deg_property(double roll_offset_deg);
-
-    void setPosition (const SGGeod& geod);
-    void setTargetPosition (const SGGeod& geod);
-
-    double getAbsolutePosition_x() const;
-    double getAbsolutePosition_y() const;
-    double getAbsolutePosition_z() const;
-
-    double getRawOrientation_w() const;
-    double getRawOrientation_x() const;
-    double getRawOrientation_y() const;
-    double getRawOrientation_z() const;
-
-    // quaternion accessors, for debugging:
-    double getFrame_w() const;
-    double getFrame_x() const;
-    double getFrame_y() const;
-    double getFrame_z() const;
-
-    double getOrientation_w() const;
-    double getOrientation_x() const;
-    double getOrientation_y() const;
-    double getOrientation_z() const;
-
-    double getOrOffset_w() const;
-    double getOrOffset_x() const;
-    double getOrOffset_y() const;
-    double getOrOffset_z() const;
-
-    double getLon_deg() const;
-    double getLat_deg() const;
-    double getElev_ft() const;
-
-    // Reference orientation rotations...
-    //   These are rotations that represent the plane attitude effect on
-    //   the view (in Pilot view).  IE The view frustrum rotates as the plane
-    //   turns, pitches, and rolls.
-    //   In model view (lookat/chaseview) these end up changing the angle that
-    //   the eye is looking at the ojbect (ie the model).
-    //   FIXME: the FGModel class should have its own version of these so that
-    //   it can generate it's own model rotations.
-    double getRoll_deg () const { return _roll_deg; }
-    double getPitch_deg () const {return _pitch_deg; }
-    void setRoll_deg (double roll_deg);
-    void setPitch_deg (double pitch_deg);
-    void setHeading_deg (double heading_deg);
-    void setOrientation (double roll_deg, double pitch_deg, double heading_deg);
-    double getTargetRoll_deg () const { return _target_roll_deg; }
-    double getTargetPitch_deg () const {return _target_pitch_deg; }
-    double getTargetHeading_deg () const {return _target_heading_deg; }
-    void setTargetRoll_deg (double roll_deg);
-    void setTargetPitch_deg (double pitch_deg);
-    void setTargetHeading_deg (double heading_deg);
-    void setTargetOrientation (double roll_deg, double pitch_deg, double heading_deg);
-
-
-
-
-    // Orientation offsets rotations from reference orientation.
-    // Goal settings are for smooth transition from prior
-    // offset when changing view direction.
-    //   These offsets are in ADDITION to the orientation rotations listed
-    //   above.
-    //   In pilot view they are applied after the position offsets in order to
-    //   give the effect of the pilot looking around.
-    //   In lookat view they are applied before the position offsets so that
-    //   the effect is the eye moving around looking at the object (ie the model)
-    //   from different angles.
-    double getGoalRollOffset_deg () const { return _goal_roll_offset_deg; }
-    double getGoalPitchOffset_deg () const { return _goal_pitch_offset_deg; }
-    double getGoalHeadingOffset_deg () const {return _goal_heading_offset_deg; }
-    void setRollOffset_deg (double roll_offset_deg);
-    void setPitchOffset_deg (double pitch_offset_deg);
-    void setGoalRollOffset_deg (double goal_roll_offset_deg);
-    void setGoalPitchOffset_deg (double goal_pitch_offset_deg);
-    void setOrientationOffsets (double roll_offset_deg,
-                                double heading_offset_deg,
-                                double pitch_offset_deg);
-    
-    void set_aspect_ratio_multiplier( double m ) {
-        _aspect_ratio_multiplier = m;
-    }
-    double get_aspect_ratio_multiplier() const {
-        return _aspect_ratio_multiplier;
-    }
-
-    double getNear_m () const { return _ground_level_nearplane_m; }
-    void setNear_m (double near_m) {
-        _ground_level_nearplane_m = near_m;
-    }
-
-    void set_fov( double fov_deg ) {
-        _fov_deg = fov_deg;
-    }
-
-    //////////////////////////////////////////////////////////////////
-    // private data                                                 //
-    //////////////////////////////////////////////////////////////////
-
-    std::string _name, _typeString;
-    
-    // flag forcing a recalc of derived view parameters
-    bool _dirty;
-
-    simgear::TiedPropertyList _tiedProperties;
-
-    SGQuatd mViewOrientation;
-    SGQuatd mViewOffsetOr;
-    SGVec3d _absolute_view_pos;
-
-    SGGeod _position;
-    SGGeod _target;
-
-    double _roll_deg;
-    double _pitch_deg;
-    double _heading_deg;
-    double _target_roll_deg;
-    double _target_pitch_deg;
-    double _target_heading_deg;
-
-    double _configRollOffsetDeg,
-        _configHeadingOffsetDeg,
-        _configPitchOffsetDeg;
-
-    SGVec3d _dampTarget; ///< current target value we are damping towards
-    SGVec3d _dampOutput; ///< current output of damping filter
-    SGVec3d _dampFactor; ///< weighting of the damping filter
-    
-    // Position offsets from FDM origin.  The X axis is positive
-    // out the tail, Y is out the right wing, and Z is positive up.
-    // distance in meters
-    SGVec3d _offset_m;
-    SGVec3d _configOffset_m;
-
-    // Target offsets from FDM origin (for "lookat" targets) The X
-    // axis is positive out the tail, Y is out the right wing, and Z
-    // is positive up.  distance in meters
-    SGVec3d _target_offset_m;
-    SGVec3d _configTargetOffset_m;
-
-    // orientation offsets from reference (_goal* are for smoothed transitions)
-    double _roll_offset_deg;
-    double _pitch_offset_deg;
-    double _heading_offset_deg;
-    double _goal_roll_offset_deg;
-    double _goal_pitch_offset_deg;
-    double _goal_heading_offset_deg;
-
-    // used to set nearplane when at ground level for this view
-    double _ground_level_nearplane_m;
-
-    ViewType _type;
-    ScalingType _scaling_type;
-
-    // internal view (e.g. cockpit) flag
-    bool _internal;
-
-    // view is looking from a model
-    bool _from_model;
-    int _from_model_index;  // number of model (for multi model)
-
-    // view is looking at a model
-    bool _at_model;
-    int _at_model_index;  // number of model (for multi model)
-
-    // the nominal field of view (angle, in degrees)
-    double _fov_deg;
-    double _configFOV_deg;
-    // default = 1.0, this value is user configurable and is
-    // multiplied into the aspect_ratio to get the actual vertical fov
-    double _aspect_ratio_multiplier;
-
-    class PositionAttitudeProperties : public SGPropertyChangeListener
-    {
-    public:
-        PositionAttitudeProperties();
-        
-        void init(SGPropertyNode_ptr parent, const std::string& prefix);
-
-        virtual ~PositionAttitudeProperties();
-
-        SGGeod position() const;
-        SGVec3d attitude() const; // as heading pitch roll
-
-    protected:
-        virtual void valueChanged(SGPropertyNode* prop);
-
-    private:
-// disable copy
-        PositionAttitudeProperties(const PositionAttitudeProperties&);
-
-        SGPropertyNode_ptr resolvePathProperty(SGPropertyNode_ptr p);
-
-        SGPropertyNode_ptr _lonProp,
-            _latProp,
-            _altProp,
-            _headingProp,
-            _pitchProp,
-            _rollProp;
-        SGPropertyNode_ptr _lonPathProp,
-            _latPathProp,
-            _altPathProp,
-            _headingPathProp,
-            _pitchPathProp,
-            _rollPathProp;
-    };
-
-    PositionAttitudeProperties _eyeProperties;
-    PositionAttitudeProperties _targetProperties;
-
-    //////////////////////////////////////////////////////////////////
-    // private functions                                            //
-    //////////////////////////////////////////////////////////////////
-
-    void recalc ();
-    void recalcLookFrom();
-    void recalcLookAt();
-
-    void setDampTarget(double h, double p, double r);
-    void getDampOutput(double& roll, double& pitch, double& heading);
-    
-    void updateDampOutput(double dt);
-    
-    // add to _heading_offset_deg
-    inline void incHeadingOffset_deg( double amt ) {
-       set_dirty();
-       _heading_offset_deg += amt;
-    }
-
-    // add to _pitch_offset_deg
-    inline void incPitchOffset_deg( double amt ) {
-       set_dirty();
-       _pitch_offset_deg += amt;
-    }
-
-    // add to _roll_offset_deg
-    inline void incRollOffset_deg( double amt ) {
-       set_dirty();
-       _roll_offset_deg += amt;
-    }
-
-}; // of class View
-
-} // of namespace flightgear
-
-
-#endif // _VIEWER_HXX
index 1bc091c8c0fcfa3053087cd5d095bdaefcdc0a5c..1293523d09ef3f84773f20c2782b597bfc0da594 100644 (file)
@@ -31,7 +31,7 @@
 #include <simgear/scene/util/OsgMath.hxx>
 
 #include <Main/fg_props.hxx>
-#include "viewer.hxx"
+#include "view.hxx"
 
 #include "CameraGroup.hxx"
 
@@ -55,7 +55,7 @@ FGViewMgr::init ()
     SG_LOG(SG_VIEW, SG_WARN, "duplicate init of view manager");
     return;
   }
-  
+
   inited = true;
 
   for (unsigned int i = 0; i < config_list.size(); i++) {
@@ -85,7 +85,7 @@ FGViewMgr::shutdown()
     if (!inited) {
         return;
     }
-    
+
     inited = false;
     views.clear();
 }