1
0
Fork 0

Minor patch from David Megginson:

Fix FGViewer::update so that pitch offset and goal pitch offset work
together nicely (the offset was snapping to 90/-90 when only one of
the two was changed).


Viewer improvements from Jim Wilson:

These files get the 3d cockpit working and fix a few issues in the viewer
code.
XYZ offsets are now defined as follows: X -left/right+ (along wing axis), Y
-up/down+ perpendicular to the aircraft, Z is -in/out+ the aircraft's body axis.
I've also done some cleaning up of unused and mostly unusable interfaces,
added commentary to the *.hxx, combined together some duplicate code and
eliminated a couple unecessary operations.  I also moved what was left of the
"protected" zone to "private" since we aren't subclassing this anymore.
This commit is contained in:
david 2002-03-25 14:32:13 +00:00
parent cf7f245b32
commit 780b4a813e
4 changed files with 308 additions and 346 deletions

View file

@ -148,6 +148,8 @@ FGAircraftModel::unbind ()
void
FGAircraftModel::update (int dt)
{
sgMat4 VIEW_ROT;
_current_timestamp.stamp();
long elapsed_ms = (_current_timestamp - _last_timestamp) / 1000;
_last_timestamp.stamp();
@ -165,7 +167,11 @@ FGAircraftModel::update (int dt)
(FGViewer *)globals->get_viewmgr()->get_view( 0 );
sgMat4 sgTRANS;
sgMakeTransMat4( sgTRANS, pilot_view->get_view_pos() );
// FIXME: this needs to be unlinked from the viewer
// The lon/lat/alt should come from properties and the
// calculation for relative position should probably be
// added to SimGear.
sgMakeTransMat4( sgTRANS, pilot_view->getRelativeViewPos() );
sgVec3 ownship_up;
sgSetVec3( ownship_up, 0.0, 0.0, 1.0);
@ -175,47 +181,41 @@ FGAircraftModel::update (int dt)
sgMat4 sgTUX;
sgCopyMat4( sgTUX, sgROT );
sgMat4 VIEW_ROT;
sgCopyMat4( VIEW_ROT, pilot_view->get_VIEW_ROT());
if (view_number == 0) {
// FIXME: orientation is not applied
// correctly when view is not forward
sgMakeRotMat4( sgROT, -pilot_view->getHeadingOffset_deg(),
pilot_view->get_world_up() );
/* Warning lame hack from Wilson ahead */
/* get the pitch value */
/* double it to counter the value already in the VIEW_ROT */
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
*/
sgMat4 PunROT;
PunROT[0][0] = SG_ONE;
PunROT[0][1] = SG_ZERO;
PunROT[0][2] = SG_ZERO;
PunROT[0][3] = SG_ZERO;
PunROT[1][0] = SG_ZERO;
PunROT[1][1] = cos((1 - sgROT[0][0]) * -pitch);
PunROT[1][2] = -sin((1 - sgROT[0][0]) * -pitch);
PunROT[1][3] = SG_ZERO;
PunROT[2][0] = SG_ZERO;
PunROT[2][1] = sin((1 - sgROT[0][0]) * -pitch);
PunROT[2][2] = cos((1 - sgROT[0][0]) * -pitch);
PunROT[2][3] = SG_ZERO;
PunROT[3][0] = SG_ZERO;
PunROT[3][1] = SG_ZERO;
PunROT[3][2] = SG_ZERO;
PunROT[3][3] = SG_ONE;
// FIXME: This needs to be unlinked from the viewer
// The lon/lat/alt should come from properties and the
// calculation for relative position should probably be
// added to SimGear.
// Note that the function for building the LOCAL matrix
// or redone using plib. Should probably be moved to Simgear.
// (cockpit_ROT = LOCAL from viewer).
sgMat4 tmpROT;
sgCopyMat4( tmpROT, pilot_view->get_COCKPIT_ROT() );
sgMat4 cockpit_ROT;
sgCopyMat4( cockpit_ROT, tmpROT );
sgPostMultMat4( sgTUX, PunROT );
sgPostMultMat4( sgTUX, VIEW_ROT );
sgPostMultMat4( sgTUX, sgROT );
// Make the Cockpit rotation matrix (just juggling the vectors).
cockpit_ROT[0][0] = tmpROT[1][0]; // right
cockpit_ROT[0][1] = tmpROT[1][1];
cockpit_ROT[0][2] = tmpROT[1][2];
cockpit_ROT[1][0] = tmpROT[2][0]; // forward
cockpit_ROT[1][1] = tmpROT[2][1];
cockpit_ROT[1][2] = tmpROT[2][2];
cockpit_ROT[2][0] = tmpROT[0][0]; // view_up
cockpit_ROT[2][1] = tmpROT[0][1];
cockpit_ROT[2][2] = tmpROT[0][2];
sgPostMultMat4( sgTUX, cockpit_ROT );
sgPostMultMat4( sgTUX, sgTRANS );
/* end lame hack */
} else {
// FIXME: Model rotation need to be unlinked from the viewer.
// When the cockpit rotation gets removed from viewer
// then it'll be easy to apply offsets and get the equivelant
// of this "VIEW_ROT" thing.
sgCopyMat4( VIEW_ROT, pilot_view->get_VIEW_ROT());
sgPostMultMat4( sgTUX, VIEW_ROT );
sgPostMultMat4( sgTUX, sgTRANS );
}
@ -383,3 +383,4 @@ FGAircraftModel::Animation::setRotation()
// end of model.cxx

View file

@ -52,8 +52,8 @@
// Constructor
FGViewer::FGViewer( void ):
scalingType(FG_SCALING_MAX),
fov(55.0),
_scaling_type(FG_SCALING_MAX),
_fov_deg(55.0),
_dirty(true),
_lon_deg(0),
_lat_deg(0),
@ -74,7 +74,6 @@ FGViewer::FGViewer( void ):
_goal_pitch_offset_deg(0.0)
{
sgdZeroVec3(_absolute_view_pos);
sea_level_radius = SG_EQUATORIAL_RADIUS_M;
//a reasonable guess for init, so that the math doesn't blow up
}
@ -267,10 +266,10 @@ FGViewer::setGoalPitchOffset_deg (double goal_pitch_offset_deg)
{
_dirty = true;
_goal_pitch_offset_deg = goal_pitch_offset_deg;
while ( _goal_pitch_offset_deg < -90 ) {
if ( _goal_pitch_offset_deg < -90 ) {
_goal_pitch_offset_deg = -90.0;
}
while ( _goal_pitch_offset_deg > 90.0 ) {
if ( _goal_pitch_offset_deg > 90.0 ) {
_goal_pitch_offset_deg = 90.0;
}
@ -330,131 +329,147 @@ void
FGViewer::recalc ()
{
sgVec3 minus_z, right, forward, tilt;
sgMat4 VIEWo;
sgMat4 tmpROT; // temp rotation work matrices
sgMat4 VIEW_HEADINGOFFSET, VIEW_PITCHOFFSET;
sgVec3 tmpVec3; // temp work vector (3)
// 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
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
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 coordinates generated by the above "recalcPositionVectors"
sgCopyVec3(_zero_elev, _zero_elev_view_pos);
sgCopyVec3(_view_pos, _relative_view_pos);
// 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;
// get the world up radial vector from planet center
// (ie. effect of aircraft location on earth "sphere" approximation)
sgSetVec3( _world_up, UP[0][0], UP[0][1], UP[0][2] );
// Creat local matrix with current geodetic position. Converting
// the orientation (pitch/roll/heading) to vectors.
fgMakeLOCAL( LOCAL, _pitch_deg * SG_DEGREES_TO_RADIANS,
_roll_deg * SG_DEGREES_TO_RADIANS,
-_heading_deg * SG_DEGREES_TO_RADIANS);
// Adjust LOCAL to current world_up vector (adjustment for planet location)
sgPostMultMat4( LOCAL, UP );
// make sg vectors view up, right and forward vectors from LOCAL
sgSetVec3( _view_up, LOCAL[0][0], LOCAL[0][1], LOCAL[0][2] );
sgSetVec3( right, LOCAL[1][0], LOCAL[1][1], LOCAL[1][2] );
sgSetVec3( forward, LOCAL[2][0], LOCAL[2][1], LOCAL[2][2] );
// create xyz offsets Vector
sgVec3 position_offset;
sgSetVec3( position_offset, _y_offset_m, _x_offset_m, _z_offset_m );
// generate the heading offset matrix using heading_offset angle(s)
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.
sgMakeRotMat4( VIEW_HEADINGOFFSET, _heading_offset_deg -_heading_deg, _world_up );
}
if (_type == FG_RPH) {
// generate the view offset matrix using orientation offset (heading)
sgMakeRotMat4( VIEW_HEADINGOFFSET, _heading_offset_deg, _view_up );
}
// create a tilt matrix using orientation offset (pitch)
sgMakeRotMat4( VIEW_PITCHOFFSET, _pitch_offset_deg, right );
sgCopyMat4(VIEW_OFFSET, VIEW_HEADINGOFFSET);
sgPreMultMat4(VIEW_OFFSET, VIEW_PITCHOFFSET);
if (_type == FG_LOOKAT) {
// transfrom "offset" and "orientation offset" to vector
sgXformVec3( position_offset, position_offset, UP );
sgXformVec3( position_offset, position_offset, VIEW_HEADINGOFFSET );
sgXformPnt3( position_offset, position_offset, VIEW_PITCHOFFSET );
sgVec3 object_pos, eye_pos;
// copy to coordinates to 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 );
}
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 );
sgXformVec3( position_offset, position_offset, LOCAL);
// add the offsets including rotations to the coordinates
sgAddVec3( _view_pos, position_offset );
// get the world up verctor from the worldup rotation matrix
sgSetVec3( world_up, UP[0][0], UP[0][1], UP[0][2] );
// Make the VIEW matrix.
VIEW[0][0] = right[0];
VIEW[0][1] = right[1];
VIEW[0][2] = right[2];
VIEW[1][0] = forward[0];
VIEW[1][1] = forward[1];
VIEW[1][2] = forward[2];
VIEW[2][0] = _view_up[0];
VIEW[2][1] = _view_up[1];
VIEW[2][2] = _view_up[2];
// multiply the OFFSETS (for heading and pitch) into the VIEW
sgPostMultMat4(VIEW, VIEW_OFFSET);
// VIEWo becomes the rotation matrix with world_up incorporated
sgCopyMat4( VIEWo, LOCAL );
sgPostMultMat4( VIEWo, UP );
// add the position data to the matrix
VIEW[3][0] = _view_pos[0];
VIEW[3][1] = _view_pos[1];
VIEW[3][2] = _view_pos[2];
VIEW[3][3] = 1.0f;
// 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 );
// copy the LOCAL matrix to COCKPIT_ROT for publication...
sgCopyMat4( COCKPIT_ROT, LOCAL );
}
// 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;
// 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);
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);
sgNegateVec3(world_down, _world_up);
sgVectorProductVec3(_surface_east, _surface_south, world_down);
set_clean();
}
@ -506,16 +521,16 @@ FGViewer::recalcPositionVectors (double lon_deg, double lat_deg, double alt_ft)
double
FGViewer::get_h_fov()
{
switch (scalingType) {
switch (_scaling_type) {
case FG_SCALING_WIDTH: // h_fov == fov
return fov;
return _fov_deg;
case FG_SCALING_MAX:
if (aspect_ratio < 1.0) {
if (_aspect_ratio < 1.0) {
// h_fov == fov
return fov;
return _fov_deg;
} else {
// v_fov == fov
return atan(tan(fov/2 * SG_DEGREES_TO_RADIANS) / aspect_ratio) *
return atan(tan(_fov_deg/2 * SG_DEGREES_TO_RADIANS) / _aspect_ratio) *
SG_RADIANS_TO_DEGREES * 2;
}
default:
@ -526,18 +541,18 @@ FGViewer::get_h_fov()
double
FGViewer::get_v_fov()
{
switch (scalingType) {
switch (_scaling_type) {
case FG_SCALING_WIDTH: // h_fov == fov
return atan(tan(fov/2 * SG_DEGREES_TO_RADIANS) * aspect_ratio) *
return atan(tan(_fov_deg/2 * SG_DEGREES_TO_RADIANS) * _aspect_ratio) *
SG_RADIANS_TO_DEGREES * 2;
case FG_SCALING_MAX:
if (aspect_ratio < 1.0) {
if (_aspect_ratio < 1.0) {
// h_fov == fov
return atan(tan(fov/2 * SG_DEGREES_TO_RADIANS) * aspect_ratio) *
return atan(tan(_fov_deg/2 * SG_DEGREES_TO_RADIANS) * _aspect_ratio) *
SG_RADIANS_TO_DEGREES * 2;
} else {
// v_fov == fov
return fov;
return _fov_deg;
}
default:
assert(false);
@ -558,21 +573,21 @@ FGViewer::update (int dt)
if ( _goal_heading_offset_deg > _heading_offset_deg )
{
if ( _goal_heading_offset_deg - _heading_offset_deg < 180 ){
inc_view_offset( 0.5 );
incHeadingOffset_deg( 0.5 );
} else {
inc_view_offset( -0.5 );
incHeadingOffset_deg( -0.5 );
}
} else {
if ( _heading_offset_deg - _goal_heading_offset_deg < 180 ){
inc_view_offset( -0.5 );
incHeadingOffset_deg( -0.5 );
} else {
inc_view_offset( 0.5 );
incHeadingOffset_deg( 0.5 );
}
}
if ( _heading_offset_deg > 360 ) {
inc_view_offset( -360 );
incHeadingOffset_deg( -360 );
} else if ( _heading_offset_deg < 0 ) {
inc_view_offset( 360 );
incHeadingOffset_deg( 360 );
}
}
}
@ -583,20 +598,12 @@ FGViewer::update (int dt)
break;
} else {
// move current_view.pitch_offset_deg towards
// current_view.goal_view_tilt
// current_view.goal_pitch_offset
if ( _goal_pitch_offset_deg > _pitch_offset_deg )
{
if ( _goal_pitch_offset_deg - _pitch_offset_deg < 0 ){
inc_view_tilt( 1.0 );
} else {
inc_view_tilt( -1.0 );
}
incPitchOffset_deg( 1.0 );
} else {
if ( _pitch_offset_deg - _goal_pitch_offset_deg < 0 ){
inc_view_tilt( -1.0 );
} else {
inc_view_tilt( 1.0 );
}
incPitchOffset_deg( -1.0 );
}
if ( _pitch_offset_deg > 90 ) {
setPitchOffset_deg(90);
@ -607,76 +614,6 @@ FGViewer::update (int dt)
}
}
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)
{
@ -708,6 +645,4 @@ void FGViewer::fgMakeLOCAL( sgMat4 dst, const double Theta,
dst[3][3] = SG_ONE ;
}
/* end from rph */

View file

@ -85,38 +85,43 @@ public:
virtual fgViewType getType() const { return _type; }
virtual void setType( int type );
// Reference geodetic position of view from position...
// Reference geodetic position of view from position...
// These are the actual aircraft position (pilot in
// pilot view, model in model view).
// FIXME: the model view position (ie target positions)
// should be in the model class.
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...
// 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
// Position offsets from reference
// These offsets position they "eye" in the scene according to a given
// location. For example in pilot view they are used to position the
// head inside the aircraft.
// Note that in pilot view these are applied "before" the orientation
// rotations (see below) so that the orientation rotations have the
// effect of the pilot staying in his seat and "looking out" in
// different directions.
// In chase view these are applied "after" the application of the
// orientation rotations listed below. This has the effect of the
// eye moving around and "looking at" the object (model) from
// different angles.
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; }
@ -127,9 +132,38 @@ public:
double y_offset_m,
double z_offset_m);
// Orientation offsets from reference
// Goal settings are for smooth transition from prior
// offset when changing view direction.
// Reference orientation rotations...
// These are rotations that represent the plane attitude effect on
// the view (in Pilot view). IE The view frustrum rotates as the plane
// turns, pitches, and rolls.
// In model view (lookat/chaseview) these end up changing the angle that
// the eye is looking at the ojbect (ie the model).
// FIXME: the FGModel class should have its own version of these so that
// it can generate it's own model rotations.
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);
// Orientation offsets rotations from reference orientation.
// Goal settings are for smooth transition from prior
// offset when changing view direction.
// These offsets are in ADDITION to the orientation rotations listed
// above.
// In pilot view they are applied after the position offsets in order to
// give the effect of the pilot looking around.
// In lookat view they are applied before the position offsets so that
// the effect is the eye moving around looking at the object (ie the model)
// from different angles.
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; }
@ -154,39 +188,57 @@ public:
// 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.
// 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.
// 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.
// 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; }
// 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...
// 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_COCKPIT_ROT() { if ( _dirty ) { recalc(); } return COCKPIT_ROT; }
virtual const sgVec4 *get_UP() { if ( _dirty ) { recalc(); } return UP; }
// (future?)
// virtual double get_ground_elev() { if ( _dirty ) { recalc(); } return ground_elev; }
// Public flags...
virtual bool get_reverse_view_offset() const { return _reverse_view_offset; }
//////////////////////////////////////////////////////////////////////
// Part 4: frustrum data setters and getters
//////////////////////////////////////////////////////////////////////
virtual void set_fov( double fov_deg ) {
_fov_deg = fov_deg;
}
virtual double get_fov() const { return _fov_deg; }
virtual double get_h_fov(); // Get horizontal fov, in degrees.
virtual double get_v_fov(); // Get vertical fov, in degrees.
virtual void set_aspect_ratio( double r ) {
_aspect_ratio = r;
}
virtual double get_aspect_ratio() const { return _aspect_ratio; }
private:
//////////////////////////////////////////////////////////////////
// private data //
//////////////////////////////////////////////////////////////////
// flag forcing a recalc of derived view parameters
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;
@ -217,60 +269,57 @@ private:
double _goal_pitch_offset_deg;
double _goal_heading_offset_deg;
protected:
fgViewType _type;
fgScalingType scalingType;
fgScalingType _scaling_type;
// the nominal field of view (angle, in degrees)
double fov;
double _fov_deg;
// ratio of window width and height; height = width * aspect_ratio
double aspect_ratio;
double _aspect_ratio;
bool reverse_view_offset;
bool _reverse_view_offset;
// view position in opengl world coordinates (this is the
// abs_view_pos translated to scenery.center)
sgVec3 view_pos;
// radius to sea level from center of the earth (m)
double sea_level_radius;
sgVec3 _view_pos;
// cartesion coordinates of current lon/lat if at sea level
// translated to scenery.center
sgVec3 zero_elev;
// height ASL of the terrain for our current view position
// (future?) double ground_elev;
sgVec3 _zero_elev;
// surface vector heading south
sgVec3 surface_south;
sgVec3 _surface_south;
// surface vector heading east (used to unambiguously align sky
// with sun)
sgVec3 surface_east;
sgVec3 _surface_east;
// world up vector (normal to the plane tangent to the earth's
// surface at the spot we are directly above
sgVec3 world_up;
// sg versions of our friendly matrices
sgMat4 VIEW, VIEW_ROT, UP;
sgVec3 _world_up;
// up vector for the view (usually point straight up through the
// top of the aircraft
sgVec3 view_up;
sgVec3 _view_up;
// the vector pointing straight out the nose of the aircraft
sgVec3 view_forward;
// // the vector pointing straight out the nose of the aircraft
// sgVec3 _view_forward;
// sg versions of our friendly matrices
sgMat4 VIEW, VIEW_ROT, UP, COCKPIT_ROT;
sgMat4 LOCAL, TRANS, LARC_TO_SSG;
// 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;
//////////////////////////////////////////////////////////////////
// private functions //
//////////////////////////////////////////////////////////////////
void recalc ();
void recalcPositionVectors (double lon_deg, double lat_deg, double alt_ft) const;
inline void set_dirty() { _dirty = true; }
inline void set_clean() { _dirty = false; }
@ -285,68 +334,44 @@ protected:
const double Phi, const double Psi);
public:
// add to _heading_offset_deg
inline void incHeadingOffset_deg( double amt ) {
set_dirty();
_heading_offset_deg += amt;
}
// add to _pitch_offset_deg
inline void incPitchOffset_deg( double amt ) {
set_dirty();
_pitch_offset_deg += amt;
}
inline void set_reverse_view_offset( bool val ) {
_reverse_view_offset = val;
}
// public:
//////////////////////////////////////////////////////////////////////
// setter functions
//////////////////////////////////////////////////////////////////////
inline void set_fov( double fov_deg ) {
fov = fov_deg;
}
inline void set_aspect_ratio( double r ) {
aspect_ratio = r;
}
inline void inc_view_offset( double amt ) {
set_dirty();
_heading_offset_deg += amt;
}
inline void set_reverse_view_offset( bool val ) {
reverse_view_offset = val;
}
inline void inc_view_tilt( double amt ) {
set_dirty();
_pitch_offset_deg += amt;
}
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 */
// 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;
// }
//////////////////////////////////////////////////////////////////////
// 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 double get_fov() const { return fov; }
inline double get_aspect_ratio() const { return aspect_ratio; }
inline bool get_reverse_view_offset() const { return reverse_view_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 */
// 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 double get_sea_level_radius() const { return sea_level_radius; }
//////////////////////////////////////////////////////////////////////
// derived values accessor functions
@ -359,3 +384,4 @@ public:

View file

@ -160,7 +160,6 @@ FGViewMgr::update (int dt)
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() );
// Update the current view
do_axes();
@ -365,3 +364,4 @@ FGViewMgr::do_axes ()
}