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:
parent
cf7f245b32
commit
780b4a813e
4 changed files with 308 additions and 346 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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 ()
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue