From 65d50389626a72a22f609369a35ce6c50293f2b2 Mon Sep 17 00:00:00 2001 From: James Turner Date: Wed, 20 Jan 2016 20:54:26 -0500 Subject: [PATCH] Tie view orientations directly - remove need for cached orientations in view-manager --- src/Viewer/viewer.cxx | 160 +++++++++++++++++++++++++++++++++++++++++ src/Viewer/viewer.hxx | 23 +++++- src/Viewer/viewmgr.cxx | 137 +---------------------------------- src/Viewer/viewmgr.hxx | 24 ------- 4 files changed, 183 insertions(+), 161 deletions(-) diff --git a/src/Viewer/viewer.cxx b/src/Viewer/viewer.cxx index c3098b22d..331f41b4b 100644 --- a/src/Viewer/viewer.cxx +++ b/src/Viewer/viewer.cxx @@ -249,6 +249,34 @@ View::bind () false /* do not set current property value */); fgSetArchivable("/sim/current-view/goal-roll-offset-deg"); +// 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); + // following config properties are exposed on current-view but don't change, // so we can simply copy them here. _tiedProperties.getRoot()->setStringValue("name", _name); @@ -871,6 +899,138 @@ View::update (double dt) recalc(); } +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(); diff --git a/src/Viewer/viewer.hxx b/src/Viewer/viewer.hxx index 3258b323c..30d339f65 100644 --- a/src/Viewer/viewer.hxx +++ b/src/Viewer/viewer.hxx @@ -252,7 +252,28 @@ private: void setPosition (const SGGeod& geod); void setTargetPosition (const SGGeod& geod); - + + 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; + ////////////////////////////////////////////////////////////////// // private data // ////////////////////////////////////////////////////////////////// diff --git a/src/Viewer/viewmgr.cxx b/src/Viewer/viewmgr.cxx index 0d2ed5546..6c35fd554 100644 --- a/src/Viewer/viewmgr.cxx +++ b/src/Viewer/viewmgr.cxx @@ -45,9 +45,7 @@ FGViewMgr::FGViewMgr( void ) : view_number(fgGetNode("/sim/current-view/view-number", true)), config_list(fgGetNode("/sim", true)->getChildren("view")), abs_viewer_position(SGVec3d::zeros()), - current(0), - current_view_orientation(SGQuatd::zeros()), - current_view_or_offset(SGQuatd::zeros()) + current(0) { } @@ -170,34 +168,6 @@ FGViewMgr::do_bind() _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::getCurrentViewOrientation_x); - _tiedProperties.Tie("debug/orientation-y", this, - &FGViewMgr::getCurrentViewOrientation_y); - _tiedProperties.Tie("debug/orientation-z", this, - &FGViewMgr::getCurrentViewOrientation_z); - - _tiedProperties.Tie("debug/orientation_offset-w", this, - &FGViewMgr::getCurrentViewOrOffset_w); - _tiedProperties.Tie("debug/orientation_offset-x", this, - &FGViewMgr::getCurrentViewOrOffset_x); - _tiedProperties.Tie("debug/orientation_offset-y", this, - &FGViewMgr::getCurrentViewOrOffset_y); - _tiedProperties.Tie("debug/orientation_offset-z", this, - &FGViewMgr::getCurrentViewOrOffset_z); - - _tiedProperties.Tie("debug/frame-w", this, - &FGViewMgr::getCurrentViewFrame_w); - _tiedProperties.Tie("debug/frame-x", this, - &FGViewMgr::getCurrentViewFrame_x); - _tiedProperties.Tie("debug/frame-y", this, - &FGViewMgr::getCurrentViewFrame_y); - _tiedProperties.Tie("debug/frame-z", this, - &FGViewMgr::getCurrentViewFrame_z); } void @@ -239,9 +209,6 @@ FGViewMgr::update (double dt) setViewTargetYOffset_m(target_y_offs->getDoubleValue()); setViewTargetZOffset_m(target_z_offs->getDoubleValue()); - current_view_orientation = currentView->getViewOrientation(); - current_view_or_offset = currentView->getViewOrientationOffset(); - // Update the current view do_axes(); currentView->update(dt); @@ -254,12 +221,6 @@ FGViewMgr::update (double dt) toOsg(currentView->getViewOrientation())); cameraGroup->setCameraParameters(currentView->get_v_fov(), cameraGroup->getMasterAspectRatio()); - - // 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]); - } } void FGViewMgr::clear() @@ -571,102 +532,6 @@ FGViewMgr::getViewElev_ft() const 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. -// -// 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 FGViewMgr::getCurrentViewFrame_w() const{ - return ((current_view_orientation*conj(fsb2sta())*conj(current_view_or_offset))).w(); -} -double FGViewMgr::getCurrentViewFrame_x() const{ - return ((current_view_orientation*conj(fsb2sta())*conj(current_view_or_offset))).x(); -} -double FGViewMgr::getCurrentViewFrame_y() const{ - return ((current_view_orientation*conj(fsb2sta())*conj(current_view_or_offset))).y(); -} -double FGViewMgr::getCurrentViewFrame_z() const{ - return ((current_view_orientation*conj(fsb2sta())*conj(current_view_or_offset))).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 FGViewMgr::getCurrentViewOrOffset_w() const{ - return current_view_or_offset.w(); -} -double FGViewMgr::getCurrentViewOrOffset_x() const{ - return current_view_or_offset.x(); -} -double FGViewMgr::getCurrentViewOrOffset_y() const{ - return current_view_or_offset.y(); -} -double FGViewMgr::getCurrentViewOrOffset_z() const{ - return current_view_or_offset.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 FGViewMgr::getCurrentViewOrientation_w() const{ - return (current_view_orientation * conj(fsb2sta())).w(); -} -double FGViewMgr::getCurrentViewOrientation_x() const{ - return (current_view_orientation * conj(fsb2sta())).x(); -} -double FGViewMgr::getCurrentViewOrientation_y() const{ - return (current_view_orientation * conj(fsb2sta())).y(); -} -double FGViewMgr::getCurrentViewOrientation_z() const{ - return (current_view_orientation * conj(fsb2sta())).z(); -} - void FGViewMgr::do_axes () { diff --git a/src/Viewer/viewmgr.hxx b/src/Viewer/viewmgr.hxx index 32a9e63f4..74b4acf08 100644 --- a/src/Viewer/viewmgr.hxx +++ b/src/Viewer/viewmgr.hxx @@ -116,20 +116,6 @@ private: double getViewLon_deg() const; double getViewLat_deg() const; double getViewElev_ft() const; - -// quaternion accessors, for debugging: - double getCurrentViewOrientation_w() const; - double getCurrentViewOrientation_x() const; - double getCurrentViewOrientation_y() const; - double getCurrentViewOrientation_z() const; - double getCurrentViewOrOffset_w() const; - double getCurrentViewOrOffset_x() const; - double getCurrentViewOrOffset_y() const; - double getCurrentViewOrOffset_z() const; - double getCurrentViewFrame_w() const; - double getCurrentViewFrame_x() const; - double getCurrentViewFrame_y() const; - double getCurrentViewFrame_z() const; bool inited; SGPropertyNode_ptr view_number; @@ -139,20 +125,10 @@ private: SGVec3d abs_viewer_position; int current; - SGQuatd current_view_orientation, current_view_or_offset; SGPropertyNode_ptr current_x_offs, current_y_offs, current_z_offs; SGPropertyNode_ptr target_x_offs, target_y_offs, target_z_offs; }; -// 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. -inline const SGQuatd fsb2sta() -{ - return SGQuatd(-0.5, -0.5, 0.5, 0.5); -} #endif // _VIEWMGR_HXX -- 2.39.5