Modified Files:
Time/tmp.cxx Main/viewer.hxx Main/viewer.cxx Main/renderer.cxx Get rid of an other OSGFIXME. The view matrix had some plib specials included. The viewer is now updated for that.
This commit is contained in:
parent
b8f9a40fc6
commit
7e5d6d1d75
4 changed files with 213 additions and 419 deletions
|
@ -278,6 +278,12 @@ FGRenderer::init( void ) {
|
|||
sceneView->setUpdateVisitor(new SGUpdateVisitor);
|
||||
|
||||
sceneView->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
|
||||
sceneView->getCamera()->setViewMatrix(osg::Matrix(0, 0,-1, 0,
|
||||
1, 0, 0, 0,
|
||||
0,-1, 0, 0,
|
||||
0, 0, 0, 1));
|
||||
|
||||
sceneView->getCamera()->setClearMask(0);
|
||||
|
||||
osg::StateSet* stateSet = mRoot->getOrCreateStateSet();
|
||||
|
@ -412,6 +418,7 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
|||
bool enhanced_lighting = fgGetBool("/sim/rendering/enhanced-lighting");
|
||||
bool distance_attenuation
|
||||
= fgGetBool("/sim/rendering/distance-attenuation");
|
||||
// OSGFIXME
|
||||
SGConfigureDirectionalLights( use_point_sprites, enhanced_lighting,
|
||||
distance_attenuation );
|
||||
|
||||
|
@ -461,26 +468,12 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
|||
resize( fgGetInt("/sim/startup/xsize"),
|
||||
fgGetInt("/sim/startup/ysize") );
|
||||
|
||||
// OSGFXME: compute the view directly without indirection through ssg
|
||||
sgMat4 viewmat;
|
||||
sgTransposeNegateMat4(viewmat, (sgVec4 *)current__view->get_VIEW());
|
||||
sgMat4 cameraMatrix = {
|
||||
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, -1.0f, 0.0f },
|
||||
{ 0.0f, 1.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 1.0f }
|
||||
};
|
||||
sgPreMultMat4(cameraMatrix, viewmat);
|
||||
|
||||
osg::Matrixd m;
|
||||
for (unsigned i = 0; i < 4; ++i)
|
||||
for (unsigned j = 0; j < 4; ++j)
|
||||
m(i, j) = cameraMatrix[i][j];
|
||||
|
||||
osg::Quat attitude;
|
||||
attitude.set(m);
|
||||
mCameraView->setPosition(osg::Vec3d(m(3,0), m(3,1), m(3,2)));
|
||||
mCameraView->setAttitude(attitude);
|
||||
SGVec3d center = globals->get_scenery()->get_center();
|
||||
SGVec3d position = current__view->getViewPosition();
|
||||
SGQuatd attitude = current__view->getViewOrientation();
|
||||
SGVec3d osgPosition = attitude.transform(center - position);
|
||||
mCameraView->setPosition(osgPosition.osg());
|
||||
mCameraView->setAttitude(inverse(attitude).osg());
|
||||
}
|
||||
|
||||
if ( skyblend ) {
|
||||
|
@ -520,9 +513,9 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
|||
|
||||
static SGSkyState sstate;
|
||||
|
||||
sstate.view_pos = SGVec3f(current__view->get_view_pos());
|
||||
sstate.zero_elev = SGVec3f(current__view->get_zero_elev());
|
||||
sstate.view_up = SGVec3f(current__view->get_world_up());
|
||||
sstate.view_pos = current__view->get_view_pos();
|
||||
sstate.zero_elev = current__view->get_zero_elev();
|
||||
sstate.view_up = current__view->get_world_up();
|
||||
sstate.lon = current__view->getLongitude_deg()
|
||||
* SGD_DEGREES_TO_RADIANS;
|
||||
sstate.lat = current__view->getLatitude_deg()
|
||||
|
|
|
@ -51,124 +51,6 @@
|
|||
#include "viewer.hxx"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Norman's Optimized matrix rotators! //
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Since these are pure rotation matrices we can save some bookwork
|
||||
// by considering them to be 3x3 until the very end -- NHV
|
||||
static void MakeVIEW_OFFSET( sgMat4 dst,
|
||||
const float angle1, const sgVec3 axis1,
|
||||
const float angle2, const sgVec3 axis2,
|
||||
const float angle3, const sgVec3 axis3 )
|
||||
{
|
||||
// make rotmatrix1 from angle and axis
|
||||
float s = (float) sin ( angle1 ) ;
|
||||
float c = (float) cos ( angle1 ) ;
|
||||
float t = SG_ONE - c ;
|
||||
|
||||
sgMat3 mat1;
|
||||
float tmp = t * axis1[0];
|
||||
mat1[0][0] = tmp * axis1[0] + c ;
|
||||
mat1[0][1] = tmp * axis1[1] + s * axis1[2] ;
|
||||
mat1[0][2] = tmp * axis1[2] - s * axis1[1] ;
|
||||
|
||||
tmp = t * axis1[1];
|
||||
mat1[1][0] = tmp * axis1[0] - s * axis1[2] ;
|
||||
mat1[1][1] = tmp * axis1[1] + c ;
|
||||
mat1[1][2] = tmp * axis1[2] + s * axis1[0] ;
|
||||
|
||||
tmp = t * axis1[2];
|
||||
mat1[2][0] = tmp * axis1[0] + s * axis1[1] ;
|
||||
mat1[2][1] = tmp * axis1[1] - s * axis1[0] ;
|
||||
mat1[2][2] = tmp * axis1[2] + c ;
|
||||
|
||||
// make rotmatrix2 from angle and axis
|
||||
s = (float) sin ( angle2 ) ;
|
||||
c = (float) cos ( angle2 ) ;
|
||||
t = SG_ONE - c ;
|
||||
|
||||
sgMat3 mat2;
|
||||
tmp = t * axis2[0];
|
||||
mat2[0][0] = tmp * axis2[0] + c ;
|
||||
mat2[0][1] = tmp * axis2[1] + s * axis2[2] ;
|
||||
mat2[0][2] = tmp * axis2[2] - s * axis2[1] ;
|
||||
|
||||
tmp = t * axis2[1];
|
||||
mat2[1][0] = tmp * axis2[0] - s * axis2[2] ;
|
||||
mat2[1][1] = tmp * axis2[1] + c ;
|
||||
mat2[1][2] = tmp * axis2[2] + s * axis2[0] ;
|
||||
|
||||
tmp = t * axis2[2];
|
||||
mat2[2][0] = tmp * axis2[0] + s * axis2[1] ;
|
||||
mat2[2][1] = tmp * axis2[1] - s * axis2[0] ;
|
||||
mat2[2][2] = tmp * axis2[2] + c ;
|
||||
|
||||
|
||||
// make rotmatrix3 from angle and axis (roll)
|
||||
s = (float) sin ( angle3 ) ;
|
||||
c = (float) cos ( angle3 ) ;
|
||||
t = SG_ONE - c ;
|
||||
|
||||
sgMat3 mat3;
|
||||
tmp = t * axis3[0];
|
||||
mat3[0][0] = tmp * axis3[0] + c ;
|
||||
mat3[0][1] = tmp * axis3[1] + s * axis3[2] ;
|
||||
mat3[0][2] = tmp * axis3[2] - s * axis3[1] ;
|
||||
|
||||
tmp = t * axis3[1];
|
||||
mat3[1][0] = tmp * axis3[0] - s * axis3[2] ;
|
||||
mat3[1][1] = tmp * axis3[1] + c ;
|
||||
mat3[1][2] = tmp * axis3[2] + s * axis3[0] ;
|
||||
|
||||
tmp = t * axis3[2];
|
||||
mat3[2][0] = tmp * axis3[0] + s * axis3[1] ;
|
||||
mat3[2][1] = tmp * axis3[1] - s * axis3[0] ;
|
||||
mat3[2][2] = tmp * axis3[2] + c ;
|
||||
|
||||
sgMat3 matt;
|
||||
|
||||
// multiply matrices
|
||||
for ( int j = 0 ; j < 3 ; j++ ) {
|
||||
matt[0][j] = mat2[0][0] * mat1[0][j] +
|
||||
mat2[0][1] * mat1[1][j] +
|
||||
mat2[0][2] * mat1[2][j];
|
||||
|
||||
matt[1][j] = mat2[1][0] * mat1[0][j] +
|
||||
mat2[1][1] * mat1[1][j] +
|
||||
mat2[1][2] * mat1[2][j];
|
||||
|
||||
matt[2][j] = mat2[2][0] * mat1[0][j] +
|
||||
mat2[2][1] * mat1[1][j] +
|
||||
mat2[2][2] * mat1[2][j];
|
||||
}
|
||||
|
||||
// multiply matrices
|
||||
for ( int j = 0 ; j < 3 ; j++ ) {
|
||||
dst[0][j] = mat3[0][0] * matt[0][j] +
|
||||
mat3[0][1] * matt[1][j] +
|
||||
mat3[0][2] * matt[2][j];
|
||||
|
||||
dst[1][j] = mat3[1][0] * matt[0][j] +
|
||||
mat3[1][1] * matt[1][j] +
|
||||
mat3[1][2] * matt[2][j];
|
||||
|
||||
dst[2][j] = mat3[2][0] * matt[0][j] +
|
||||
mat3[2][1] * matt[1][j] +
|
||||
mat3[2][2] * matt[2][j];
|
||||
}
|
||||
// fill in 4x4 matrix elements
|
||||
dst[0][3] = SG_ZERO;
|
||||
dst[1][3] = SG_ZERO;
|
||||
dst[2][3] = SG_ZERO;
|
||||
dst[3][0] = SG_ZERO;
|
||||
dst[3][1] = SG_ZERO;
|
||||
dst[3][2] = SG_ZERO;
|
||||
dst[3][3] = SG_ONE;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of FGViewer.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -197,9 +79,11 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index,
|
|||
_damp_roll(0),
|
||||
_damp_pitch(0),
|
||||
_damp_heading(0),
|
||||
_scaling_type(FG_SCALING_MAX)
|
||||
_scaling_type(FG_SCALING_MAX),
|
||||
_location(0),
|
||||
_target_location(0)
|
||||
{
|
||||
sgdZeroVec3(_absolute_view_pos);
|
||||
_absolute_view_pos = SGVec3d(0, 0, 0);
|
||||
_type = Type;
|
||||
_from_model = from_model;
|
||||
_from_model_index = from_model_index;
|
||||
|
@ -215,9 +99,9 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index,
|
|||
if (damp_heading > 0.0)
|
||||
_damp_heading = 1.0 / pow(10.0, fabs(damp_heading));
|
||||
|
||||
_x_offset_m = x_offset_m;
|
||||
_y_offset_m = y_offset_m;
|
||||
_z_offset_m = z_offset_m;
|
||||
_offset_m.x() = x_offset_m;
|
||||
_offset_m.y() = y_offset_m;
|
||||
_offset_m.z() = z_offset_m;
|
||||
_heading_offset_deg = heading_offset_deg;
|
||||
_pitch_offset_deg = pitch_offset_deg;
|
||||
_roll_offset_deg = roll_offset_deg;
|
||||
|
@ -230,9 +114,9 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index,
|
|||
_fov_deg = 55;
|
||||
}
|
||||
_aspect_ratio_multiplier = aspect_ratio_multiplier;
|
||||
_target_x_offset_m = target_x_offset_m;
|
||||
_target_y_offset_m = target_y_offset_m;
|
||||
_target_z_offset_m = target_z_offset_m;
|
||||
_target_offset_m.x() = target_x_offset_m;
|
||||
_target_offset_m.y() = target_y_offset_m;
|
||||
_target_offset_m.z() = target_z_offset_m;
|
||||
_ground_level_nearplane_m = near_m;
|
||||
// a reasonable guess for init, so that the math doesn't blow up
|
||||
}
|
||||
|
@ -248,7 +132,7 @@ FGViewer::init ()
|
|||
if ( _from_model )
|
||||
_location = (SGLocation *) globals->get_aircraft_model()->get3DModel()->getSGLocation();
|
||||
else
|
||||
_location = (SGLocation *) new SGLocation;
|
||||
_location = new SGLocation;
|
||||
|
||||
if ( _type == FG_LOOKAT ) {
|
||||
if ( _at_model )
|
||||
|
@ -407,51 +291,51 @@ void
|
|||
FGViewer::setXOffset_m (double x_offset_m)
|
||||
{
|
||||
_dirty = true;
|
||||
_x_offset_m = x_offset_m;
|
||||
_offset_m.x() = x_offset_m;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setYOffset_m (double y_offset_m)
|
||||
{
|
||||
_dirty = true;
|
||||
_y_offset_m = y_offset_m;
|
||||
_offset_m.y() = y_offset_m;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setZOffset_m (double z_offset_m)
|
||||
{
|
||||
_dirty = true;
|
||||
_z_offset_m = z_offset_m;
|
||||
_offset_m.z() = z_offset_m;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setTargetXOffset_m (double target_x_offset_m)
|
||||
{
|
||||
_dirty = true;
|
||||
_target_x_offset_m = target_x_offset_m;
|
||||
_target_offset_m.x() = target_x_offset_m;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setTargetYOffset_m (double target_y_offset_m)
|
||||
{
|
||||
_dirty = true;
|
||||
_target_y_offset_m = target_y_offset_m;
|
||||
_target_offset_m.y() = target_y_offset_m;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setTargetZOffset_m (double target_z_offset_m)
|
||||
{
|
||||
_dirty = true;
|
||||
_target_z_offset_m = target_z_offset_m;
|
||||
_target_offset_m.z() = target_z_offset_m;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::setPositionOffsets (double x_offset_m, double y_offset_m, double z_offset_m)
|
||||
{
|
||||
_dirty = true;
|
||||
_x_offset_m = x_offset_m;
|
||||
_y_offset_m = y_offset_m;
|
||||
_z_offset_m = z_offset_m;
|
||||
_offset_m.x() = x_offset_m;
|
||||
_offset_m.y() = y_offset_m;
|
||||
_offset_m.z() = z_offset_m;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -523,38 +407,7 @@ FGViewer::get_absolute_view_pos ()
|
|||
{
|
||||
if (_dirty)
|
||||
recalc();
|
||||
return _absolute_view_pos;
|
||||
}
|
||||
|
||||
float *
|
||||
FGViewer::getRelativeViewPos ()
|
||||
{
|
||||
if (_dirty)
|
||||
recalc();
|
||||
return _relative_view_pos;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::updateFromModelLocation (SGLocation * location)
|
||||
{
|
||||
sgCopyMat4(LOCAL, location->getTransformMatrix());
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::updateAtModelLocation (SGLocation * location)
|
||||
{
|
||||
sgCopyMat4(ATLOCAL, location->getTransformMatrix());
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::recalcOurOwnLocation (SGLocation * location, double lon_deg, double lat_deg, double alt_ft,
|
||||
double roll_deg, double pitch_deg, double heading_deg)
|
||||
{
|
||||
// update from our own data...
|
||||
dampEyeData(roll_deg, pitch_deg, heading_deg);
|
||||
location->setPosition( lon_deg, lat_deg, alt_ft );
|
||||
location->setOrientation( roll_deg, pitch_deg, heading_deg );
|
||||
sgCopyMat4(LOCAL, location->getTransformMatrix());
|
||||
return _absolute_view_pos.data();
|
||||
}
|
||||
|
||||
// recalc() is done every time one of the setters is called (making the
|
||||
|
@ -569,173 +422,17 @@ FGViewer::recalc ()
|
|||
recalcLookAt();
|
||||
}
|
||||
|
||||
set_clean();
|
||||
}
|
||||
|
||||
// recalculate for LookFrom view type...
|
||||
void
|
||||
FGViewer::recalcLookFrom ()
|
||||
{
|
||||
sgVec3 right, forward;
|
||||
sgVec3 position_offset; // eye position offsets (xyz)
|
||||
|
||||
// LOOKFROM mode...
|
||||
|
||||
// Update location data...
|
||||
if ( _from_model ) {
|
||||
// update or data from model location
|
||||
updateFromModelLocation(_location);
|
||||
} else {
|
||||
// update from our own data...
|
||||
recalcOurOwnLocation( _location, _lon_deg, _lat_deg, _alt_ft,
|
||||
_roll_deg, _pitch_deg, _heading_deg );
|
||||
}
|
||||
|
||||
// copy data from location class to local items...
|
||||
copyLocationData();
|
||||
|
||||
// make sg vectors view up, right and forward vectors from LOCAL
|
||||
sgSetVec3( _view_up, LOCAL[2][0], LOCAL[2][1], LOCAL[2][2] );
|
||||
sgSetVec3( right, LOCAL[1][0], LOCAL[1][1], LOCAL[1][2] );
|
||||
sgSetVec3( forward, -LOCAL[0][0], -LOCAL[0][1], -LOCAL[0][2] );
|
||||
|
||||
// Note that when in "lookfrom" view the "view up" vector is always applied
|
||||
// to the viewer. View up is based on verticle of the aircraft itself. (see
|
||||
// "LOCAL" matrix above)
|
||||
|
||||
// Orientation Offsets matrix
|
||||
MakeVIEW_OFFSET( VIEW_OFFSET,
|
||||
_heading_offset_deg * SG_DEGREES_TO_RADIANS, _view_up,
|
||||
_pitch_offset_deg * SG_DEGREES_TO_RADIANS, right,
|
||||
_roll_offset_deg * SG_DEGREES_TO_RADIANS, forward );
|
||||
|
||||
// Make the VIEW matrix.
|
||||
sgSetVec4(VIEW[0], right[0], right[1], right[2],SG_ZERO);
|
||||
sgSetVec4(VIEW[1], forward[0], forward[1], forward[2],SG_ZERO);
|
||||
sgSetVec4(VIEW[2], _view_up[0], _view_up[1], _view_up[2],SG_ZERO);
|
||||
sgSetVec4(VIEW[3], SG_ZERO, SG_ZERO, SG_ZERO,SG_ONE);
|
||||
|
||||
// rotate model or local matrix to get a matrix to apply Eye Position Offsets
|
||||
sgMat4 VIEW_UP; // L0 forward L1 right L2 up
|
||||
sgCopyVec4(VIEW_UP[0], LOCAL[1]);
|
||||
sgCopyVec4(VIEW_UP[1], LOCAL[2]);
|
||||
sgCopyVec4(VIEW_UP[2], LOCAL[0]);
|
||||
sgZeroVec4(VIEW_UP[3]);
|
||||
|
||||
// Eye Position Offsets to vector
|
||||
sgSetVec3( position_offset, _x_offset_m, _y_offset_m, _z_offset_m );
|
||||
sgXformVec3( position_offset, position_offset, VIEW_UP);
|
||||
|
||||
// add the offsets including rotations to the translation vector
|
||||
sgAddVec3( _view_pos, position_offset );
|
||||
|
||||
// multiply the OFFSETS (for heading and pitch) into the VIEW
|
||||
sgPostMultMat4(VIEW, VIEW_OFFSET);
|
||||
|
||||
// add the position data to the matrix
|
||||
sgSetVec4(VIEW[3], _view_pos[0], _view_pos[1], _view_pos[2],SG_ONE);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::recalcLookAt ()
|
||||
{
|
||||
sgVec3 right, forward;
|
||||
sgVec3 eye_pos, at_pos;
|
||||
sgVec3 position_offset; // eye position offsets (xyz)
|
||||
sgVec3 target_position_offset; // target position offsets (xyz)
|
||||
|
||||
// The position vectors originate from the view point or target location
|
||||
// depending on the type of view.
|
||||
|
||||
// LOOKAT mode...
|
||||
|
||||
// Update location data for target...
|
||||
if ( _at_model ) {
|
||||
// update or data from model location
|
||||
updateAtModelLocation(_target_location);
|
||||
} else {
|
||||
// if not model then calculate our own target position...
|
||||
recalcOurOwnLocation( _target_location, _target_lon_deg, _target_lat_deg, _target_alt_ft,
|
||||
_target_roll_deg, _target_pitch_deg, _target_heading_deg );
|
||||
}
|
||||
// calculate the "at" target object positon relative to eye or view's tile center...
|
||||
SGVec3d center = globals->get_scenery()->get_center();
|
||||
sgdVec3 dVec3;
|
||||
sgdSetVec3(dVec3, center[0], center[1], center[2]);
|
||||
sgdSubVec3(dVec3, _target_location->get_absolute_view_pos(), dVec3 );
|
||||
sgSetVec3(at_pos, dVec3[0], dVec3[1], dVec3[2]);
|
||||
_view_pos = toVec3f(_absolute_view_pos - center);
|
||||
|
||||
// Update location data for eye...
|
||||
if ( _from_model ) {
|
||||
// update or data from model location
|
||||
updateFromModelLocation(_location);
|
||||
} else {
|
||||
// update from our own data, just the rotation here...
|
||||
recalcOurOwnLocation( _location, _lon_deg, _lat_deg, _alt_ft,
|
||||
_roll_deg, _pitch_deg, _heading_deg );
|
||||
}
|
||||
// save the eye positon...
|
||||
sgCopyVec3(eye_pos, _location->get_view_pos(center));
|
||||
SGGeod geodEyePoint = SGGeod::fromCart(_absolute_view_pos);
|
||||
geodEyePoint.setElevationM(0);
|
||||
_zero_elev = toVec3f(SGVec3d::fromGeod(geodEyePoint) - center);
|
||||
|
||||
// copy data from location class to local items...
|
||||
copyLocationData();
|
||||
|
||||
// make sg vectors view up, right and forward vectors from LOCAL
|
||||
sgSetVec3( _view_up, LOCAL[2][0], LOCAL[2][1], LOCAL[2][2] );
|
||||
sgSetVec3( right, LOCAL[1][0], LOCAL[1][1], LOCAL[1][2] );
|
||||
sgSetVec3( forward, -LOCAL[0][0], -LOCAL[0][1], -LOCAL[0][2] );
|
||||
|
||||
// rotate model or local matrix to get a matrix to apply Eye Position Offsets
|
||||
sgMat4 VIEW_UP; // L0 forward L1 right L2 up
|
||||
sgCopyVec4(VIEW_UP[0], LOCAL[1]);
|
||||
sgCopyVec4(VIEW_UP[1], LOCAL[2]);
|
||||
sgCopyVec4(VIEW_UP[2], LOCAL[0]);
|
||||
sgZeroVec4(VIEW_UP[3]);
|
||||
|
||||
// get Orientation Offsets matrix
|
||||
MakeVIEW_OFFSET( VIEW_OFFSET,
|
||||
(_heading_offset_deg - 180) * SG_DEGREES_TO_RADIANS, _view_up,
|
||||
_pitch_offset_deg * SG_DEGREES_TO_RADIANS, right,
|
||||
_roll_offset_deg * SG_DEGREES_TO_RADIANS, forward );
|
||||
|
||||
// add in the position offsets
|
||||
sgSetVec3( position_offset, _y_offset_m, _x_offset_m, _z_offset_m );
|
||||
sgXformVec3( position_offset, position_offset, VIEW_UP);
|
||||
|
||||
// apply the Orientation offsets
|
||||
sgXformVec3( position_offset, position_offset, VIEW_OFFSET );
|
||||
|
||||
// add the Position offsets from object to the eye position
|
||||
sgAddVec3( eye_pos, eye_pos, position_offset );
|
||||
|
||||
// add target offsets to at_position...
|
||||
sgSetVec3(target_position_offset, _target_z_offset_m, _target_x_offset_m,
|
||||
_target_y_offset_m );
|
||||
sgXformVec3(target_position_offset, target_position_offset, ATLOCAL);
|
||||
sgAddVec3( at_pos, at_pos, target_position_offset);
|
||||
|
||||
sgAddVec3( eye_pos, eye_pos, target_position_offset);
|
||||
|
||||
// Make the VIEW matrix for a "LOOKAT".
|
||||
sgMakeLookAtMat4( VIEW, eye_pos, at_pos, _view_up );
|
||||
|
||||
}
|
||||
|
||||
// copy results from location class to viewer...
|
||||
// FIXME: some of these should be changed to reference directly to SGLocation...
|
||||
void
|
||||
FGViewer::copyLocationData()
|
||||
{
|
||||
SGVec3d center = globals->get_scenery()->get_center();
|
||||
// Get our friendly vectors from the eye location...
|
||||
sgdCopyVec3(_absolute_view_pos, _location->get_absolute_view_pos());
|
||||
sgCopyVec3(_relative_view_pos, _location->get_view_pos(center));
|
||||
sgCopyMat4(UP, _location->getCachedUpMatrix());
|
||||
sgCopyVec3(_world_up, _location->get_world_up());
|
||||
// these are the vectors that the sun and moon code like to get...
|
||||
sgCopyVec3(_surface_east, _location->get_surface_east());
|
||||
sgCopyVec3(_surface_south, _location->get_surface_south());
|
||||
SGQuatd hlOr = SGQuatd::fromLonLat(geodEyePoint);
|
||||
_surface_south = toVec3f(hlOr.backTransform(-SGVec3d::e1()));
|
||||
_surface_east = toVec3f(hlOr.backTransform(SGVec3d::e2()));
|
||||
_world_up = toVec3f(hlOr.backTransform(-SGVec3d::e3()));
|
||||
|
||||
// Update viewer's postion data for the eye location...
|
||||
_lon_deg = _location->getLongitude_deg();
|
||||
|
@ -755,10 +452,141 @@ FGViewer::copyLocationData()
|
|||
_target_heading_deg = _target_location->getHeading_deg();
|
||||
}
|
||||
|
||||
// copy coordinates to outputs for viewer...
|
||||
sgCopyVec3(_zero_elev, _relative_view_pos);
|
||||
sgAddScaledVec3(_zero_elev, _world_up, -_alt_ft*SG_FEET_TO_METER);
|
||||
sgCopyVec3(_view_pos, _relative_view_pos);
|
||||
set_clean();
|
||||
}
|
||||
|
||||
// recalculate for LookFrom view type...
|
||||
void
|
||||
FGViewer::recalcLookFrom ()
|
||||
{
|
||||
// Update location data ...
|
||||
if ( !_from_model ) {
|
||||
_location->setPosition( _lon_deg, _lat_deg, _alt_ft );
|
||||
_location->setOrientation( _roll_deg, _pitch_deg, _heading_deg );
|
||||
_location->getTransformMatrix();
|
||||
}
|
||||
double lat = _location->getLatitude_deg();
|
||||
double lon = _location->getLongitude_deg();
|
||||
double alt = _location->getAltitudeASL_ft();
|
||||
double head = _location->getHeading_deg();
|
||||
double pitch = _location->getPitch_deg();
|
||||
double roll = _location->getRoll_deg();
|
||||
if ( !_from_model ) {
|
||||
// update from our own data...
|
||||
dampEyeData(roll, pitch, head);
|
||||
}
|
||||
|
||||
// The geodetic position of our base view position
|
||||
SGGeod geodPos = SGGeod::fromDegFt(lon, lat, alt);
|
||||
// The rotation rotating from the earth centerd frame to
|
||||
// the horizontal local frame
|
||||
SGQuatd hlOr = SGQuatd::fromLonLat(geodPos);
|
||||
// the rotation from the horizontal local frame to the basic view orientation
|
||||
SGQuatd hlToBody = SGQuatd::fromYawPitchRollDeg(head, pitch, roll);
|
||||
// The cartesian position of the basic view coordinate
|
||||
SGVec3d position = SGVec3d::fromGeod(geodPos);
|
||||
// the rotation offset, don't know why heading is negative here ...
|
||||
SGQuatd viewOffsetOr =
|
||||
SGQuatd::fromYawPitchRollDeg(-_heading_offset_deg, _pitch_offset_deg,
|
||||
_roll_offset_deg);
|
||||
|
||||
// The offset vector is meant: x +right/-left, y +up/-down, z, +back/-fwd
|
||||
// We work in the body coordinate system which is slightly different
|
||||
SGVec3d off(-_offset_m.z(), _offset_m.x(), -_offset_m.y());
|
||||
|
||||
// Compute the eyepoints orientation and position
|
||||
// wrt the earth centered frame - that is global coorinates
|
||||
SGQuatd ec2body = hlOr*hlToBody;
|
||||
_absolute_view_pos = position + ec2body.backTransform(off);
|
||||
mViewOrientation = ec2body*viewOffsetOr;
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::recalcLookAt ()
|
||||
{
|
||||
// The geodetic position of our target to look at
|
||||
SGGeod geodTargetPos;
|
||||
SGQuatd geodTargetOr;
|
||||
if ( _at_model ) {
|
||||
geodTargetPos = SGGeod::fromDegFt(_target_location->getLongitude_deg(),
|
||||
_target_location->getLatitude_deg(),
|
||||
_target_location->getAltitudeASL_ft());
|
||||
double head = _target_location->getHeading_deg();
|
||||
double pitch = _target_location->getPitch_deg();
|
||||
double roll = _target_location->getRoll_deg();
|
||||
geodTargetOr = SGQuatd::fromYawPitchRollDeg(head, pitch, roll);
|
||||
} else {
|
||||
dampEyeData(_target_roll_deg, _target_pitch_deg, _target_heading_deg);
|
||||
_target_location->setPosition( _target_lon_deg, _target_lat_deg, _target_alt_ft );
|
||||
_target_location->setOrientation( _target_roll_deg, _target_pitch_deg, _target_heading_deg );
|
||||
_target_location->getTransformMatrix();
|
||||
|
||||
// if not model then calculate our own target position...
|
||||
geodTargetPos = SGGeod::fromDegFt(_target_lon_deg,
|
||||
_target_lat_deg,
|
||||
_target_alt_ft);
|
||||
geodTargetOr = SGQuatd::fromYawPitchRollDeg(_target_heading_deg,
|
||||
_target_pitch_deg,
|
||||
_target_roll_deg);
|
||||
}
|
||||
SGQuatd geodTargetHlOr = SGQuatd::fromLonLat(geodTargetPos);
|
||||
|
||||
|
||||
SGGeod geodEyePos;
|
||||
SGQuatd geodEyeOr;
|
||||
if ( _from_model ) {
|
||||
geodEyePos = SGGeod::fromDegFt(_location->getLongitude_deg(),
|
||||
_location->getLatitude_deg(),
|
||||
_location->getAltitudeASL_ft());
|
||||
double head = _location->getHeading_deg();
|
||||
double pitch = _location->getPitch_deg();
|
||||
double roll = _location->getRoll_deg();
|
||||
geodEyeOr = SGQuatd::fromYawPitchRollDeg(head, pitch, roll);
|
||||
} else {
|
||||
dampEyeData(_roll_deg, _pitch_deg, _heading_deg);
|
||||
_location->setPosition( _lon_deg, _lat_deg, _alt_ft );
|
||||
_location->setOrientation( _roll_deg, _pitch_deg, _heading_deg );
|
||||
_location->getTransformMatrix();
|
||||
|
||||
// update from our own data, just the rotation here...
|
||||
geodEyePos = SGGeod::fromDegFt(_lon_deg, _lat_deg, _alt_ft);
|
||||
geodEyeOr = SGQuatd::fromYawPitchRollDeg(_heading_deg,
|
||||
_pitch_deg,
|
||||
_roll_deg);
|
||||
}
|
||||
SGQuatd geodEyeHlOr = SGQuatd::fromLonLat(geodEyePos);
|
||||
|
||||
// the rotation offset, don't know why heading is negative here ...
|
||||
SGQuatd eyeOffsetOr =
|
||||
SGQuatd::fromYawPitchRollDeg(-_heading_offset_deg + 180, _pitch_offset_deg,
|
||||
_roll_offset_deg);
|
||||
|
||||
// Offsets to the eye position
|
||||
SGVec3d eyeOff(-_offset_m.z(), _offset_m.y(), -_offset_m.x());
|
||||
SGQuatd ec2eye = geodEyeHlOr*geodEyeOr;
|
||||
SGVec3d eyeCart = SGVec3d::fromGeod(geodEyePos);
|
||||
eyeCart += (ec2eye*eyeOffsetOr).backTransform(eyeOff);
|
||||
|
||||
SGVec3d atCart = SGVec3d::fromGeod(geodTargetPos);
|
||||
|
||||
// add target offsets to at_position...
|
||||
SGVec3d target_pos_off(-_target_offset_m.z(), _target_offset_m.x(),
|
||||
-_target_offset_m.y());
|
||||
target_pos_off = (geodTargetHlOr*geodTargetOr).backTransform(target_pos_off);
|
||||
atCart += target_pos_off;
|
||||
eyeCart += target_pos_off;
|
||||
|
||||
// Compute the eyepoints orientation and position
|
||||
// wrt the earth centered frame - that is global coorinates
|
||||
_absolute_view_pos = eyeCart;
|
||||
|
||||
// the view direction
|
||||
SGVec3d dir = normalize(atCart - eyeCart);
|
||||
// the up directon
|
||||
SGVec3d up = ec2eye.backTransform(SGVec3d(0, 0, 1));
|
||||
// rotate dir to the 0-th unit vector
|
||||
// rotate up to 2-th unit vector
|
||||
mViewOrientation = SGQuatd::fromRotateTo(dir, 0, up, 2);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -130,12 +130,12 @@ public:
|
|||
// 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; }
|
||||
virtual double getTargetXOffset_m () const { return _target_x_offset_m; }
|
||||
virtual double getTargetYOffset_m () const { return _target_y_offset_m; }
|
||||
virtual double getTargetZOffset_m () const { return _target_z_offset_m; }
|
||||
virtual double getXOffset_m () const { return _offset_m.x(); }
|
||||
virtual double getYOffset_m () const { return _offset_m.y(); }
|
||||
virtual double getZOffset_m () const { return _offset_m.z(); }
|
||||
virtual double getTargetXOffset_m () const { return _target_offset_m.x(); }
|
||||
virtual double getTargetYOffset_m () const { return _target_offset_m.y(); }
|
||||
virtual double getTargetZOffset_m () const { return _target_offset_m.z(); }
|
||||
virtual void setXOffset_m (double x_offset_m);
|
||||
virtual void setYOffset_m (double y_offset_m);
|
||||
virtual void setZOffset_m (double z_offset_m);
|
||||
|
@ -210,23 +210,20 @@ public:
|
|||
// Vectors and positions...
|
||||
|
||||
// Get zero view_pos
|
||||
virtual float * get_view_pos() {if ( _dirty ) { recalc(); } return _view_pos; }
|
||||
const SGVec3f& 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; }
|
||||
const SGVec3f& 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 ();
|
||||
const SGVec3f& get_world_up() {if ( _dirty ) { recalc(); } return _world_up; }
|
||||
// Get surface east vector
|
||||
virtual float *get_surface_east() { if ( _dirty ) { recalc(); } return _surface_east; }
|
||||
const SGVec3f& get_surface_east() { if ( _dirty ) { recalc(); } return _surface_east; }
|
||||
// Get surface south vector
|
||||
virtual float *get_surface_south() {if ( _dirty ) { recalc(); } return _surface_south; }
|
||||
const SGVec3f& get_surface_south() {if ( _dirty ) { recalc(); } return _surface_south; }
|
||||
|
||||
// Matrices...
|
||||
virtual const sgVec4 *get_VIEW() { if ( _dirty ) { recalc(); } return VIEW; }
|
||||
virtual const sgVec4 *get_UP() { if ( _dirty ) { recalc(); } return UP; }
|
||||
const SGVec3d& getViewPosition() { if ( _dirty ) { recalc(); } return _absolute_view_pos; }
|
||||
const SGQuatd& getViewOrientation() { if ( _dirty ) { recalc(); } return mViewOrientation; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Part 4: View and frustrum data setters and getters
|
||||
|
@ -276,8 +273,9 @@ private:
|
|||
// flag forcing a recalc of derived view parameters
|
||||
bool _dirty;
|
||||
|
||||
mutable sgdVec3 _absolute_view_pos;
|
||||
mutable sgVec3 _relative_view_pos;
|
||||
SGQuatd mViewOrientation;
|
||||
SGVec3d _absolute_view_pos;
|
||||
SGVec3f _relative_view_pos;
|
||||
|
||||
double _lon_deg;
|
||||
double _lat_deg;
|
||||
|
@ -305,16 +303,12 @@ private:
|
|||
// Position offsets from FDM origin. The X axis is positive
|
||||
// out the tail, Y is out the right wing, and Z is positive up.
|
||||
// distance in meters
|
||||
double _x_offset_m;
|
||||
double _y_offset_m;
|
||||
double _z_offset_m;
|
||||
SGVec3d _offset_m;
|
||||
|
||||
// Target offsets from FDM origin (for "lookat" targets) The X
|
||||
// axis is positive out the tail, Y is out the right wing, and Z
|
||||
// is positive up. distance in meters
|
||||
double _target_x_offset_m;
|
||||
double _target_y_offset_m;
|
||||
double _target_z_offset_m;
|
||||
SGVec3d _target_offset_m;
|
||||
|
||||
|
||||
// orientation offsets from reference (_goal* are for smoothed transitions)
|
||||
|
@ -357,38 +351,24 @@ private:
|
|||
// multiplied into the aspect_ratio to get the actual vertical fov
|
||||
double _aspect_ratio_multiplier;
|
||||
|
||||
bool _reverse_view_offset;
|
||||
|
||||
// view position in opengl world coordinates (this is the
|
||||
// abs_view_pos translated to scenery.center)
|
||||
sgVec3 _view_pos;
|
||||
SGVec3f _view_pos;
|
||||
|
||||
// cartesion coordinates of current lon/lat if at sea level
|
||||
// translated to scenery.center
|
||||
sgVec3 _zero_elev;
|
||||
SGVec3f _zero_elev;
|
||||
|
||||
// surface vector heading south
|
||||
sgVec3 _surface_south;
|
||||
SGVec3f _surface_south;
|
||||
|
||||
// surface vector heading east (used to unambiguously align sky
|
||||
// with sun)
|
||||
sgVec3 _surface_east;
|
||||
SGVec3f _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;
|
||||
|
||||
// up vector for the view (usually point straight up through the
|
||||
// top of the aircraft
|
||||
sgVec3 _view_up;
|
||||
|
||||
// sg versions of our friendly matrices
|
||||
sgMat4 VIEW, UP;
|
||||
sgMat4 LOCAL, ATLOCAL, TRANS, LARC_TO_SSG;
|
||||
|
||||
// Transformation matrix for the view direction offset relative to
|
||||
// the AIRCRAFT matrix
|
||||
sgMat4 VIEW_OFFSET;
|
||||
SGVec3f _world_up;
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// private functions //
|
||||
|
@ -397,12 +377,7 @@ private:
|
|||
void recalc ();
|
||||
void recalcLookFrom();
|
||||
void recalcLookAt();
|
||||
void copyLocationData();
|
||||
void updateFromModelLocation (SGLocation * location);
|
||||
void updateAtModelLocation (SGLocation * location);
|
||||
void recalcOurOwnLocation (SGLocation * location, double lon_deg, double lat_deg, double alt_ft,
|
||||
double roll_deg, double pitch_deg, double heading_deg);
|
||||
void dampEyeData (double &roll_deg, double &pitch_deg, double &heading_deg);
|
||||
void dampEyeData(double &roll_deg, double &pitch_deg, double &heading_deg);
|
||||
|
||||
// add to _heading_offset_deg
|
||||
inline void incHeadingOffset_deg( double amt ) {
|
||||
|
@ -422,10 +397,6 @@ private:
|
|||
_roll_offset_deg += amt;
|
||||
}
|
||||
|
||||
inline void set_reverse_view_offset( bool val ) {
|
||||
_reverse_view_offset = val;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ void fgUpdateSunPos( void ) {
|
|||
// << ","<< l->sun_vec[2] << endl;
|
||||
|
||||
// calculate the sun's relative angle to local up
|
||||
sgCopyVec3( nup, v->get_world_up() );
|
||||
sgCopyVec3( nup, v->get_world_up().data() );
|
||||
sgSetVec3( nsun, l->get_sunpos().x(),
|
||||
l->get_sunpos().y(), l->get_sunpos().z() );
|
||||
sgNormalizeVec3(nup);
|
||||
|
@ -141,7 +141,9 @@ void fgUpdateSunPos( void ) {
|
|||
// earth's surface the sun is directly over, map into onto the
|
||||
// local plane representing "horizontal".
|
||||
|
||||
sgmap_vec_onto_cur_surface_plane( v->get_world_up(), v->get_view_pos(),
|
||||
SGVec3f world_up = v->get_world_up();
|
||||
SGVec3f view_pos = v->get_view_pos();
|
||||
sgmap_vec_onto_cur_surface_plane( world_up.data(), view_pos.data(),
|
||||
to_sun, surface_to_sun );
|
||||
sgNormalizeVec3(surface_to_sun);
|
||||
// cout << "(sg) Surface direction to sun is "
|
||||
|
@ -155,13 +157,13 @@ void fgUpdateSunPos( void ) {
|
|||
// v->get_surface_east(). We do this so we can sort out the
|
||||
// acos() ambiguity. I wish I could think of a more efficient
|
||||
// way. :-(
|
||||
east_dot = sgScalarProductVec3( surface_to_sun, v->get_surface_east() );
|
||||
east_dot = sgScalarProductVec3( surface_to_sun, v->get_surface_east().data() );
|
||||
// cout << " East dot product = " << east_dot << endl;
|
||||
|
||||
// calculate the angle between v->surface_to_sun and
|
||||
// v->surface_south. this is how much we have to rotate the sky
|
||||
// for it to align with the sun
|
||||
dot = sgScalarProductVec3( surface_to_sun, v->get_surface_south() );
|
||||
dot = sgScalarProductVec3( surface_to_sun, v->get_surface_south().data() );
|
||||
// cout << " Dot product = " << dot << endl;
|
||||
|
||||
if (dot > 1.0) {
|
||||
|
|
Loading…
Add table
Reference in a new issue