Major viewer-code overhaul from Jim Wilson:
Description: This update includes the new viewer interface as proposed by David M. and a first pass at cleaning up the viewer/view manager code by Jim W. Note that I have dropped Main/viewer_lookat.?xx and Main/viewer_rph.?xx and modified the Makefile.am accordingly. Detail of work: Overall: The code reads a little easier. There are still some unnecessary bits in there and I'd like to supplement the comments in the viewer.hxx with a tiny bit on each interface group and what the groupings mean (similar but briefer than what you emailed me the other day). I tried not to mess up the style, but there is an occasional inconsistency. In general I wouldn't call it done (especially since there's no tower yet! :)), but I'd like to get this out there so others can comment, and test. In Viewer: The interface as you suggested has been implemented. Basically everything seems to work as it did visually. There is no difference that I can see in performance, although some things might be a tiny bit faster. I've merged the lookat and rph (pilot view) code into the recalc for the viewer. There is still some redundancy between the two, but a lot has been removed. In some cases I've taken some code that we'd likely want to inline anyway and left it in there in duplicate. You'll see that the code for both looks a little cleaner. I need to take a closer look at the rotations in particular. I've cleaned up a little there, but I suspect more can be done to streamline this. The external declaration to the Quat_mat in mouse.cxx has been removed. IMHO the quat doesn't serve any intrinsic purpose in mouse.cxx, but I'm not about to rip it out. It would seem that there more conventional ways to get spherical data that are just as fast. In any case all the viewer was pulling from the quat matrix was the pitch value so I modified mouse.cxx to output to our pitchOffset input and that works fine. I've changed the native values to degrees from radians where appropriate. This required a conversion from degrees to radians in a couple modules that access the interface. Perhaps we should add interface calls that do the conversion, e.g. a getHeadingOffset_rad() to go along with the getHeadingOffset_deg(). On the view_offset (now headingOffset) thing there are two entry points because of the ability to instantly switch views or to scroll to a new view angle (by hitting the numeric keys for example). This leaves an anomaly in the interface which should be resolved by adding "goal" settings to the interface, e.g. a setGoalHeadingOffset_deg(), setGoalPitchOffset_deg(), etc. Other than these two issues, the next step here will be to look at some further optimizations, and to write support code for a tower view. That should be fairly simple at this point. I was considering creating a "simulated tower view" or "pedestrian view" that defaulted to a position off to the right of whereever the plane is at the moment you switch to the tower view. This could be a fall back when we don't have an actual tower location at hand (as would be the case with rural airports). ViewManager: Basically all I did here was neaten things up by ripping out excess crap and made it compatible as is with the new interface. The result is that viewmanager is now ready to be developed. The two preexisting views are still hardcoded into the view manager. The next step would be to design configuration xml (eg /sim/view[x]/config/blahblah) that could be used to set up as many views as we want. If we want to take the easy way out, we might want to insist that view[0] be a pilot-view and have viewmanager check for that.
This commit is contained in:
parent
99fa3a6e79
commit
4d4cd16012
14 changed files with 836 additions and 376 deletions
|
@ -259,7 +259,7 @@ float get_climb_rate( void )
|
|||
|
||||
float get_view_direction( void )
|
||||
{
|
||||
double view_off = SGD_2PI - globals->get_current_view()->get_view_offset();
|
||||
double view_off = SGD_2PI - globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS;
|
||||
double view = ( current_aircraft.fdm_state->get_Psi() + view_off)
|
||||
* SGD_RADIANS_TO_DEGREES;
|
||||
|
||||
|
@ -745,3 +745,4 @@ void fgCockpitUpdate( void ) {
|
|||
|
||||
glViewport( 0, 0, iwidth, iheight );
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ fgPanelVisible ()
|
|||
return false;
|
||||
if(globals->get_viewmgr()->get_current() != 0)
|
||||
return false;
|
||||
if(globals->get_current_view()->get_view_offset() != 0 &&
|
||||
if(globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS != 0 &&
|
||||
!fgGetBool("/sim/virtual-cockpit"))
|
||||
return false;
|
||||
return true;
|
||||
|
@ -452,8 +452,8 @@ FGPanel::setupVirtualCockpit()
|
|||
// Generate a "look at" matrix using OpenGL (!) coordinate
|
||||
// conventions.
|
||||
float lookat[3];
|
||||
float pitch = view->get_view_tilt();
|
||||
float rot = view->get_view_offset();
|
||||
float pitch = view->getPitchOffset_deg() * SGD_DEGREES_TO_RADIANS;
|
||||
float rot = view->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS;
|
||||
lookat[0] = -sin(rot);
|
||||
lookat[1] = sin(pitch) / cos(pitch);
|
||||
lookat[2] = -cos(rot);
|
||||
|
@ -1150,3 +1150,4 @@ FGSwitchLayer::draw ()
|
|||
// end of panel.cxx
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -175,20 +175,30 @@ static inline int right_button( void ) {
|
|||
|
||||
static inline void set_goal_view_offset( float offset )
|
||||
{
|
||||
globals->get_current_view()->set_goal_view_offset(offset);
|
||||
globals->get_current_view()->set_goal_view_offset(offset * SGD_RADIANS_TO_DEGREES);
|
||||
}
|
||||
|
||||
static inline void set_view_offset( float offset )
|
||||
{
|
||||
globals->get_current_view()->set_view_offset(offset);
|
||||
globals->get_current_view()->setHeadingOffset_deg(offset * SGD_RADIANS_TO_DEGREES);
|
||||
}
|
||||
|
||||
static inline void set_goal_view_tilt( float tilt )
|
||||
{
|
||||
globals->get_current_view()->set_goal_view_tilt(tilt);
|
||||
}
|
||||
|
||||
static inline void set_view_tilt( float tilt )
|
||||
{
|
||||
globals->get_current_view()->setPitchOffset_deg(tilt);
|
||||
}
|
||||
|
||||
static inline float get_view_offset() {
|
||||
return globals->get_current_view()->get_view_offset();
|
||||
return globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS;
|
||||
}
|
||||
|
||||
static inline float get_goal_view_offset() {
|
||||
return globals->get_current_view()->get_goal_view_offset();
|
||||
return globals->get_current_view()->get_goal_view_offset() * SGD_DEGREES_TO_RADIANS;
|
||||
}
|
||||
|
||||
static inline void move_brake(float offset) {
|
||||
|
@ -476,8 +486,10 @@ void guiMotionFunc ( int x, int y )
|
|||
offset -= SGD_2PI;
|
||||
}
|
||||
set_goal_view_offset(offset);
|
||||
set_goal_view_tilt(asin( GuiQuat_mat[1][2]) * SGD_RADIANS_TO_DEGREES );
|
||||
#ifdef NO_SMOOTH_MOUSE_VIEW
|
||||
set_view_offset(offset);
|
||||
set_view_tilt(asin( GuiQuat_mat[1][2]) * SGD_RADIANS_TO_DEGREES );
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
@ -532,6 +544,7 @@ void guiMouseFunc(int button, int updown, int x, int y)
|
|||
y = _Vy;
|
||||
sgCopyVec4(curGuiQuat, _quat);
|
||||
set_goal_view_offset(_view_offset);
|
||||
set_goal_view_tilt(0.0);
|
||||
#ifdef NO_SMOOTH_MOUSE_VIEW
|
||||
set_view_offset(_view_offset);
|
||||
#endif
|
||||
|
@ -547,8 +560,10 @@ void guiMouseFunc(int button, int updown, int x, int y)
|
|||
Quat0();
|
||||
_view_offset = get_goal_view_offset();
|
||||
set_goal_view_offset(0.0);
|
||||
set_goal_view_tilt(0.0);
|
||||
#ifdef NO_SMOOTH_MOUSE_VIEW
|
||||
set_view_offset(0.0);
|
||||
set_view_tilt(0.0);
|
||||
#endif
|
||||
}
|
||||
glutWarpPointer( x , y);
|
||||
|
@ -605,8 +620,10 @@ void guiMouseFunc(int button, int updown, int x, int y)
|
|||
Quat0();
|
||||
build_rotmatrix(GuiQuat_mat, curGuiQuat);
|
||||
set_goal_view_offset(0.0);
|
||||
set_goal_view_tilt(0.0);
|
||||
#ifdef NO_SMOOTH_MOUSE_VIEW
|
||||
set_view_offset(0.0);
|
||||
set_view_tilt(0.0);
|
||||
#endif // NO_SMOOTH_MOUSE_VIEW
|
||||
#endif // RESET_VIEW_ON_LEAVING_MOUSE_VIEW
|
||||
glutSetCursor(GLUT_CURSOR_INHERIT);
|
||||
|
@ -646,3 +663,5 @@ void guiMouseFunc(int button, int updown, int x, int y)
|
|||
glutPostRedisplay ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -52,8 +52,6 @@ fgfs_SOURCES = \
|
|||
options.cxx options.hxx \
|
||||
splash.cxx splash.hxx \
|
||||
viewer.cxx viewer.hxx \
|
||||
viewer_lookat.cxx viewer_lookat.hxx \
|
||||
viewer_rph.cxx viewer_rph.hxx \
|
||||
viewmgr.cxx viewmgr.hxx
|
||||
|
||||
fgfs_LDADD = \
|
||||
|
@ -95,3 +93,4 @@ INCLUDES += -I$(top_srcdir) -I$(top_srcdir)/src
|
|||
else
|
||||
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
|
||||
endif
|
||||
|
||||
|
|
|
@ -242,7 +242,7 @@ do_preferences_load (const SGPropertyNode * arg, SGCommandState ** state)
|
|||
static bool
|
||||
do_view_cycle (const SGPropertyNode * arg, SGCommandState ** state)
|
||||
{
|
||||
globals->get_current_view()->set_view_offset(0.0);
|
||||
globals->get_current_view()->setHeadingOffset_deg(0.0);
|
||||
globals->get_viewmgr()->next_view();
|
||||
if ( fgGetString("/sim/flight-model") == "ada" ) {
|
||||
globals->get_props()->setBoolValue( "/sim/hud/visibility", true );
|
||||
|
@ -605,3 +605,4 @@ fgInitCommands ()
|
|||
}
|
||||
|
||||
// end of fg_commands.hxx
|
||||
|
||||
|
|
|
@ -159,8 +159,8 @@ FGAircraftModel::update (int dt)
|
|||
do_animation(_animations[i], elapsed_ms);
|
||||
|
||||
_selector->select(true);
|
||||
FGViewerRPH *pilot_view =
|
||||
(FGViewerRPH *)globals->get_viewmgr()->get_view( 0 );
|
||||
FGViewer *pilot_view =
|
||||
(FGViewer *)globals->get_viewmgr()->get_view( 0 );
|
||||
|
||||
sgMat4 sgTRANS;
|
||||
sgMakeTransMat4( sgTRANS, pilot_view->get_view_pos() );
|
||||
|
@ -178,15 +178,13 @@ FGAircraftModel::update (int dt)
|
|||
if (view_number == 0) {
|
||||
// FIXME: orientation is not applied
|
||||
// correctly when view is not forward
|
||||
sgMakeRotMat4( sgROT, -pilot_view->get_view_offset()
|
||||
* SGD_RADIANS_TO_DEGREES, pilot_view->get_world_up() );
|
||||
sgMakeRotMat4( sgROT, -pilot_view->getHeadingOffset_deg(),
|
||||
pilot_view->get_world_up() );
|
||||
|
||||
/* Warning lame hack from Wilson ahead */
|
||||
/* get the pitch value */
|
||||
sgVec3 rph;
|
||||
sgCopyVec3(rph, pilot_view->get_rph());
|
||||
/* double it to counter the value already in the VIEW_ROT */
|
||||
float pitch = rph[1] * 2;
|
||||
float pitch = pilot_view->getPitch_deg() * SGD_DEGREES_TO_RADIANS * 2;
|
||||
/* make a ROT matrix
|
||||
with the values waited by the X coordinate from the offset
|
||||
rotation see sgROT above
|
||||
|
@ -383,3 +381,7 @@ FGAircraftModel::Animation::setRotation()
|
|||
|
||||
|
||||
// end of model.cxx
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -882,11 +882,11 @@ parse_option (const string& arg)
|
|||
} else {
|
||||
default_view_offset = atof( woffset.c_str() ) * SGD_DEGREES_TO_RADIANS;
|
||||
}
|
||||
FGViewerRPH *pilot_view =
|
||||
(FGViewerRPH *)globals->get_viewmgr()->get_view( 0 );
|
||||
pilot_view->set_view_offset( default_view_offset );
|
||||
pilot_view->set_goal_view_offset( default_view_offset );
|
||||
fgSetDouble("/sim/view/offset-deg", default_view_offset);
|
||||
FGViewer *pilot_view =
|
||||
(FGViewer *)globals->get_viewmgr()->get_view( 0 );
|
||||
pilot_view->setHeadingOffset_deg( default_view_offset * SGD_RADIANS_TO_DEGREES );
|
||||
pilot_view->set_goal_view_offset( default_view_offset * SGD_RADIANS_TO_DEGREES );
|
||||
fgSetDouble("/sim/view/offset-deg", default_view_offset * SGD_RADIANS_TO_DEGREES );
|
||||
// $$$ end - added VS Renganathan, 14 Oct 2K
|
||||
} else if ( arg.find( "--visibility=" ) == 0 ) {
|
||||
fgSetDouble("/environment/visibility-m", atof(arg.substr(13)));
|
||||
|
@ -1297,3 +1297,5 @@ fgUsage ()
|
|||
<< " instances allowed." << endl
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
//
|
||||
// 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 - curt@flightgear.org
|
||||
//
|
||||
|
@ -36,99 +38,13 @@
|
|||
|
||||
#include <Scenery/scenery.hxx>
|
||||
|
||||
/* from lookat */
|
||||
#include <simgear/math/vector.hxx>
|
||||
#include "globals.hxx"
|
||||
/* end from lookat */
|
||||
|
||||
#include "viewer.hxx"
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of FGViewPoint.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FGViewPoint::FGViewPoint ()
|
||||
: _dirty(true),
|
||||
_lon_deg(0),
|
||||
_lat_deg(0),
|
||||
_alt_ft(0)
|
||||
{
|
||||
}
|
||||
|
||||
FGViewPoint::~FGViewPoint ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
FGViewPoint::setPosition (double lon_deg, double lat_deg, double alt_ft)
|
||||
{
|
||||
_dirty = true;
|
||||
_lon_deg = lon_deg;
|
||||
_lat_deg = lat_deg;
|
||||
_alt_ft = alt_ft;
|
||||
}
|
||||
|
||||
const double *
|
||||
FGViewPoint::getAbsoluteViewPos () const
|
||||
{
|
||||
if (_dirty)
|
||||
recalc();
|
||||
return _absolute_view_pos;
|
||||
}
|
||||
|
||||
const float *
|
||||
FGViewPoint::getRelativeViewPos () const
|
||||
{
|
||||
if (_dirty)
|
||||
recalc();
|
||||
return _relative_view_pos;
|
||||
}
|
||||
|
||||
const float *
|
||||
FGViewPoint::getZeroElevViewPos () const
|
||||
{
|
||||
if (_dirty)
|
||||
recalc();
|
||||
return _zero_elev_view_pos;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewPoint::recalc () const
|
||||
{
|
||||
double sea_level_radius_m;
|
||||
double lat_geoc_rad;
|
||||
|
||||
// Convert from geodetic to geocentric
|
||||
// coordinates.
|
||||
sgGeodToGeoc(_lat_deg * SGD_DEGREES_TO_RADIANS,
|
||||
_alt_ft * SG_FEET_TO_METER,
|
||||
&sea_level_radius_m,
|
||||
&lat_geoc_rad);
|
||||
|
||||
// Calculate the cartesian coordinates
|
||||
// of point directly below at sea level.
|
||||
Point3D p = Point3D(_lon_deg * SG_DEGREES_TO_RADIANS,
|
||||
lat_geoc_rad,
|
||||
sea_level_radius_m);
|
||||
Point3D tmp = sgPolarToCart3d(p) - scenery.get_next_center();
|
||||
sgSetVec3(_zero_elev_view_pos, tmp[0], tmp[1], tmp[2]);
|
||||
|
||||
// Calculate the absolute view position
|
||||
// in fgfs coordinates.
|
||||
p.setz(p.radius() + _alt_ft * SG_FEET_TO_METER);
|
||||
tmp = sgPolarToCart3d(p);
|
||||
sgdSetVec3(_absolute_view_pos, tmp[0], tmp[1], tmp[2]);
|
||||
|
||||
// Calculate the relative view position
|
||||
// from the scenery center.
|
||||
sgdVec3 scenery_center;
|
||||
sgdSetVec3(scenery_center,
|
||||
scenery.get_next_center().x(),
|
||||
scenery.get_next_center().y(),
|
||||
scenery.get_next_center().z());
|
||||
sgdVec3 view_pos;
|
||||
sgdSubVec3(view_pos, _absolute_view_pos, scenery_center);
|
||||
sgSetVec3(_relative_view_pos, view_pos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of FGViewer.
|
||||
|
@ -138,14 +54,26 @@ FGViewPoint::recalc () const
|
|||
FGViewer::FGViewer( void ):
|
||||
scalingType(FG_SCALING_MAX),
|
||||
fov(55.0),
|
||||
view_offset(0.0),
|
||||
goal_view_offset(0.0),
|
||||
view_tilt(0.0),
|
||||
goal_view_tilt(0.0)
|
||||
goal_view_tilt(0.0),
|
||||
_dirty(true),
|
||||
_lon_deg(0),
|
||||
_lat_deg(0),
|
||||
_alt_ft(0),
|
||||
_target_lon_deg(0),
|
||||
_target_lat_deg(0),
|
||||
_target_alt_ft(0),
|
||||
_roll_deg(0),
|
||||
_pitch_deg(0),
|
||||
_heading_deg(0),
|
||||
_x_offset_m(0),
|
||||
_y_offset_m(0),
|
||||
_z_offset_m(0),
|
||||
_heading_offset_deg(0),
|
||||
_pitch_offset_deg(0),
|
||||
_roll_offset_deg(0)
|
||||
{
|
||||
sgSetVec3( pilot_offset, 0.0, 0.0, 0.0 );
|
||||
sgdZeroVec3(geod_view_pos);
|
||||
sgdZeroVec3(abs_view_pos);
|
||||
sgdZeroVec3(_absolute_view_pos);
|
||||
sea_level_radius = SG_EQUATORIAL_RADIUS_M;
|
||||
//a reasonable guess for init, so that the math doesn't blow up
|
||||
}
|
||||
|
@ -158,6 +86,13 @@ FGViewer::~FGViewer( void ) {
|
|||
void
|
||||
FGViewer::init ()
|
||||
{
|
||||
if ( _type == FG_LOOKAT ) {
|
||||
set_reverse_view_offset(true);
|
||||
}
|
||||
|
||||
if ( _type == FG_RPH ) {
|
||||
set_reverse_view_offset(false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -170,6 +105,369 @@ FGViewer::unbind ()
|
|||
{
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setType ( int type )
|
||||
{
|
||||
if (type == 0)
|
||||
_type = FG_RPH;
|
||||
if (type == 1)
|
||||
_type = FG_LOOKAT;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setLongitude_deg (double lon_deg)
|
||||
{
|
||||
_dirty = true;
|
||||
_lon_deg = lon_deg;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setLatitude_deg (double lat_deg)
|
||||
{
|
||||
_dirty = true;
|
||||
_lat_deg = lat_deg;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setAltitude_ft (double alt_ft)
|
||||
{
|
||||
_dirty = true;
|
||||
_alt_ft = alt_ft;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setPosition (double lon_deg, double lat_deg, double alt_ft)
|
||||
{
|
||||
_dirty = true;
|
||||
_lon_deg = lon_deg;
|
||||
_lat_deg = lat_deg;
|
||||
_alt_ft = alt_ft;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setTargetLongitude_deg (double lon_deg)
|
||||
{
|
||||
_dirty = true;
|
||||
_target_lon_deg = lon_deg;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setTargetLatitude_deg (double lat_deg)
|
||||
{
|
||||
_dirty = true;
|
||||
_target_lat_deg = lat_deg;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setTargetAltitude_ft (double alt_ft)
|
||||
{
|
||||
_dirty = true;
|
||||
_target_alt_ft = alt_ft;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setTargetPosition (double lon_deg, double lat_deg, double alt_ft)
|
||||
{
|
||||
_dirty = true;
|
||||
_target_lon_deg = lon_deg;
|
||||
_target_lat_deg = lat_deg;
|
||||
_target_alt_ft = alt_ft;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setRoll_deg (double roll_deg)
|
||||
{
|
||||
_dirty = true;
|
||||
_roll_deg = roll_deg;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setPitch_deg (double pitch_deg)
|
||||
{
|
||||
_dirty = true;
|
||||
_pitch_deg = pitch_deg;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setHeading_deg (double heading_deg)
|
||||
{
|
||||
_dirty = true;
|
||||
_heading_deg = heading_deg;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::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
|
||||
FGViewer::setXOffset_m (double x_offset_m)
|
||||
{
|
||||
_dirty = true;
|
||||
_x_offset_m = x_offset_m;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setYOffset_m (double y_offset_m)
|
||||
{
|
||||
_dirty = true;
|
||||
_y_offset_m = y_offset_m;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setZOffset_m (double z_offset_m)
|
||||
{
|
||||
_dirty = true;
|
||||
_z_offset_m = z_offset_m;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setPositionOffsets (double x_offset_m, double y_offset_m, double z_offset_m)
|
||||
{
|
||||
_dirty = true;
|
||||
_x_offset_m = x_offset_m;
|
||||
_y_offset_m = y_offset_m;
|
||||
_z_offset_m = z_offset_m;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setRollOffset_deg (double roll_offset_deg)
|
||||
{
|
||||
_dirty = true;
|
||||
_roll_offset_deg = roll_offset_deg;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setPitchOffset_deg (double pitch_offset_deg)
|
||||
{
|
||||
_dirty = true;
|
||||
_pitch_offset_deg = pitch_offset_deg;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setHeadingOffset_deg (double heading_offset_deg)
|
||||
{
|
||||
_dirty = true;
|
||||
_heading_offset_deg = heading_offset_deg;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::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;
|
||||
}
|
||||
|
||||
double *
|
||||
FGViewer::get_absolute_view_pos ()
|
||||
{
|
||||
if (_dirty)
|
||||
recalc();
|
||||
return _absolute_view_pos;
|
||||
}
|
||||
|
||||
float *
|
||||
FGViewer::getRelativeViewPos ()
|
||||
{
|
||||
if (_dirty)
|
||||
recalc();
|
||||
return _relative_view_pos;
|
||||
}
|
||||
|
||||
float *
|
||||
FGViewer::getZeroElevViewPos ()
|
||||
{
|
||||
if (_dirty)
|
||||
recalc();
|
||||
return _zero_elev_view_pos;
|
||||
}
|
||||
|
||||
|
||||
// recalc() is done every time one of the setters is called (making the
|
||||
// cached data "dirty"). It calculates all the outputs for viewer.
|
||||
void
|
||||
FGViewer::recalc ()
|
||||
{
|
||||
sgVec3 minus_z, right, forward, tilt;
|
||||
sgMat4 VIEWo;
|
||||
sgMat4 tmpROT; // temp rotation work matrices
|
||||
sgVec3 tmpVec3; // temp work vector (3)
|
||||
|
||||
|
||||
// The position vectors originate from the view point or target location
|
||||
// depending on the type of view.
|
||||
|
||||
if (_type == FG_RPH) {
|
||||
recalcPositionVectors( _lon_deg, _lat_deg, _alt_ft );
|
||||
} else {
|
||||
recalcPositionVectors( _target_lon_deg, _target_lat_deg, _target_alt_ft );
|
||||
}
|
||||
|
||||
sgCopyVec3(zero_elev, _zero_elev_view_pos);
|
||||
sgCopyVec3(view_pos, _relative_view_pos);
|
||||
|
||||
if (_type == FG_LOOKAT) {
|
||||
|
||||
// Make the world up rotation matrix for lookat
|
||||
sgMakeRotMat4( UP, _target_lon_deg, 0.0, -_target_lat_deg );
|
||||
|
||||
// get the world up verctor from the worldup rotation matrix
|
||||
sgSetVec3( world_up, UP[0][0], UP[0][1], UP[0][2] );
|
||||
|
||||
sgCopyVec3( view_up, world_up );
|
||||
|
||||
|
||||
// create offset vector
|
||||
sgVec3 lookat_offset;
|
||||
sgSetVec3( lookat_offset, _x_offset_m, _y_offset_m, _z_offset_m );
|
||||
|
||||
// Apply heading orientation and orientation offset to lookat_offset...
|
||||
sgMakeRotMat4( tmpROT, _heading_offset_deg -_heading_deg, world_up);
|
||||
sgXformVec3( lookat_offset, lookat_offset, UP );
|
||||
sgXformVec3( lookat_offset, lookat_offset, tmpROT );
|
||||
|
||||
// Apply orientation offset tilt...
|
||||
// FIXME: Need to get and use a "right" vector instead of 1-0-0
|
||||
sgSetVec3 (tmpVec3, 1, 0, 0);
|
||||
sgMakeRotMat4( tmpROT, _pitch_offset_deg, tmpVec3 );
|
||||
sgXformPnt3( lookat_offset, lookat_offset, tmpROT );
|
||||
|
||||
// add the offsets including rotations to the coordinates
|
||||
sgAddVec3( view_pos, lookat_offset );
|
||||
|
||||
// Make the VIEW matrix.
|
||||
fgMakeLookAtMat4( VIEW, view_pos, view_forward, view_up );
|
||||
|
||||
|
||||
// the VIEW matrix includes both rotation and translation. Let's
|
||||
// knock out the translation part to make the VIEW_ROT matrix
|
||||
sgCopyMat4( VIEW_ROT, VIEW );
|
||||
VIEW_ROT[3][0] = VIEW_ROT[3][1] = VIEW_ROT[3][2] = 0.0;
|
||||
|
||||
}
|
||||
|
||||
if (_type == FG_RPH) {
|
||||
|
||||
// code to calculate LOCAL matrix calculated from Phi, Theta, and
|
||||
// Psi (roll, pitch, yaw) in case we aren't running LaRCsim as our
|
||||
// flight model
|
||||
|
||||
fgMakeLOCAL( LOCAL, _pitch_deg * SG_DEGREES_TO_RADIANS,
|
||||
_roll_deg * SG_DEGREES_TO_RADIANS,
|
||||
-_heading_deg * SG_DEGREES_TO_RADIANS);
|
||||
|
||||
// Make the world up rotation matrix for pilot view
|
||||
sgMakeRotMat4( UP, _lon_deg, 0.0, -_lat_deg );
|
||||
|
||||
// get the world up verctor from the worldup rotation matrix
|
||||
sgSetVec3( world_up, UP[0][0], UP[0][1], UP[0][2] );
|
||||
|
||||
// VIEWo becomes the rotation matrix with world_up incorporated
|
||||
sgCopyMat4( VIEWo, LOCAL );
|
||||
sgPostMultMat4( VIEWo, UP );
|
||||
|
||||
// generate the sg view up and forward vectors
|
||||
sgSetVec3( view_up, VIEWo[0][0], VIEWo[0][1], VIEWo[0][2] );
|
||||
sgSetVec3( right, VIEWo[1][0], VIEWo[1][1], VIEWo[1][2] );
|
||||
sgSetVec3( forward, VIEWo[2][0], VIEWo[2][1], VIEWo[2][2] );
|
||||
|
||||
// apply the offsets in world coordinates
|
||||
sgVec3 pilot_offset_world;
|
||||
sgSetVec3( pilot_offset_world,
|
||||
_z_offset_m, _y_offset_m, -_x_offset_m );
|
||||
sgXformVec3( pilot_offset_world, pilot_offset_world, VIEWo );
|
||||
|
||||
// generate the view offset matrix using orientation offset (heading)
|
||||
sgMakeRotMat4( VIEW_OFFSET, _heading_offset_deg, view_up );
|
||||
|
||||
// create a tilt matrix using orientation offset (pitch)
|
||||
sgMat4 VIEW_TILT;
|
||||
sgMakeRotMat4( VIEW_TILT, _pitch_offset_deg, right );
|
||||
sgPreMultMat4(VIEW_OFFSET, VIEW_TILT);
|
||||
sgXformVec3( view_forward, forward, VIEW_OFFSET );
|
||||
SG_LOG( SG_VIEW, SG_DEBUG, "(RPH) view forward = "
|
||||
<< view_forward[0] << "," << view_forward[1] << ","
|
||||
<< view_forward[2] );
|
||||
|
||||
// VIEW_ROT = LARC_TO_SSG * ( VIEWo * VIEW_OFFSET )
|
||||
fgMakeViewRot( VIEW_ROT, VIEW_OFFSET, VIEWo );
|
||||
|
||||
sgVec3 trans_vec;
|
||||
sgAddVec3( trans_vec, view_pos, pilot_offset_world );
|
||||
|
||||
// VIEW = VIEW_ROT * TRANS
|
||||
sgCopyMat4( VIEW, VIEW_ROT );
|
||||
sgPostMultMat4ByTransMat4( VIEW, trans_vec );
|
||||
|
||||
}
|
||||
|
||||
// Given a vector pointing straight down (-Z), map into onto the
|
||||
// local plane representing "horizontal". This should give us the
|
||||
// local direction for moving "south".
|
||||
sgSetVec3( minus_z, 0.0, 0.0, -1.0 );
|
||||
|
||||
sgmap_vec_onto_cur_surface_plane(world_up, view_pos, minus_z,
|
||||
surface_south);
|
||||
sgNormalizeVec3(surface_south);
|
||||
|
||||
// now calculate the surface east vector
|
||||
sgVec3 world_down;
|
||||
sgNegateVec3(world_down, world_up);
|
||||
sgVectorProductVec3(surface_east, surface_south, world_down);
|
||||
|
||||
set_clean();
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::recalcPositionVectors (double lon_deg, double lat_deg, double alt_ft) const
|
||||
{
|
||||
double sea_level_radius_m;
|
||||
double lat_geoc_rad;
|
||||
|
||||
|
||||
// Convert from geodetic to geocentric
|
||||
// coordinates.
|
||||
sgGeodToGeoc(lat_deg * SGD_DEGREES_TO_RADIANS,
|
||||
alt_ft * SG_FEET_TO_METER,
|
||||
&sea_level_radius_m,
|
||||
&lat_geoc_rad);
|
||||
|
||||
// Calculate the cartesian coordinates
|
||||
// of point directly below at sea level.
|
||||
// aka Zero Elevation Position
|
||||
Point3D p = Point3D(lon_deg * SG_DEGREES_TO_RADIANS,
|
||||
lat_geoc_rad,
|
||||
sea_level_radius_m);
|
||||
Point3D tmp = sgPolarToCart3d(p) - scenery.get_next_center();
|
||||
sgSetVec3(_zero_elev_view_pos, tmp[0], tmp[1], tmp[2]);
|
||||
|
||||
// Calculate the absolute view position
|
||||
// in fgfs coordinates.
|
||||
// aka Absolute View Position
|
||||
p.setz(p.radius() + alt_ft * SG_FEET_TO_METER);
|
||||
tmp = sgPolarToCart3d(p);
|
||||
sgdSetVec3(_absolute_view_pos, tmp[0], tmp[1], tmp[2]);
|
||||
|
||||
// Calculate the relative view position
|
||||
// from the scenery center.
|
||||
// aka Relative View Position
|
||||
sgdVec3 scenery_center;
|
||||
sgdSetVec3(scenery_center,
|
||||
scenery.get_next_center().x(),
|
||||
scenery.get_next_center().y(),
|
||||
scenery.get_next_center().z());
|
||||
sgdVec3 view_pos;
|
||||
sgdSubVec3(view_pos, _absolute_view_pos, scenery_center);
|
||||
sgSetVec3(_relative_view_pos, view_pos);
|
||||
|
||||
}
|
||||
|
||||
double
|
||||
FGViewer::get_h_fov()
|
||||
{
|
||||
|
@ -216,60 +514,164 @@ FGViewer::update (int dt)
|
|||
{
|
||||
int i;
|
||||
for ( i = 0; i < dt; i++ ) {
|
||||
if ( fabs(get_goal_view_offset() - get_view_offset()) < 0.05 ) {
|
||||
set_view_offset( get_goal_view_offset() );
|
||||
if ( fabs(get_goal_view_offset() - getHeadingOffset_deg()) < 1 ) {
|
||||
setHeadingOffset_deg( get_goal_view_offset() );
|
||||
break;
|
||||
} else {
|
||||
// move current_view.view_offset towards
|
||||
// move current_view.headingoffset towards
|
||||
// current_view.goal_view_offset
|
||||
if ( get_goal_view_offset() > get_view_offset() )
|
||||
if ( get_goal_view_offset() > getHeadingOffset_deg() )
|
||||
{
|
||||
if ( get_goal_view_offset() - get_view_offset() < SGD_PI ){
|
||||
inc_view_offset( 0.01 );
|
||||
if ( get_goal_view_offset() - getHeadingOffset_deg() < 180 ){
|
||||
inc_view_offset( 0.5 );
|
||||
} else {
|
||||
inc_view_offset( -0.01 );
|
||||
inc_view_offset( -0.5 );
|
||||
}
|
||||
} else {
|
||||
if ( get_view_offset() - get_goal_view_offset() < SGD_PI ){
|
||||
inc_view_offset( -0.01 );
|
||||
if ( getHeadingOffset_deg() - get_goal_view_offset() < 180 ){
|
||||
inc_view_offset( -0.5 );
|
||||
} else {
|
||||
inc_view_offset( 0.01 );
|
||||
inc_view_offset( 0.5 );
|
||||
}
|
||||
}
|
||||
if ( get_view_offset() > SGD_2PI ) {
|
||||
inc_view_offset( -SGD_2PI );
|
||||
} else if ( get_view_offset() < 0 ) {
|
||||
inc_view_offset( SGD_2PI );
|
||||
if ( getHeadingOffset_deg() > 360 ) {
|
||||
inc_view_offset( -360 );
|
||||
} else if ( getHeadingOffset_deg() < 0 ) {
|
||||
inc_view_offset( 360 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( i = 0; i < dt; i++ ) {
|
||||
if ( fabs(get_goal_view_tilt() - get_view_tilt()) < 0.05 ) {
|
||||
set_view_tilt( get_goal_view_tilt() );
|
||||
if ( fabs(get_goal_view_tilt() - getPitchOffset_deg()) < 1 ) {
|
||||
setPitchOffset_deg( get_goal_view_tilt() );
|
||||
break;
|
||||
} else {
|
||||
// move current_view.view_tilt towards
|
||||
// move current_view.pitch_offset_deg towards
|
||||
// current_view.goal_view_tilt
|
||||
if ( get_goal_view_tilt() > get_view_tilt() )
|
||||
if ( get_goal_view_tilt() > getPitchOffset_deg() )
|
||||
{
|
||||
if ( get_goal_view_tilt() - get_view_tilt() < SGD_PI ){
|
||||
inc_view_tilt( 0.01 );
|
||||
if ( get_goal_view_tilt() - getPitchOffset_deg() < 0 ){
|
||||
inc_view_tilt( 1.0 );
|
||||
} else {
|
||||
inc_view_tilt( -0.01 );
|
||||
inc_view_tilt( -1.0 );
|
||||
}
|
||||
} else {
|
||||
if ( get_view_tilt() - get_goal_view_tilt() < SGD_PI ){
|
||||
inc_view_tilt( -0.01 );
|
||||
if ( getPitchOffset_deg() - get_goal_view_tilt() < 0 ){
|
||||
inc_view_tilt( -1.0 );
|
||||
} else {
|
||||
inc_view_tilt( 0.01 );
|
||||
inc_view_tilt( 1.0 );
|
||||
}
|
||||
}
|
||||
if ( get_view_tilt() > SGD_2PI ) {
|
||||
inc_view_tilt( -SGD_2PI );
|
||||
} else if ( get_view_tilt() < 0 ) {
|
||||
inc_view_tilt( SGD_2PI );
|
||||
if ( getPitchOffset_deg() > 90 ) {
|
||||
setPitchOffset_deg(90);
|
||||
} else if ( getPitchOffset_deg() < -90 ) {
|
||||
setPitchOffset_deg( -90 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FGViewer::fgMakeLookAtMat4 ( sgMat4 dst, const sgVec3 eye, const sgVec3 center,
|
||||
const sgVec3 up )
|
||||
{
|
||||
// Caveats:
|
||||
// 1) In order to compute the line of sight, the eye point must not be equal
|
||||
// to the center point.
|
||||
// 2) The up vector must not be parallel to the line of sight from the eye
|
||||
// to the center point.
|
||||
|
||||
/* Compute the direction vectors */
|
||||
sgVec3 x,y,z;
|
||||
|
||||
/* Y vector = center - eye */
|
||||
sgSubVec3 ( y, center, eye ) ;
|
||||
|
||||
/* Z vector = up */
|
||||
sgCopyVec3 ( z, up ) ;
|
||||
|
||||
/* X vector = Y cross Z */
|
||||
sgVectorProductVec3 ( x, y, z ) ;
|
||||
|
||||
/* Recompute Z = X cross Y */
|
||||
sgVectorProductVec3 ( z, x, y ) ;
|
||||
|
||||
/* Normalize everything */
|
||||
sgNormaliseVec3 ( x ) ;
|
||||
sgNormaliseVec3 ( y ) ;
|
||||
sgNormaliseVec3 ( z ) ;
|
||||
|
||||
/* Build the matrix */
|
||||
#define M(row,col) dst[row][col]
|
||||
M(0,0) = x[0]; M(0,1) = x[1]; M(0,2) = x[2]; M(0,3) = 0.0;
|
||||
M(1,0) = y[0]; M(1,1) = y[1]; M(1,2) = y[2]; M(1,3) = 0.0;
|
||||
M(2,0) = z[0]; M(2,1) = z[1]; M(2,2) = z[2]; M(2,3) = 0.0;
|
||||
M(3,0) = eye[0]; M(3,1) = eye[1]; M(3,2) = eye[2]; M(3,3) = 1.0;
|
||||
#undef M
|
||||
}
|
||||
/* end from lookat */
|
||||
|
||||
/* from rph */
|
||||
// VIEW_ROT = LARC_TO_SSG * ( VIEWo * VIEW_OFFSET )
|
||||
// This takes advantage of the fact that VIEWo and VIEW_OFFSET
|
||||
// only have entries in the upper 3x3 block
|
||||
// and that LARC_TO_SSG is just a shift of rows NHV
|
||||
void FGViewer::fgMakeViewRot( sgMat4 dst, const sgMat4 m1, const sgMat4 m2 )
|
||||
{
|
||||
for ( int j = 0 ; j < 3 ; j++ ) {
|
||||
dst[2][j] = m2[0][0] * m1[0][j] +
|
||||
m2[0][1] * m1[1][j] +
|
||||
m2[0][2] * m1[2][j];
|
||||
|
||||
dst[0][j] = m2[1][0] * m1[0][j] +
|
||||
m2[1][1] * m1[1][j] +
|
||||
m2[1][2] * m1[2][j];
|
||||
|
||||
dst[1][j] = m2[2][0] * m1[0][j] +
|
||||
m2[2][1] * m1[1][j] +
|
||||
m2[2][2] * m1[2][j];
|
||||
}
|
||||
dst[0][3] =
|
||||
dst[1][3] =
|
||||
dst[2][3] =
|
||||
dst[3][0] =
|
||||
dst[3][1] =
|
||||
dst[3][2] = SG_ZERO;
|
||||
dst[3][3] = SG_ONE;
|
||||
}
|
||||
|
||||
|
||||
void FGViewer::fgMakeLOCAL( sgMat4 dst, const double Theta,
|
||||
const double Phi, const double Psi)
|
||||
{
|
||||
SGfloat cosTheta = (SGfloat) cos(Theta);
|
||||
SGfloat sinTheta = (SGfloat) sin(Theta);
|
||||
SGfloat cosPhi = (SGfloat) cos(Phi);
|
||||
SGfloat sinPhi = (SGfloat) sin(Phi);
|
||||
SGfloat sinPsi = (SGfloat) sin(Psi) ;
|
||||
SGfloat cosPsi = (SGfloat) cos(Psi) ;
|
||||
|
||||
dst[0][0] = cosPhi * cosTheta;
|
||||
dst[0][1] = sinPhi * cosPsi + cosPhi * -sinTheta * -sinPsi;
|
||||
dst[0][2] = sinPhi * sinPsi + cosPhi * -sinTheta * cosPsi;
|
||||
dst[0][3] = SG_ZERO;
|
||||
|
||||
dst[1][0] = -sinPhi * cosTheta;
|
||||
dst[1][1] = cosPhi * cosPsi + -sinPhi * -sinTheta * -sinPsi;
|
||||
dst[1][2] = cosPhi * sinPsi + -sinPhi * -sinTheta * cosPsi;
|
||||
dst[1][3] = SG_ZERO ;
|
||||
|
||||
dst[2][0] = sinTheta;
|
||||
dst[2][1] = cosTheta * -sinPsi;
|
||||
dst[2][2] = cosTheta * cosPsi;
|
||||
dst[2][3] = SG_ZERO;
|
||||
|
||||
dst[3][0] = SG_ZERO;
|
||||
dst[3][1] = SG_ZERO;
|
||||
dst[3][2] = SG_ZERO;
|
||||
dst[3][3] = SG_ONE ;
|
||||
}
|
||||
|
||||
/* end from rph */
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
//
|
||||
// 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 - curt@flightgear.org
|
||||
//
|
||||
|
@ -42,73 +44,8 @@
|
|||
#define FG_FOV_MAX 179.9
|
||||
|
||||
|
||||
/**
|
||||
* Representation of a single viewpoint in the FlightGear world.
|
||||
*/
|
||||
class FGViewPoint
|
||||
{
|
||||
public:
|
||||
FGViewPoint ();
|
||||
virtual ~FGViewPoint ();
|
||||
|
||||
/**
|
||||
* Set the geodetic position for the view point.
|
||||
*/
|
||||
virtual void setPosition (double lon_deg, double lat_deg, double alt_ft);
|
||||
|
||||
|
||||
/**
|
||||
* Get the longitude in degrees.
|
||||
*/
|
||||
virtual double getLongitude_deg () const { return _lon_deg; }
|
||||
|
||||
/**
|
||||
* Get the latitude in degrees.
|
||||
*/
|
||||
virtual double getLatitude_deg () const { return _lat_deg; }
|
||||
|
||||
/**
|
||||
* Get the altitude in feet ASL.
|
||||
*/
|
||||
virtual double getAltitudeASL_ft () const { return _alt_ft; }
|
||||
|
||||
/**
|
||||
* Get the absolute view position in fgfs coordinates.
|
||||
*/
|
||||
virtual const double * getAbsoluteViewPos () const;
|
||||
|
||||
|
||||
/**
|
||||
* Get the relative view position in fgfs coordinates.
|
||||
*
|
||||
* The position is relative to the scenery centre.
|
||||
*/
|
||||
virtual const float * getRelativeViewPos () const;
|
||||
|
||||
|
||||
/**
|
||||
* Get the absolute zero-elevation view position in fgfs coordinates.
|
||||
*/
|
||||
virtual const float * getZeroElevViewPos () const;
|
||||
|
||||
private:
|
||||
|
||||
void recalc () const;
|
||||
|
||||
mutable sgdVec3 _absolute_view_pos;
|
||||
mutable sgVec3 _relative_view_pos;
|
||||
mutable sgVec3 _zero_elev_view_pos;
|
||||
|
||||
bool _dirty;
|
||||
double _lon_deg;
|
||||
double _lat_deg;
|
||||
double _alt_ft;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Define a structure containing view information
|
||||
class FGViewer {
|
||||
class FGViewer : public FGSubsystem {
|
||||
|
||||
public:
|
||||
|
||||
|
@ -125,42 +62,168 @@ public:
|
|||
// FG_SCALING_INDEPENDENT // whole screen
|
||||
};
|
||||
|
||||
// Constructor
|
||||
FGViewer( void );
|
||||
|
||||
// Destructor
|
||||
virtual ~FGViewer( void );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Part 1: standard FGSubsystem implementation.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual void init ();
|
||||
virtual void bind ();
|
||||
virtual void unbind ();
|
||||
void update (int dt);
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Part 2: user settings.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual fgViewType getType() const { return _type; }
|
||||
virtual void setType( int type );
|
||||
|
||||
// Reference geodetic position of view from position...
|
||||
virtual double getLongitude_deg () const { return _lon_deg; }
|
||||
virtual double getLatitude_deg () const { return _lat_deg; }
|
||||
virtual double getAltitudeASL_ft () const { return _alt_ft; }
|
||||
// Set individual coordinates for the view point position.
|
||||
virtual void setLongitude_deg (double lon_deg);
|
||||
virtual void setLatitude_deg (double lat_deg);
|
||||
virtual void setAltitude_ft (double alt_ft);
|
||||
// Set the geodetic position for the view point.
|
||||
virtual void setPosition (double lon_deg, double lat_deg, double alt_ft);
|
||||
|
||||
// Reference geodetic target position...
|
||||
virtual double getTargetLongitude_deg () const { return _target_lon_deg; }
|
||||
virtual double getTargetLatitude_deg () const { return _target_lat_deg; }
|
||||
virtual double getTargetAltitudeASL_ft () const { return _target_alt_ft; }
|
||||
// Set individual coordinates for the Target point position.
|
||||
virtual void setTargetLongitude_deg (double lon_deg);
|
||||
virtual void setTargetLatitude_deg (double lat_deg);
|
||||
virtual void setTargetAltitude_ft (double alt_ft);
|
||||
// Set the geodetic position for the Target point.
|
||||
virtual void setTargetPosition (double lon_deg, double lat_deg, double alt_ft);
|
||||
|
||||
// Refence orientation...
|
||||
virtual double getRoll_deg () const { return _roll_deg; }
|
||||
virtual double getPitch_deg () const {return _pitch_deg; }
|
||||
virtual double getHeading_deg () const {return _heading_deg; }
|
||||
virtual void setRoll_deg (double roll_deg);
|
||||
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);
|
||||
|
||||
// Position offsets from reference
|
||||
virtual double getXOffset_m () const { return _x_offset_m; }
|
||||
virtual double getYOffset_m () const { return _y_offset_m; }
|
||||
virtual double getZOffset_m () const { return _z_offset_m; }
|
||||
virtual void setXOffset_m (double x_offset_m);
|
||||
virtual void setYOffset_m (double y_offset_m);
|
||||
virtual void setZOffset_m (double z_offset_m);
|
||||
virtual void setPositionOffsets (double x_offset_m,
|
||||
double y_offset_m,
|
||||
double z_offset_m);
|
||||
|
||||
// Orientation offsets from reference
|
||||
virtual double getRollOffset_deg () const { return _roll_offset_deg; }
|
||||
virtual double getPitchOffset_deg () const { return _pitch_offset_deg; }
|
||||
virtual double getHeadingOffset_deg () const { return _heading_offset_deg; }
|
||||
virtual void setRollOffset_deg (double roll_offset_deg);
|
||||
virtual void setPitchOffset_deg (double pitch_offset_deg);
|
||||
virtual void setHeadingOffset_deg (double heading_offset_deg);
|
||||
virtual void setOrientationOffsets (double roll_offset_deg,
|
||||
double heading_offset_deg,
|
||||
double pitch_offset_deg);
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Part 3: output vectors and matrices in FlightGear coordinates.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Vectors and positions...
|
||||
|
||||
// Get zero view_pos
|
||||
virtual float * get_view_pos() {if ( _dirty ) { recalc(); } return view_pos; }
|
||||
// Get the absolute view position in fgfs coordinates.
|
||||
virtual double * get_absolute_view_pos ();
|
||||
// Get zero elev
|
||||
virtual float * get_zero_elev() {if ( _dirty ) { recalc(); } return zero_elev; }
|
||||
// Get world up vector
|
||||
virtual float *get_world_up() {if ( _dirty ) { recalc(); } return world_up; }
|
||||
// Get the relative (to scenery center) view position in fgfs coordinates.
|
||||
virtual float * getRelativeViewPos ();
|
||||
// Get the absolute zero-elevation view position in fgfs coordinates.
|
||||
virtual float * getZeroElevViewPos ();
|
||||
// Get surface east vector
|
||||
virtual float *get_surface_east() { if ( _dirty ) { recalc(); } return surface_east; }
|
||||
// Get surface south vector
|
||||
virtual float *get_surface_south() {if ( _dirty ) { recalc(); } return surface_south; }
|
||||
|
||||
// Matrices...
|
||||
virtual const sgVec4 *get_VIEW() { if ( _dirty ) { recalc(); } return VIEW; }
|
||||
virtual const sgVec4 *get_VIEW_ROT() { if ( _dirty ) { recalc(); } return VIEW_ROT; }
|
||||
virtual const sgVec4 *get_UP() { if ( _dirty ) { recalc(); } return UP; }
|
||||
// (future?)
|
||||
// virtual double get_ground_elev() { if ( _dirty ) { recalc(); } return ground_elev; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// flag forcing a recalc of derived view parameters
|
||||
bool dirty;
|
||||
bool _dirty;
|
||||
|
||||
void recalc ();
|
||||
void recalcPositionVectors (double lon_deg, double lat_deg, double alt_ft) const;
|
||||
|
||||
mutable sgdVec3 _absolute_view_pos;
|
||||
mutable sgVec3 _relative_view_pos;
|
||||
mutable sgVec3 _zero_elev_view_pos;
|
||||
|
||||
double _lon_deg;
|
||||
double _lat_deg;
|
||||
double _alt_ft;
|
||||
double _target_lon_deg;
|
||||
double _target_lat_deg;
|
||||
double _target_alt_ft;
|
||||
|
||||
double _roll_deg;
|
||||
double _pitch_deg;
|
||||
double _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.
|
||||
// distance in meters
|
||||
double _x_offset_m;
|
||||
double _y_offset_m;
|
||||
double _z_offset_m;
|
||||
|
||||
// orientation offsets from reference
|
||||
double _roll_offset_deg;
|
||||
double _pitch_offset_deg;
|
||||
double _heading_offset_deg;
|
||||
|
||||
protected:
|
||||
|
||||
fgViewType _type;
|
||||
fgScalingType scalingType;
|
||||
|
||||
FGViewPoint view_point;
|
||||
|
||||
// the nominal field of view (angle, in degrees)
|
||||
double fov;
|
||||
|
||||
// ratio of window width and height; height = width * aspect_ratio
|
||||
double aspect_ratio;
|
||||
|
||||
// the current view offset angle from forward (rotated about the
|
||||
// view_up vector)
|
||||
double view_offset;
|
||||
bool reverse_view_offset;
|
||||
|
||||
// the goal view offset angle (used for smooth view changes)
|
||||
double goal_view_offset;
|
||||
|
||||
// the view tilt angles
|
||||
double view_tilt;
|
||||
double goal_view_tilt;
|
||||
|
||||
// geodetic view position
|
||||
sgdVec3 geod_view_pos;
|
||||
|
||||
// absolute view position in earth coordinates
|
||||
sgdVec3 abs_view_pos;
|
||||
|
||||
// view position in opengl world coordinates (this is the
|
||||
// abs_view_pos translated to scenery.center)
|
||||
sgVec3 view_pos;
|
||||
|
@ -175,11 +238,6 @@ protected:
|
|||
// height ASL of the terrain for our current view position
|
||||
// (future?) double ground_elev;
|
||||
|
||||
// pilot offset from center of gravity. The X axis is positive
|
||||
// out the tail, Y is out the right wing, and Z is positive up.
|
||||
// Distances in meters of course.
|
||||
sgVec3 pilot_offset;
|
||||
|
||||
// surface vector heading south
|
||||
sgVec3 surface_south;
|
||||
|
||||
|
@ -194,24 +252,35 @@ protected:
|
|||
// sg versions of our friendly matrices
|
||||
sgMat4 VIEW, VIEW_ROT, UP;
|
||||
|
||||
inline void set_dirty() { dirty = true; }
|
||||
inline void set_clean() { dirty = false; }
|
||||
// up vector for the view (usually point straight up through the
|
||||
// top of the aircraft
|
||||
sgVec3 view_up;
|
||||
|
||||
// the vector pointing straight out the nose of the aircraft
|
||||
sgVec3 view_forward;
|
||||
|
||||
// Transformation matrix for the view direction offset relative to
|
||||
// the AIRCRAFT matrix
|
||||
sgMat4 VIEW_OFFSET;
|
||||
|
||||
// sg versions of our friendly matrices (from lookat)
|
||||
sgMat4 LOCAL, TRANS, LARC_TO_SSG;
|
||||
|
||||
inline void set_dirty() { _dirty = true; }
|
||||
inline void set_clean() { _dirty = false; }
|
||||
|
||||
// from lookat
|
||||
void fgMakeLookAtMat4 ( sgMat4 dst, const sgVec3 eye, const sgVec3 center,
|
||||
const sgVec3 up );
|
||||
|
||||
// from rph
|
||||
void fgMakeViewRot( sgMat4 dst, const sgMat4 m1, const sgMat4 m2 );
|
||||
void fgMakeLOCAL( sgMat4 dst, const double Theta,
|
||||
const double Phi, const double Psi);
|
||||
|
||||
// Update the view volume, position, and orientation
|
||||
virtual void update() = 0;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
FGViewer( void );
|
||||
|
||||
// Destructor
|
||||
virtual ~FGViewer( void );
|
||||
|
||||
virtual void init ();
|
||||
virtual void bind ();
|
||||
virtual void unbind ();
|
||||
virtual void update (int dt);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// setter functions
|
||||
|
@ -224,127 +293,81 @@ public:
|
|||
inline void set_aspect_ratio( double r ) {
|
||||
aspect_ratio = r;
|
||||
}
|
||||
inline void set_view_offset( double a ) {
|
||||
set_dirty();
|
||||
view_offset = a;
|
||||
}
|
||||
inline void inc_view_offset( double amt ) {
|
||||
set_dirty();
|
||||
view_offset += amt;
|
||||
_heading_offset_deg += amt;
|
||||
}
|
||||
inline void set_goal_view_offset( double a) {
|
||||
set_dirty();
|
||||
goal_view_offset = a;
|
||||
while ( goal_view_offset < 0.0 ) {
|
||||
goal_view_offset += SGD_2PI;
|
||||
goal_view_offset += 360;
|
||||
}
|
||||
while ( goal_view_offset > SGD_2PI ) {
|
||||
goal_view_offset -= SGD_2PI;
|
||||
while ( goal_view_offset > 360 ) {
|
||||
goal_view_offset -= 360;
|
||||
}
|
||||
}
|
||||
inline void set_reverse_view_offset( bool val ) {
|
||||
reverse_view_offset = val;
|
||||
}
|
||||
inline void set_view_tilt( double a ) {
|
||||
set_dirty();
|
||||
view_tilt = a;
|
||||
}
|
||||
inline void inc_view_tilt( double amt ) {
|
||||
set_dirty();
|
||||
view_tilt += amt;
|
||||
_pitch_offset_deg += amt;
|
||||
}
|
||||
inline void set_goal_view_tilt( double a) {
|
||||
set_dirty();
|
||||
goal_view_tilt = a;
|
||||
while ( goal_view_tilt < 0 ) {
|
||||
goal_view_tilt += 360.0;
|
||||
while ( goal_view_tilt < -90 ) {
|
||||
goal_view_tilt = -90.0;
|
||||
}
|
||||
while ( goal_view_tilt > 360.0 ) {
|
||||
goal_view_tilt -= 360.0;
|
||||
while ( goal_view_tilt > 90.0 ) {
|
||||
goal_view_tilt = 90.0;
|
||||
}
|
||||
}
|
||||
inline void set_geod_view_pos( double lon, double lat, double alt ) {
|
||||
// data should be in radians and meters asl
|
||||
set_dirty();
|
||||
// cout << "set_geod_view_pos = " << lon << ", " << lat << ", " << alt
|
||||
// << endl;
|
||||
sgdSetVec3( geod_view_pos, lon, lat, alt );
|
||||
}
|
||||
inline void set_pilot_offset( float x, float y, float z ) {
|
||||
set_dirty();
|
||||
sgSetVec3( pilot_offset, x, y, z );
|
||||
}
|
||||
inline void set_sea_level_radius( double r ) {
|
||||
// data should be in meters from the center of the earth
|
||||
set_dirty();
|
||||
sea_level_radius = r;
|
||||
}
|
||||
|
||||
/* from lookat */
|
||||
inline void set_view_forward( sgVec3 vf ) {
|
||||
set_dirty();
|
||||
sgCopyVec3( view_forward, vf );
|
||||
}
|
||||
inline void set_view_up( sgVec3 vf ) {
|
||||
set_dirty();
|
||||
sgCopyVec3( view_up, vf );
|
||||
}
|
||||
/* end from lookat */
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// accessor functions
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
inline int get_type() const { return _type ; }
|
||||
inline int is_a( int t ) const { return get_type() == t ; }
|
||||
inline bool is_dirty() const { return dirty; }
|
||||
inline bool is_dirty() const { return _dirty; }
|
||||
inline double get_fov() const { return fov; }
|
||||
inline double get_aspect_ratio() const { return aspect_ratio; }
|
||||
inline double get_view_offset() const { return view_offset; }
|
||||
inline bool get_reverse_view_offset() const { return reverse_view_offset; }
|
||||
inline double get_goal_view_offset() const { return goal_view_offset; }
|
||||
inline double get_view_tilt() const { return view_tilt; }
|
||||
inline double get_goal_view_tilt() const { return goal_view_tilt; }
|
||||
inline double *get_geod_view_pos() { return geod_view_pos; }
|
||||
inline float *get_pilot_offset() { return pilot_offset; }
|
||||
inline double get_sea_level_radius() const { return sea_level_radius; }
|
||||
// Get horizontal field of view angle, in degrees.
|
||||
double get_h_fov();
|
||||
// Get vertical field of view angle, in degrees.
|
||||
double get_v_fov();
|
||||
|
||||
/* from lookat */
|
||||
inline float *get_view_forward() { return view_forward; }
|
||||
inline float *get_view_up() { return view_up; }
|
||||
/* end from lookat */
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// derived values accessor functions
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
inline double *get_abs_view_pos() {
|
||||
if ( dirty ) { update(); }
|
||||
return abs_view_pos;
|
||||
}
|
||||
inline float *get_view_pos() {
|
||||
if ( dirty ) { update(); }
|
||||
return view_pos;
|
||||
}
|
||||
inline float *get_zero_elev() {
|
||||
if ( dirty ) { update(); }
|
||||
return zero_elev;
|
||||
}
|
||||
// (future?)
|
||||
// inline double get_ground_elev() {
|
||||
// if ( dirty ) { update(); }
|
||||
// return ground_elev;
|
||||
// }
|
||||
inline float *get_surface_south() {
|
||||
if ( dirty ) { update(); }
|
||||
return surface_south;
|
||||
}
|
||||
inline float *get_surface_east() {
|
||||
if ( dirty ) { update(); }
|
||||
return surface_east;
|
||||
}
|
||||
inline float *get_world_up() {
|
||||
if ( dirty ) { update(); }
|
||||
return world_up;
|
||||
}
|
||||
inline const sgVec4 *get_VIEW() {
|
||||
if ( dirty ) { update(); }
|
||||
return VIEW;
|
||||
}
|
||||
inline const sgVec4 *get_VIEW_ROT() {
|
||||
if ( dirty ) { update(); }
|
||||
return VIEW_ROT;
|
||||
}
|
||||
inline const sgVec4 *get_UP() {
|
||||
if ( dirty ) { update(); }
|
||||
return UP;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// viewmgr.cxx -- class for managing all the views in the flightgear world.
|
||||
//
|
||||
// Written by Curtis Olson, started October 2000.
|
||||
// partially rewritten by Jim Wilson March 2002
|
||||
//
|
||||
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
|
@ -44,8 +45,8 @@ FGViewMgr::~FGViewMgr( void ) {
|
|||
void
|
||||
FGViewMgr::init ()
|
||||
{
|
||||
add_view(new FGViewerRPH);
|
||||
add_view(new FGViewerLookAt);
|
||||
add_view(new FGViewer, 0);
|
||||
add_view(new FGViewer, 1);
|
||||
}
|
||||
|
||||
typedef double (FGViewMgr::*double_getter)() const;
|
||||
|
@ -120,38 +121,44 @@ FGViewMgr::update (int dt)
|
|||
* SGD_DEGREES_TO_RADIANS;
|
||||
|
||||
// Set up the pilot view
|
||||
FGViewerRPH *pilot_view = (FGViewerRPH *)get_view( 0 );
|
||||
pilot_view ->set_geod_view_pos(lon_rad, lat_rad, alt_m);
|
||||
pilot_view->set_rph(roll_rad, pitch_rad, heading_rad);
|
||||
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 (fgGetString("/sim/flight-model") == "ada") {
|
||||
//+ve x is aft, +ve z is up (see viewer.hxx)
|
||||
pilot_view->set_pilot_offset( -5.0, 0.0, 1.0 );
|
||||
pilot_view->setPositionOffsets( -5.0, 0.0, 1.0 );
|
||||
}
|
||||
|
||||
// Set up the chase view
|
||||
|
||||
// FIXME: the matrix math belongs in
|
||||
// the viewer, not here.
|
||||
FGViewerLookAt *chase_view = (FGViewerLookAt *)get_view( 1 );
|
||||
FGViewer *chase_view = (FGViewer *)get_view( 1 );
|
||||
|
||||
sgVec3 po; // chase view pilot_offset
|
||||
sgVec3 wup; // chase view world up
|
||||
sgSetVec3( po, 0.0, 0.0, 100.0 );
|
||||
sgCopyVec3( wup, pilot_view->get_world_up() );
|
||||
sgMat4 CXFM; // chase view + pilot offset xform
|
||||
sgMakeRotMat4( CXFM,
|
||||
chase_view->get_view_offset() * SGD_RADIANS_TO_DEGREES -
|
||||
heading_rad * SGD_RADIANS_TO_DEGREES,
|
||||
wup );
|
||||
sgVec3 npo; // new pilot offset after rotation
|
||||
// get xyz Position offsets directly from GUI/sgVec3Slider
|
||||
// FIXME: change GUI/sgVec3Slider to store the xyz in properties
|
||||
// it would probably be faster than the way PilotOffsetGet()
|
||||
// triggers a recalc all the time.
|
||||
sgVec3 *pPO = PilotOffsetGet();
|
||||
sgXformVec3( po, *pPO, pilot_view->get_UP() );
|
||||
sgXformVec3( npo, po, CXFM );
|
||||
sgVec3 zPO;
|
||||
sgCopyVec3( zPO, *pPO );
|
||||
chase_view->setPositionOffsets(zPO[0], zPO[1], zPO[2] );
|
||||
|
||||
chase_view->set_geod_view_pos(lon_rad, lat_rad, alt_m);
|
||||
chase_view->set_pilot_offset( npo[0], npo[1], npo[2] );
|
||||
chase_view->setOrientation(
|
||||
fgGetDouble("/orientation/roll-deg"),
|
||||
fgGetDouble("/orientation/pitch-deg"),
|
||||
fgGetDouble("/orientation/heading-deg"));
|
||||
|
||||
chase_view ->setTargetPosition(
|
||||
fgGetDouble("/position/longitude-deg"),
|
||||
fgGetDouble("/position/latitude-deg"),
|
||||
fgGetDouble("/position/altitude-ft"));
|
||||
chase_view->setPositionOffsets(zPO[0], zPO[1], zPO[2] );
|
||||
chase_view->set_view_forward( pilot_view->get_view_pos() );
|
||||
chase_view->set_view_up( wup );
|
||||
|
||||
// Update the current view
|
||||
do_axes();
|
||||
|
@ -162,7 +169,7 @@ double
|
|||
FGViewMgr::getViewOffset_deg () const
|
||||
{
|
||||
const FGViewer * view = get_current_view();
|
||||
return (view == 0 ? 0 : view->get_view_offset() * SGD_RADIANS_TO_DEGREES);
|
||||
return (view == 0 ? 0 : view->getHeadingOffset_deg());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -170,14 +177,14 @@ FGViewMgr::setViewOffset_deg (double offset)
|
|||
{
|
||||
FGViewer * view = get_current_view();
|
||||
if (view != 0)
|
||||
view->set_view_offset(offset * SGD_DEGREES_TO_RADIANS);
|
||||
view->setHeadingOffset_deg(offset);
|
||||
}
|
||||
|
||||
double
|
||||
FGViewMgr::getGoalViewOffset_deg () const
|
||||
{
|
||||
const FGViewer * view = get_current_view();
|
||||
return (view == 0 ? 0 : view->get_goal_view_offset() * SGD_RADIANS_TO_DEGREES);
|
||||
return (view == 0 ? 0 : view->get_goal_view_offset());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -185,14 +192,14 @@ FGViewMgr::setGoalViewOffset_deg (double offset)
|
|||
{
|
||||
FGViewer * view = get_current_view();
|
||||
if (view != 0)
|
||||
view->set_goal_view_offset(offset * SGD_DEGREES_TO_RADIANS);
|
||||
view->set_goal_view_offset(offset);
|
||||
}
|
||||
|
||||
double
|
||||
FGViewMgr::getViewTilt_deg () const
|
||||
{
|
||||
const FGViewer * view = get_current_view();
|
||||
return (view == 0 ? 0 : view->get_view_tilt() * SGD_RADIANS_TO_DEGREES);
|
||||
return (view == 0 ? 0 : view->getPitchOffset_deg());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -200,14 +207,14 @@ FGViewMgr::setViewTilt_deg (double tilt)
|
|||
{
|
||||
FGViewer * view = get_current_view();
|
||||
if (view != 0)
|
||||
view->set_view_tilt(tilt * SGD_DEGREES_TO_RADIANS);
|
||||
view->setPitchOffset_deg(tilt);
|
||||
}
|
||||
|
||||
double
|
||||
FGViewMgr::getGoalViewTilt_deg () const
|
||||
{
|
||||
const FGViewer * view = get_current_view();
|
||||
return (view == 0 ? 0 : view->get_goal_view_tilt() * SGD_RADIANS_TO_DEGREES);
|
||||
return (view == 0 ? 0 : view->get_goal_view_tilt());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -215,7 +222,7 @@ FGViewMgr::setGoalViewTilt_deg (double tilt)
|
|||
{
|
||||
FGViewer * view = get_current_view();
|
||||
if (view != 0)
|
||||
view->set_goal_view_tilt(tilt * SGD_DEGREES_TO_RADIANS);
|
||||
view->set_goal_view_tilt(tilt);
|
||||
}
|
||||
|
||||
double
|
||||
|
@ -224,8 +231,7 @@ FGViewMgr::getPilotXOffset_m () const
|
|||
// FIXME: hard-coded pilot view position
|
||||
const FGViewer * pilot_view = get_view(0);
|
||||
if (pilot_view != 0) {
|
||||
float * offset = ((FGViewer *)pilot_view)->get_pilot_offset();
|
||||
return offset[0];
|
||||
return ((FGViewer *)pilot_view)->getXOffset_m();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -237,8 +243,7 @@ FGViewMgr::setPilotXOffset_m (double x)
|
|||
// FIXME: hard-coded pilot view position
|
||||
FGViewer * pilot_view = get_view(0);
|
||||
if (pilot_view != 0) {
|
||||
float * offset = pilot_view->get_pilot_offset();
|
||||
pilot_view->set_pilot_offset(x, offset[1], offset[2]);
|
||||
pilot_view->setXOffset_m(x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,8 +253,7 @@ FGViewMgr::getPilotYOffset_m () const
|
|||
// FIXME: hard-coded pilot view position
|
||||
const FGViewer * pilot_view = get_view(0);
|
||||
if (pilot_view != 0) {
|
||||
float * offset = ((FGViewer *)pilot_view)->get_pilot_offset();
|
||||
return offset[1];
|
||||
return ((FGViewer *)pilot_view)->getYOffset_m();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -261,8 +265,7 @@ FGViewMgr::setPilotYOffset_m (double y)
|
|||
// FIXME: hard-coded pilot view position
|
||||
FGViewer * pilot_view = get_view(0);
|
||||
if (pilot_view != 0) {
|
||||
float * offset = pilot_view->get_pilot_offset();
|
||||
pilot_view->set_pilot_offset(offset[0], y, offset[2]);
|
||||
pilot_view->setYOffset_m(y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,8 +275,7 @@ FGViewMgr::getPilotZOffset_m () const
|
|||
// FIXME: hard-coded pilot view position
|
||||
const FGViewer * pilot_view = get_view(0);
|
||||
if (pilot_view != 0) {
|
||||
float * offset = ((FGViewer *)pilot_view)->get_pilot_offset();
|
||||
return offset[2];
|
||||
return ((FGViewer *)pilot_view)->getZOffset_m();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -285,8 +287,7 @@ FGViewMgr::setPilotZOffset_m (double z)
|
|||
// FIXME: hard-coded pilot view position
|
||||
FGViewer * pilot_view = get_view(0);
|
||||
if (pilot_view != 0) {
|
||||
float * offset = pilot_view->get_pilot_offset();
|
||||
pilot_view->set_pilot_offset(offset[0], offset[1], z);
|
||||
pilot_view->setZOffset_m(z);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,5 +359,6 @@ FGViewMgr::do_axes ()
|
|||
viewDir = SGD_RADIANS_TO_DEGREES * atan2 ( -axis_lat, -axis_long );
|
||||
if ( viewDir < -1 ) viewDir += 360;
|
||||
|
||||
get_current_view()->set_goal_view_offset(viewDir*SGD_DEGREES_TO_RADIANS);
|
||||
get_current_view()->set_goal_view_offset(viewDir);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,8 +39,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "fgfs.hxx"
|
||||
#include "viewer_lookat.hxx"
|
||||
#include "viewer_rph.hxx"
|
||||
#include "viewer.hxx"
|
||||
|
||||
SG_USING_STD(vector);
|
||||
|
||||
|
@ -107,8 +106,10 @@ public:
|
|||
// setters
|
||||
inline void clear() { views.clear(); }
|
||||
inline void set_view( const int v ) { current = v; }
|
||||
inline void add_view( FGViewer * v ) {
|
||||
inline void add_view( FGViewer * v, int type ) {
|
||||
views.push_back(v);
|
||||
v->setType(type);
|
||||
v->init();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -146,3 +147,7 @@ private:
|
|||
|
||||
|
||||
#endif // _VIEWMGR_HXX
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ bool FGNewCache::make_space() {
|
|||
if ( e->is_loaded() && (e->get_pending_models() == 0) ) {
|
||||
// calculate approximate distance from view point
|
||||
sgdCopyVec3( abs_view_pos,
|
||||
globals->get_current_view()->get_abs_view_pos() );
|
||||
globals->get_current_view()->get_absolute_view_pos() );
|
||||
|
||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "DIST Abs view pos = "
|
||||
<< abs_view_pos[0] << ","
|
||||
|
@ -220,3 +220,4 @@ bool FGNewCache::insert_tile( FGTileEntry *e ) {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -403,7 +403,7 @@ int FGTileMgr::update( double lon, double lat ) {
|
|||
scenery.get_center()[0],
|
||||
scenery.get_center()[1],
|
||||
scenery.get_center()[2] );
|
||||
hit = fgCurrentElev(globals->get_current_view()->get_abs_view_pos(),
|
||||
hit = fgCurrentElev(globals->get_current_view()->get_absolute_view_pos(),
|
||||
sc,
|
||||
current_tile->get_terra_transform(),
|
||||
&hit_list,
|
||||
|
@ -452,3 +452,4 @@ void FGTileMgr::prep_ssg_nodes() {
|
|||
tile_cache.next();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -175,17 +175,17 @@ void fgLIGHT::UpdateAdjFog( void ) {
|
|||
SG_LOG( SG_EVENT, SG_ALERT, "Psi rotation bad = " << f->get_Psi() );
|
||||
exit(-1);
|
||||
}
|
||||
if ( globals->get_current_view()->get_view_offset() < -2.0 * SGD_2PI ||
|
||||
globals->get_current_view()->get_view_offset() > 2.0 * SGD_2PI ) {
|
||||
if ( globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS < -2.0 * SGD_2PI ||
|
||||
globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS > 2.0 * SGD_2PI ) {
|
||||
SG_LOG( SG_EVENT, SG_ALERT, "current view()->view offset bad = "
|
||||
<< globals->get_current_view()->get_view_offset() );
|
||||
<< globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// first determine the difference between our view angle and local
|
||||
// direction to the sun
|
||||
rotation = -(sun_rotation + SGD_PI)
|
||||
- (f->get_Psi() - globals->get_current_view()->get_view_offset());
|
||||
- (f->get_Psi() - globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS);
|
||||
if ( globals->get_current_view()->get_reverse_view_offset() ) {
|
||||
rotation += SGD_PI;
|
||||
}
|
||||
|
@ -241,3 +241,4 @@ fgLIGHT::~fgLIGHT( void ) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue