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.
This commit is contained in:
parent
9d6011aa69
commit
ec6888d4a4
4 changed files with 151 additions and 72 deletions
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
for (int i = 0; i < fgGetInt("/sim/number-views"); i++) {
|
||||
viewpath = "/sim/view";
|
||||
sprintf(stridx, "[%d]", i);
|
||||
viewpath += stridx;
|
||||
|
||||
// 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 );
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue