void
FGAircraftModel::update (int dt)
{
+ sgMat4 VIEW_ROT;
+
_current_timestamp.stamp();
long elapsed_ms = (_current_timestamp - _last_timestamp) / 1000;
_last_timestamp.stamp();
(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);
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;
-
- sgPostMultMat4( sgTUX, PunROT );
- sgPostMultMat4( sgTUX, VIEW_ROT );
- sgPostMultMat4( sgTUX, sgROT );
+
+ // 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 );
+
+ // 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 );
}
// end of model.cxx
+
// 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),
_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
}
{
_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;
}
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 );
+ // Make the world up rotation matrix for lookat
+ sgMakeRotMat4( UP, _target_lon_deg, 0.0, -_target_lat_deg );
}
+ // the coordinates generated by the above "recalcPositionVectors"
+ sgCopyVec3(_zero_elev, _zero_elev_view_pos);
+ sgCopyVec3(_view_pos, _relative_view_pos);
- 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] );
+ // 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] );
- 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 );
+ // 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] );
- // 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 );
+ // create xyz offsets Vector
+ sgVec3 position_offset;
+ sgSetVec3( position_offset, _y_offset_m, _x_offset_m, _z_offset_m );
- // 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;
+ // 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 );
+ }
- // 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] );
+ // 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);
- // 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] );
+ 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 );
- // 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 );
+ sgVec3 object_pos, eye_pos;
+ // copy to coordinates to object...
+ sgCopyVec3( object_pos, _view_pos );
- // 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 );
+ // add the offsets from object to the coordinates to get "eye"
+ sgAddVec3( eye_pos, _view_pos, position_offset );
- sgVec3 trans_vec;
- sgAddVec3( trans_vec, view_pos, pilot_offset_world );
+ // Make the VIEW matrix for "lookat".
+ sgMakeLookAtMat4( VIEW, eye_pos, object_pos, _view_up );
+ }
+
+ if (_type == FG_RPH) {
- // VIEW = VIEW_ROT * TRANS
- sgCopyMat4( VIEW, VIEW_ROT );
- sgPostMultMat4ByTransMat4( VIEW, trans_vec );
+ sgXformVec3( position_offset, position_offset, LOCAL);
+ // add the offsets including rotations to the coordinates
+ sgAddVec3( _view_pos, position_offset );
+ // 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);
+
+ // 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;
+
+
+ // 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();
}
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:
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);
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 );
}
}
}
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);
}
}
-
-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)
{
dst[3][3] = SG_ONE ;
}
-/* end from rph */
-
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; }
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; }
// 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;
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; }
const double Phi, const double Psi);
-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 ) {
+ // add to _heading_offset_deg
+ inline void incHeadingOffset_deg( 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 ) {
+
+ // add to _pitch_offset_deg
+ inline void incPitchOffset_deg( 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 );
+ inline void set_reverse_view_offset( bool val ) {
+ _reverse_view_offset = val;
}
- /* end from lookat */
+
+
+// public:
+
+
+ //////////////////////////////////////////////////////////////////////
+ // setter functions
+ //////////////////////////////////////////////////////////////////////
+
+// 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
+