#include "viewmgr.hxx"
-#include <string.h> // strcmp
+#include <string.h> // strcmp
#include <simgear/compiler.h>
-#include <simgear/sound/soundmgr_openal.hxx>
#include <Main/fg_props.hxx>
#include "viewer.hxx"
abs_viewer_position(SGVec3d::zeros()),
current(0),
current_view_orientation(SGQuatd::zeros()),
- current_view_or_offset(SGQuatd::zeros()),
- smgr(globals->get_soundmgr())
+ current_view_or_offset(SGQuatd::zeros())
{
+ globals->set_viewmgr(this);
}
// Destructor
-FGViewMgr::~FGViewMgr( void ) {
+FGViewMgr::~FGViewMgr( void )
+{
+ globals->set_viewmgr(NULL);
}
void
inited = true;
+ // stash properties
+ current_x_offs = fgGetNode("/sim/current-view/x-offset-m", true);
+ current_y_offs = fgGetNode("/sim/current-view/y-offset-m", true);
+ current_z_offs = fgGetNode("/sim/current-view/z-offset-m", true);
+ target_x_offs = fgGetNode("/sim/current-view/target-x-offset-m", true);
+ target_y_offs = fgGetNode("/sim/current-view/target-y-offset-m", true);
+ target_z_offs = fgGetNode("/sim/current-view/target-z-offset-m", true);
+
double aspect_ratio_multiplier
= fgGetDouble("/sim/current-view/aspect-ratio-multiplier");
for (unsigned int i = 0; i < config_list.size(); i++) {
SGPropertyNode *n = config_list[i];
+ SGPropertyNode *config = n->getChild("config", 0, true);
// find out if this is an internal view (e.g. in cockpit, low near plane)
bool internal = n->getBoolValue("internal", false);
// model-from-type as well.
// find out if this is a model we are looking from...
- bool from_model = n->getBoolValue("config/from-model");
- int from_model_index = n->getIntValue("config/from-model-idx");
+ bool from_model = config->getBoolValue("from-model");
+ int from_model_index = config->getIntValue("from-model-idx");
- double x_offset_m = n->getDoubleValue("config/x-offset-m");
- double y_offset_m = n->getDoubleValue("config/y-offset-m");
- double z_offset_m = n->getDoubleValue("config/z-offset-m");
+ 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 = n->getDoubleValue("config/heading-offset-deg");
- n->setDoubleValue("config/heading-offset-deg", heading_offset_deg);
- double pitch_offset_deg = n->getDoubleValue("config/pitch-offset-deg");
- n->setDoubleValue("config/pitch-offset-deg", pitch_offset_deg);
- double roll_offset_deg = n->getDoubleValue("config/roll-offset-deg");
- n->setDoubleValue("config/roll-offset-deg", roll_offset_deg);
+ 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 = n->getDoubleValue("config/default-field-of-view-deg");
- double near_m = n->getDoubleValue("config/ground-level-nearplane-m");
+ double fov_deg = config->getDoubleValue("default-field-of-view-deg");
+ double near_m = config->getDoubleValue("ground-level-nearplane-m");
// supporting two types "lookat" = 1 and "lookfrom" = 0
const char *type = n->getStringValue("type");
if (!strcmp(type, "lookat")) {
- bool at_model = n->getBoolValue("config/at-model");
- int at_model_index = n->getIntValue("config/at-model-idx");
+ bool at_model = config->getBoolValue("at-model");
+ int at_model_index = config->getIntValue("at-model-idx");
- double damp_roll = n->getDoubleValue("config/at-model-roll-damping");
- double damp_pitch = n->getDoubleValue("config/at-model-pitch-damping");
- double damp_heading = n->getDoubleValue("config/at-model-heading-damping");
+ 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 = n->getDoubleValue("config/target-x-offset-m");
- double target_y_offset_m = n->getDoubleValue("config/target-y-offset-m");
- double target_z_offset_m = n->getDoubleValue("config/target-z-offset-m");
+ 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");
add_view(new FGViewer ( FG_LOOKAT, from_model, from_model_index,
at_model, at_model_index,
do_bind();
}
+void
+FGViewMgr::shutdown()
+{
+ if (!inited) {
+ return;
+ }
+
+ inited = false;
+}
+
void
FGViewMgr::reinit ()
{
+ int current_view_index = current;
+
// reset offsets and fov to configuration defaults
for (unsigned int i = 0; i < config_list.size(); i++) {
SGPropertyNode *n = config_list[i];
fgSetDouble("/sim/current-view/target-z-offset-m",
n->getDoubleValue("config/target-z-offset-m"));
}
- setView(0);
+ setView(current_view_index);
}
typedef double (FGViewMgr::*double_getter)() const;
void
FGViewMgr::do_bind()
-{
- velocityNorthFPS = fgGetNode("velocities/speed-north-fps", true);
- velocityEastFPS = fgGetNode("velocities/speed-east-fps", true);
- velocityDownFPS = fgGetNode("velocities/speed-down-fps", true);
-
+{
// these are bound to the current view properties
_tiedProperties.setRoot(fgGetNode("/sim/current-view", true));
_tiedProperties.Tie("heading-offset-deg", this,
_tiedProperties.Tie("view-number", this,
&FGViewMgr::getView, &FGViewMgr::setView);
- fgSetArchivable("/sim/current-view/view-number", false);
+ SGPropertyNode* view_number =
+ _tiedProperties.getRoot()->getNode("view-number");
+ view_number->setAttribute(SGPropertyNode::ARCHIVE, false);
+
+ // Keep view on reset/reinit
+ view_number->setAttribute(SGPropertyNode::PRESERVE, true);
_tiedProperties.Tie("axes/long", this,
(double_getter)0, &FGViewMgr::setViewAxisLong);
_tiedProperties.Tie(n->getNode("viewer-y-m", true),SGRawValuePointer<double>(&abs_viewer_position[1]));
_tiedProperties.Tie(n->getNode("viewer-z-m", true),SGRawValuePointer<double>(&abs_viewer_position[2]));
+ _tiedProperties.Tie("viewer-lon-deg", this, &FGViewMgr::getViewLon_deg);
+ _tiedProperties.Tie("viewer-lat-deg", this, &FGViewMgr::getViewLat_deg);
+ _tiedProperties.Tie("viewer-elev-ft", this, &FGViewMgr::getViewElev_ft);
+
+
_tiedProperties.Tie("debug/orientation-w", this,
&FGViewMgr::getCurrentViewOrientation_w);
_tiedProperties.Tie("debug/orientation-x", this,
FGViewMgr::unbind ()
{
_tiedProperties.Untie();
+ config_list.clear();
+ view_number.clear();
}
void
FGViewMgr::update (double dt)
{
- FGViewer *loop_view = (FGViewer *)get_current_view();
- if (loop_view == 0) return;
+ FGViewer* currentView = (FGViewer *)get_current_view();
+ if (!currentView) return;
SGPropertyNode *n = config_list[current];
+ SGPropertyNode *config = n->getChild("config", 0, true);
double lon_deg, lat_deg, alt_ft, roll_deg, pitch_deg, heading_deg;
// Set up view location and orientation
- if (!n->getBoolValue("config/from-model")) {
- lon_deg = fgGetDouble(n->getStringValue("config/eye-lon-deg-path"));
- lat_deg = fgGetDouble(n->getStringValue("config/eye-lat-deg-path"));
- alt_ft = fgGetDouble(n->getStringValue("config/eye-alt-ft-path"));
- roll_deg = fgGetDouble(n->getStringValue("config/eye-roll-deg-path"));
- pitch_deg = fgGetDouble(n->getStringValue("config/eye-pitch-deg-path"));
- heading_deg = fgGetDouble(n->getStringValue("config/eye-heading-deg-path"));
+ if (!config->getBoolValue("from-model")) {
+ lon_deg = fgGetDouble(config->getStringValue("eye-lon-deg-path"));
+ lat_deg = fgGetDouble(config->getStringValue("eye-lat-deg-path"));
+ alt_ft = fgGetDouble(config->getStringValue("eye-alt-ft-path"));
+ roll_deg = fgGetDouble(config->getStringValue("eye-roll-deg-path"));
+ pitch_deg = fgGetDouble(config->getStringValue("eye-pitch-deg-path"));
+ heading_deg = fgGetDouble(config->getStringValue("eye-heading-deg-path"));
- loop_view->setPosition(lon_deg, lat_deg, alt_ft);
- loop_view->setOrientation(roll_deg, pitch_deg, heading_deg);
+ currentView->setPosition(lon_deg, lat_deg, alt_ft);
+ currentView->setOrientation(roll_deg, pitch_deg, heading_deg);
} else {
// force recalc in viewer
- loop_view->set_dirty();
+ currentView->set_dirty();
}
// if lookat (type 1) then get target data...
- if (loop_view->getType() == FG_LOOKAT) {
- if (!n->getBoolValue("config/from-model")) {
- lon_deg = fgGetDouble(n->getStringValue("config/target-lon-deg-path"));
- lat_deg = fgGetDouble(n->getStringValue("config/target-lat-deg-path"));
- alt_ft = fgGetDouble(n->getStringValue("config/target-alt-ft-path"));
- roll_deg = fgGetDouble(n->getStringValue("config/target-roll-deg-path"));
- pitch_deg = fgGetDouble(n->getStringValue("config/target-pitch-deg-path"));
- heading_deg = fgGetDouble(n->getStringValue("config/target-heading-deg-path"));
-
- loop_view->setTargetPosition(lon_deg, lat_deg, alt_ft);
- loop_view->setTargetOrientation(roll_deg, pitch_deg, heading_deg);
+ if (currentView->getType() == FG_LOOKAT) {
+ if (!config->getBoolValue("from-model")) {
+ lon_deg = fgGetDouble(config->getStringValue("target-lon-deg-path"));
+ lat_deg = fgGetDouble(config->getStringValue("target-lat-deg-path"));
+ alt_ft = fgGetDouble(config->getStringValue("target-alt-ft-path"));
+ roll_deg = fgGetDouble(config->getStringValue("target-roll-deg-path"));
+ pitch_deg = fgGetDouble(config->getStringValue("target-pitch-deg-path"));
+ heading_deg = fgGetDouble(config->getStringValue("target-heading-deg-path"));
+
+ currentView->setTargetPosition(lon_deg, lat_deg, alt_ft);
+ currentView->setTargetOrientation(roll_deg, pitch_deg, heading_deg);
} else {
- loop_view->set_dirty();
+ currentView->set_dirty();
}
}
- setViewXOffset_m(fgGetDouble("/sim/current-view/x-offset-m"));
- setViewYOffset_m(fgGetDouble("/sim/current-view/y-offset-m"));
- setViewZOffset_m(fgGetDouble("/sim/current-view/z-offset-m"));
+ setViewXOffset_m(current_x_offs->getDoubleValue());
+ setViewYOffset_m(current_y_offs->getDoubleValue());
+ setViewZOffset_m(current_z_offs->getDoubleValue());
- setViewTargetXOffset_m(fgGetDouble("/sim/current-view/target-x-offset-m"));
- setViewTargetYOffset_m(fgGetDouble("/sim/current-view/target-y-offset-m"));
- setViewTargetZOffset_m(fgGetDouble("/sim/current-view/target-z-offset-m"));
+ setViewTargetXOffset_m(target_x_offs->getDoubleValue());
+ setViewTargetYOffset_m(target_y_offs->getDoubleValue());
+ setViewTargetZOffset_m(target_z_offs->getDoubleValue());
- current_view_orientation = loop_view->getViewOrientation();
- current_view_or_offset = loop_view->getViewOrientationOffset();
+ current_view_orientation = currentView->getViewOrientation();
+ current_view_or_offset = currentView->getViewOrientationOffset();
// Update the current view
do_axes();
- loop_view->update(dt);
- abs_viewer_position = loop_view->getViewPosition();
-
- // update audio listener values
- // set the viewer position in Cartesian coordinates in meters
- smgr->set_position( abs_viewer_position, loop_view->getPosition() );
- smgr->set_orientation( current_view_orientation );
-
- // get the model velocity
- SGVec3d velocity = SGVec3d::zeros();
- if ( !stationary() ) {
- velocity = SGVec3d( velocityNorthFPS->getDoubleValue(),
- velocityEastFPS->getDoubleValue(),
- velocityDownFPS->getDoubleValue() );
+ currentView->update(dt);
+ abs_viewer_position = currentView->getViewPosition();
+
+ // expose the raw (OpenGL) orientation to the property tree,
+ // for the sound-manager
+ for (int i=0; i<4; ++i) {
+ _tiedProperties.getRoot()->getChild("raw-orientation", i, true)->setDoubleValue(current_view_orientation[i]);
}
- smgr->set_velocity( velocity );
}
void
FGViewMgr::copyToCurrent()
{
- if (!inited) {
- return;
- }
+ if (!inited) {
+ return;
+ }
SGPropertyNode *n = config_list[current];
fgSetString("/sim/current-view/name", n->getStringValue("name"));
void FGViewMgr::clear()
{
- views.clear();
+ views.clear();
}
FGViewer*
FGViewMgr::get_current_view()
{
- if ( current < (int)views.size() ) {
- return views[current];
- } else {
- return NULL;
- }
+ if ( current < (int)views.size() ) {
+ return views[current];
+ } else {
+ return NULL;
+ }
}
const FGViewer*
FGViewMgr::get_current_view() const
{
- if ( current < (int)views.size() ) {
- return views[current];
- } else {
- return NULL;
- }
+ if ( current < (int)views.size() ) {
+ return views[current];
+ } else {
+ return NULL;
+ }
}
FGViewer*
FGViewMgr::get_view( int i )
{
- if ( i < 0 ) { i = 0; }
- if ( i >= (int)views.size() ) { i = views.size() - 1; }
- return views[i];
+ if ( i < 0 ) { i = 0; }
+ if ( i >= (int)views.size() ) { i = views.size() - 1; }
+ return views[i];
}
const FGViewer*
FGViewMgr::get_view( int i ) const
{
- if ( i < 0 ) { i = 0; }
- if ( i >= (int)views.size() ) { i = views.size() - 1; }
- return views[i];
+ if ( i < 0 ) { i = 0; }
+ if ( i >= (int)views.size() ) { i = views.size() - 1; }
+ return views[i];
}
FGViewer*
FGViewMgr::next_view()
{
- setView((current+1 < (int)views.size()) ? (current + 1) : 0);
- view_number->fireValueChanged();
- return views[current];
+ setView((current+1 < (int)views.size()) ? (current + 1) : 0);
+ view_number->fireValueChanged();
+ return views[current];
}
FGViewer*
FGViewMgr::prev_view()
{
- setView((0 < current) ? (current - 1) : (views.size() - 1));
- view_number->fireValueChanged();
- return views[current];
+ setView((0 < current) ? (current - 1) : (views.size() - 1));
+ view_number->fireValueChanged();
+ return views[current];
}
void
}
}
-bool
-FGViewMgr::stationary () const
-{
- const FGViewer * view = get_current_view();
- if (view != 0) {
- if (((FGViewer *)view)->getXOffset_m() == 0.0 &&
- ((FGViewer *)view)->getYOffset_m() == 0.0 &&
- ((FGViewer *)view)->getZOffset_m() == 0.0)
- return true;
- }
-
- return false;
-}
-
double
FGViewMgr::getViewTargetXOffset_m () const
{
axis_lat = axis;
}
+double
+FGViewMgr::getViewLon_deg() const
+{
+ const FGViewer* view = get_current_view();
+ return (view != NULL) ? view->getPosition().getLongitudeDeg() : 0.0;
+}
+
+double
+FGViewMgr::getViewLat_deg() const
+{
+ const FGViewer* view = get_current_view();
+ return (view != NULL) ? view->getPosition().getLatitudeDeg() : 0.0;
+}
+
+double
+FGViewMgr::getViewElev_ft() const
+{
+ const FGViewer* view = get_current_view();
+ return (view != NULL) ? view->getPosition().getElevationFt() : 0.0;
+}
+
+
// reference frame orientation.
// This is the view orientation you get when you have no
// view offset, i.e. the offset operator is the identity.
void
FGViewMgr::do_axes ()
{
- // Take no action when hat is centered
+ // Take no action when hat is centered
if ( ( axis_long < 0.01 ) &&
( axis_long > -0.01 ) &&
( axis_lat < 0.01 ) &&
double viewDir = 999;
/* Do all the quick and easy cases */
- if (axis_long < 0) { // Longitudinal axis forward
+ if (axis_long < 0) { // Longitudinal axis forward
if (axis_lat == axis_long)
viewDir = fgGetDouble("/sim/view/config/front-left-direction-deg");
else if (axis_lat == - axis_long)
viewDir = fgGetDouble("/sim/view/config/front-right-direction-deg");
else if (axis_lat == 0)
viewDir = fgGetDouble("/sim/view/config/front-direction-deg");
- } else if (axis_long > 0) { // Longitudinal axis backward
+ } else if (axis_long > 0) { // Longitudinal axis backward
if (axis_lat == - axis_long)
viewDir = fgGetDouble("/sim/view/config/back-left-direction-deg");
else if (axis_lat == axis_long)
viewDir = fgGetDouble("/sim/view/config/back-right-direction-deg");
else if (axis_lat == 0)
viewDir = fgGetDouble("/sim/view/config/back-direction-deg");
- } else if (axis_long == 0) { // Longitudinal axis neutral
+ } else if (axis_long == 0) { // Longitudinal axis neutral
if (axis_lat < 0)
viewDir = fgGetDouble("/sim/view/config/left-direction-deg");
else if (axis_lat > 0)
else return; /* And assertion failure maybe? */
}
- // Do all the difficult cases
+ // Do all the difficult cases
if ( viewDir > 900 )
viewDir = SGD_RADIANS_TO_DEGREES * atan2 ( -axis_lat, -axis_long );
if ( viewDir < -1 ) viewDir += 360;