From ec6888d4a4d119c11f62bc27292a8f17fb8a18af Mon Sep 17 00:00:00 2001 From: david Date: Fri, 5 Apr 2002 18:49:04 +0000 Subject: [PATCH] Viewer update from Jim Wilson: Tower View and viewer config is in place. Note that the interface is still in a state of flux. A couple of the config items (namely the offsets) are still using the old settings. The tower is hard coded into the base package for a position off the starting runway at KSFO and is probably not in the right place for there even. Looks pretty cool though! Tower View is the third view. If you aren't at KSFO you'll just see blank space in view 3. It's looking through the earth or something like that :-). Important note: zoom in with a few hits of the "x" key to see the plane better in tower view. --- src/Main/main.cxx | 11 ++-- src/Main/viewer.cxx | 77 ++++++++++++++++++-------- src/Main/viewer.hxx | 11 ++++ src/Main/viewmgr.cxx | 126 +++++++++++++++++++++++++++---------------- 4 files changed, 152 insertions(+), 73 deletions(-) diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 68c80e025..f9ad07f80 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -1379,11 +1379,6 @@ int mainLoop( int argc, char **argv ) { FGControls *controls = new FGControls; globals->set_controls( controls ); - FGViewMgr *viewmgr = new FGViewMgr; - globals->set_viewmgr( viewmgr ); - viewmgr->init(); - viewmgr->bind(); - string_list *col = new string_list; globals->set_channel_options_list( col ); @@ -1466,6 +1461,11 @@ int mainLoop( int argc, char **argv ) { SGPath modelpath( globals->get_fg_root() ); ssgModelPath( (char *)modelpath.c_str() ); + FGViewMgr *viewmgr = new FGViewMgr; + globals->set_viewmgr( viewmgr ); + viewmgr->init(); + viewmgr->bind(); + // Scene graph root scene = new ssgRoot; scene->setName( "Scene" ); @@ -1935,3 +1935,4 @@ void fgUpdateDCS (void) { // added Venky , 12 Nov 2K + diff --git a/src/Main/viewer.cxx b/src/Main/viewer.cxx index e213a1993..bed93454b 100644 --- a/src/Main/viewer.cxx +++ b/src/Main/viewer.cxx @@ -340,6 +340,36 @@ FGViewer::setOrientation (double roll_deg, double pitch_deg, double heading_deg) _heading_deg = heading_deg; } +void +FGViewer::setTargetRoll_deg (double target_roll_deg) +{ + _dirty = true; + _target_roll_deg = target_roll_deg; +} + +void +FGViewer::setTargetPitch_deg (double target_pitch_deg) +{ + _dirty = true; + _target_pitch_deg = target_pitch_deg; +} + +void +FGViewer::setTargetHeading_deg (double target_heading_deg) +{ + _dirty = true; + _target_heading_deg = target_heading_deg; +} + +void +FGViewer::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 FGViewer::setXOffset_m (double x_offset_m) { @@ -469,30 +499,30 @@ FGViewer::recalc () sgMat4 tmpROT; // temp rotation work matrices sgMat4 VIEW_HEADINGOFFSET, VIEW_PITCHOFFSET; sgVec3 tmpVec3; // temp work vector (3) - + sgVec3 eye_pos, object_pos; // The position vectors originate from the view point or target location // depending on the type of view. - // FIXME: In particular this routine will need to support both locations - // and chase view (aka lookat) is only unique in that the - // eye position is calculated in relation to the object's position. // FIXME: Later note: actually the object (target) info needs to be held // by the model class. + if (_type == FG_RPH) { - // position is the location of the pilot + // eye position is the location of the pilot recalcPositionVectors( _lon_deg, _lat_deg, _alt_ft ); - // Make the world up rotation matrix for rph - sgMakeRotMat4( UP, _lon_deg, 0.0, -_lat_deg ); } else { - // position is the location of the object being looked at + // eye position is now calculated based on lon/lat; + recalcPositionVectors( _lon_deg, _lat_deg, _alt_ft ); + sgCopyVec3(eye_pos, _relative_view_pos); + + // object position is the location of the object being looked at recalcPositionVectors( _target_lon_deg, _target_lat_deg, _target_alt_ft ); - // Make the world up rotation matrix for lookat - sgMakeRotMat4( UP, _target_lon_deg, 0.0, -_target_lat_deg ); } // the coordinates generated by the above "recalcPositionVectors" sgCopyVec3(_zero_elev, _zero_elev_view_pos); sgCopyVec3(_view_pos, _relative_view_pos); + // Make the world up rotation matrix for eye positioin... + sgMakeRotMat4( UP, _lon_deg, 0.0, -_lat_deg ); // get the world up radial vector from planet center @@ -523,21 +553,22 @@ FGViewer::recalc () sgSetVec3( position_offset, _y_offset_m, _x_offset_m, _z_offset_m ); - // Eye rotations. // Looking up/down left/right in pilot view (lookfrom mode) // or Floating Rotatation around the object in chase view (lookat mode). // Generate the offset matrix to be applied using offset angles: if (_type == FG_LOOKAT) { - // Note that when in "chase view" the offset is in relation to the - // orientation heading (_heading_deg) of the model being looked at as - // it is used to rotate around the model. + // Note that when in "lookat" view the "world up" vector is always applied + // to the viewer. World up is based on verticle at a given lon/lat (see + // matrix "UP" above). MakeVIEW_OFFSET( VIEW_OFFSET, - (_heading_offset_deg - _heading_deg) * SG_DEGREES_TO_RADIANS, _world_up, + _heading_offset_deg * SG_DEGREES_TO_RADIANS, _world_up, _pitch_offset_deg * SG_DEGREES_TO_RADIANS, right ); } if (_type == FG_RPH) { - // generate the view offset matrix using orientation offsets + // Note that when in "lookfrom" view the "view up" vector is always applied + // to the viewer. View up is based on verticle of the aircraft itself. (see + // "LOCAL" matrix above) MakeVIEW_OFFSET( VIEW_OFFSET, _heading_offset_deg * SG_DEGREES_TO_RADIANS, _view_up, _pitch_offset_deg * SG_DEGREES_TO_RADIANS, right ); @@ -549,15 +580,17 @@ FGViewer::recalc () // transfrom "offset" and "orientation offset" to vector sgXformVec3( position_offset, position_offset, UP ); + + // add heading to offset so that the eye does heading as such... + sgMakeRotMat4(tmpROT, -_heading_deg, _world_up); + sgPostMultMat4(VIEW_OFFSET, tmpROT); sgXformVec3( position_offset, position_offset, VIEW_OFFSET ); - sgVec3 object_pos, eye_pos; - // copy to coordinates to object... + // add the offsets from object to the eye position + sgAddVec3( eye_pos, eye_pos, position_offset ); + // copy object sgCopyVec3( object_pos, _view_pos ); - // add the offsets from object to the coordinates to get "eye" - sgAddVec3( eye_pos, _view_pos, position_offset ); - // Make the VIEW matrix for "lookat". sgMakeLookAtMat4( VIEW, eye_pos, object_pos, _view_up ); } @@ -759,3 +792,5 @@ FGViewer::update (int dt) } + + diff --git a/src/Main/viewer.hxx b/src/Main/viewer.hxx index 88b327419..feda79145 100644 --- a/src/Main/viewer.hxx +++ b/src/Main/viewer.hxx @@ -150,6 +150,13 @@ public: virtual void setPitch_deg (double pitch_deg); virtual void setHeading_deg (double heading_deg); virtual void setOrientation (double roll_deg, double pitch_deg, double heading_deg); + virtual double getTargetRoll_deg () const { return _target_roll_deg; } + virtual double getTargetPitch_deg () const {return _target_pitch_deg; } + virtual double getTargetHeading_deg () const {return _target_heading_deg; } + virtual void setTargetRoll_deg (double roll_deg); + virtual void setTargetPitch_deg (double pitch_deg); + virtual void setTargetHeading_deg (double heading_deg); + virtual void setTargetOrientation (double roll_deg, double pitch_deg, double heading_deg); @@ -250,6 +257,9 @@ private: double _roll_deg; double _pitch_deg; double _heading_deg; + double _target_roll_deg; + double _target_pitch_deg; + double _target_heading_deg; // Position offsets from center of gravity. The X axis is positive // out the tail, Y is out the right wing, and Z is positive up. @@ -350,3 +360,4 @@ private: + diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 110a06f59..2d8b3f7eb 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -30,6 +30,8 @@ #include "viewmgr.hxx" #include "fg_props.hxx" +// strings +string viewpath, nodepath, strdata; // Constructor FGViewMgr::FGViewMgr( void ) : @@ -47,8 +49,19 @@ FGViewMgr::~FGViewMgr( void ) { void FGViewMgr::init () { - add_view(new FGViewer, 0); - add_view(new FGViewer, 1); + char stridx [ 20 ]; + for (int i = 0; i < fgGetInt("/sim/number-views"); i++) { + nodepath = "/sim/view"; + sprintf(stridx, "[%d]", i); + nodepath += stridx; + nodepath += "/type"; + strdata = fgGetString(nodepath.c_str()); + // supporting two types now "lookat" = 1 and "lookfrom" = 1 + if ( strcmp("lookat",strdata.c_str()) == 0 ) + add_view(new FGViewer, 1); + else + add_view(new FGViewer, 0); + } } typedef double (FGViewMgr::*double_getter)() const; @@ -56,6 +69,8 @@ typedef double (FGViewMgr::*double_getter)() const; void FGViewMgr::bind () { + // FIXME: + // need to redo these bindings to the new locations (move to viewer?) fgTie("/sim/view/offset-deg", this, &FGViewMgr::getViewOffset_deg, &FGViewMgr::setViewOffset_deg); fgSetArchivable("/sim/view/offset-deg"); @@ -89,6 +104,8 @@ FGViewMgr::bind () void FGViewMgr::unbind () { + // FIXME: + // need to redo these bindings to the new locations (move to viewer?) fgUntie("/sim/view/offset-deg"); fgUntie("/sim/view/goal-offset-deg"); fgUntie("/sim/view/tilt-deg"); @@ -104,41 +121,73 @@ FGViewMgr::unbind () void FGViewMgr::update (int dt) { + char stridx [20]; + FGViewer * view = get_current_view(); if (view == 0) return; - // Grab some values we'll need. - double lon_rad = fgGetDouble("/position/longitude-deg") - * SGD_DEGREES_TO_RADIANS; - double lat_rad = fgGetDouble("/position/latitude-deg") - * SGD_DEGREES_TO_RADIANS; - double alt_m = fgGetDouble("/position/altitude-ft") - * SG_FEET_TO_METER; - double roll_rad = fgGetDouble("/orientation/roll-deg") - * SGD_DEGREES_TO_RADIANS; - double pitch_rad = fgGetDouble("/orientation/pitch-deg") - * SGD_DEGREES_TO_RADIANS; - double heading_rad = fgGetDouble("/orientation/heading-deg") - * SGD_DEGREES_TO_RADIANS; - - // Set up the pilot view - FGViewer *pilot_view = (FGViewer *)get_view( 0 ); - pilot_view ->setPosition( - fgGetDouble("/position/longitude-deg"), - fgGetDouble("/position/latitude-deg"), - fgGetDouble("/position/altitude-ft")); - pilot_view->setOrientation( - fgGetDouble("/orientation/roll-deg"), - fgGetDouble("/orientation/pitch-deg"), - fgGetDouble("/orientation/heading-deg")); - if (!strcmp(fgGetString("/sim/flight-model"), "ada")) { - //+ve x is aft, +ve z is up (see viewer.hxx) - pilot_view->setPositionOffsets( -5.0, 0.0, 1.0 ); + for (int i = 0; i < fgGetInt("/sim/number-views"); i++) { + viewpath = "/sim/view"; + sprintf(stridx, "[%d]", i); + viewpath += stridx; + + + FGViewer *loop_view = (FGViewer *)get_view( i ); + + // Set up view + nodepath = viewpath; + nodepath += "/config/eye-lon-deg-path"; + double lon_deg = fgGetDouble(fgGetString(nodepath.c_str())); + nodepath = viewpath; + nodepath += "/config/eye-lat-deg-path"; + double lat_deg = fgGetDouble(fgGetString(nodepath.c_str())); + nodepath = viewpath; + nodepath += "/config/eye-alt-ft-path"; + double alt_ft = fgGetDouble(fgGetString(nodepath.c_str())); + nodepath = viewpath; + nodepath += "/config/eye-roll-deg-path"; + double roll_deg = fgGetDouble(fgGetString(nodepath.c_str())); + nodepath = viewpath; + nodepath += "/config/eye-pitch-deg-path"; + double pitch_deg = fgGetDouble(fgGetString(nodepath.c_str())); + nodepath = viewpath; + nodepath += "/config/eye-heading-deg-path"; + double heading_deg = fgGetDouble(fgGetString(nodepath.c_str())); + + loop_view->setPosition(lon_deg, lat_deg, alt_ft); + loop_view->setOrientation(roll_deg, pitch_deg, heading_deg); + + // if lookat (type 1) then get target data... + if (loop_view->getType() == 1) { + nodepath = viewpath; + nodepath += "/config/target-lon-deg-path"; + lon_deg = fgGetDouble(fgGetString(nodepath.c_str())); + nodepath = viewpath; + nodepath += "/config/target-lat-deg-path"; + lat_deg = fgGetDouble(fgGetString(nodepath.c_str())); + nodepath = viewpath; + nodepath += "/config/target-alt-ft-path"; + alt_ft = fgGetDouble(fgGetString(nodepath.c_str())); + nodepath = viewpath; + nodepath += "/config/target-roll-deg-path"; + roll_deg = fgGetDouble(fgGetString(nodepath.c_str())); + nodepath = viewpath; + nodepath += "/config/target-pitch-deg-path"; + pitch_deg = fgGetDouble(fgGetString(nodepath.c_str())); + nodepath = viewpath; + nodepath += "/config/target-heading-deg-path"; + heading_deg = fgGetDouble(fgGetString(nodepath.c_str())); + + loop_view ->setTargetPosition(lon_deg, lat_deg, alt_ft); + loop_view->setTargetOrientation(roll_deg, pitch_deg, heading_deg); + } } // Set up the chase view - + // FIXME: + // Gotta change sgVec3Slider so that it takes xyz values as inputs + // instead of spherical coordinates. FGViewer *chase_view = (FGViewer *)get_view( 1 ); // get xyz Position offsets directly from GUI/sgVec3Slider @@ -150,19 +199,6 @@ FGViewMgr::update (int dt) sgCopyVec3( zPO, *pPO ); chase_view->setPositionOffsets(zPO[1], zPO[0], zPO[2] ); - chase_view->setOrientation( - fgGetDouble("/orientation/roll-deg"), - fgGetDouble("/orientation/pitch-deg"), - fgGetDouble("/orientation/heading-deg")); - chase_view ->setPosition( - fgGetDouble("/position/longitude-deg"), - fgGetDouble("/position/latitude-deg"), - fgGetDouble("/position/altitude-ft")); - chase_view ->setTargetPosition( - fgGetDouble("/position/longitude-deg"), - fgGetDouble("/position/latitude-deg"), - fgGetDouble("/position/altitude-ft")); - // Update the current view do_axes(); view->update(dt); @@ -369,7 +405,3 @@ FGViewMgr::do_axes () get_current_view()->setGoalHeadingOffset_deg(viewDir); } - - - - -- 2.39.5