#include <simgear/debug/logstream.hxx>
#include <simgear/constants.h>
-#include <simgear/math/point3d.hxx>
#include <simgear/math/polar3d.hxx>
#include <simgear/math/sg_geodesy.hxx>
-#include <simgear/scene/model/location.hxx>
#include <simgear/scene/model/placement.hxx>
#include <simgear/math/vector.hxx>
#include "viewer.hxx"
+#include "CameraGroup.hxx"
+
+using namespace flightgear;
\f
////////////////////////////////////////////////////////////////////////
// Implementation of FGViewer.
_damp_pitch(0),
_damp_heading(0),
_scaling_type(FG_SCALING_MAX),
- _location(0),
- _target_location(0)
+ _cameraGroup(CameraGroup::getDefault())
{
_absolute_view_pos = SGVec3d(0, 0, 0);
_type = Type;
void
FGViewer::init ()
{
- if ( _from_model )
- _location = (SGLocation *) globals->get_aircraft_model()->get3DModel()->getSGLocation();
- else
- _location = new SGLocation;
-
- if ( _type == FG_LOOKAT ) {
- if ( _at_model )
- _target_location = (SGLocation *) globals->get_aircraft_model()->get3DModel()->getSGLocation();
- else
- _target_location = (SGLocation *) new SGLocation;
- }
}
void
_heading_offset_deg = heading_offset_deg;
}
-double *
-FGViewer::get_absolute_view_pos ()
-{
- if (_dirty)
- recalc();
- return _absolute_view_pos.data();
-}
-
// recalc() is done every time one of the setters is called (making the
// cached data "dirty") on the next "get". It calculates all the outputs
// for viewer.
recalcLookAt();
}
- SGVec3d center = globals->get_scenery()->get_center();
- _view_pos = toVec3f(_absolute_view_pos - center);
-
- SGGeod geodEyePoint = SGGeod::fromCart(_absolute_view_pos);
- geodEyePoint.setElevationM(0);
- _zero_elev = toVec3f(SGVec3d::fromGeod(geodEyePoint) - center);
-
- 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();
- _lat_deg = _location->getLatitude_deg();
- _alt_ft = _location->getAltitudeASL_ft();
- _roll_deg = _location->getRoll_deg();
- _pitch_deg = _location->getPitch_deg();
- _heading_deg = _location->getHeading_deg();
-
- // Update viewer's postion data for the target (at object) location
- if (_type == FG_LOOKAT) {
- _target_lon_deg = _target_location->getLongitude_deg();
- _target_lat_deg = _target_location->getLatitude_deg();
- _target_alt_ft = _target_location->getAltitudeASL_ft();
- _target_roll_deg = _target_location->getRoll_deg();
- _target_pitch_deg = _target_location->getPitch_deg();
- _target_heading_deg = _target_location->getHeading_deg();
- }
-
set_clean();
}
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, lon, alt, head, pitch, roll;
+ if ( _from_model ) {
+ SGModelPlacement* placement = globals->get_aircraft_model()->get3DModel();
+ lat = placement->getLatitudeDeg();
+ lon = placement->getLongitudeDeg();
+ alt = placement->getElevationFt();
+
+ head = placement->getHeadingDeg();
+ pitch = placement->getPitchDeg();
+ roll = placement->getRollDeg();
+ } else {
+ lat = _lat_deg;
+ lon = _lon_deg;
+ alt = _alt_ft;
+ head = _heading_deg;
+ pitch = _pitch_deg;
+ roll = _roll_deg;
}
- 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 horizontal local OpenGL frame
+ SGQuatd hlOr = SGQuatd::viewHL(geodPos);
+
// the rotation from the horizontal local frame to the basic view orientation
SGQuatd hlToBody = SGQuatd::fromYawPitchRollDeg(head, pitch, roll);
+ hlToBody = SGQuatd::simToView(hlToBody);
+
// 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 viewOffsetOr = SGQuatd::simToView(
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());
+ _roll_offset_deg));
// 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);
+ _absolute_view_pos = position + ec2body.backTransform(_offset_m);
mViewOrientation = ec2body*viewOffsetOr;
}
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();
+ SGModelPlacement* placement = globals->get_aircraft_model()->get3DModel();
+ double lat = placement->getLatitudeDeg();
+ double lon = placement->getLongitudeDeg();
+ double alt = placement->getElevationFt();
+ geodTargetPos = SGGeod::fromDegFt(lon, lat, alt);
+
+ double head = placement->getHeadingDeg();
+ double pitch = placement->getPitchDeg();
+ double roll = placement->getRollDeg();
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,
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();
+ SGModelPlacement* placement = globals->get_aircraft_model()->get3DModel();
+ double lat = placement->getLatitudeDeg();
+ double lon = placement->getLongitudeDeg();
+ double alt = placement->getElevationFt();
+ geodEyePos = SGGeod::fromDegFt(lon, lat, alt);
+
+ double head = placement->getHeadingDeg();
+ double pitch = placement->getPitchDeg();
+ double roll = placement->getRollDeg();
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);
_roll_offset_deg);
// Offsets to the eye position
- SGVec3d eyeOff(-_offset_m.z(), _offset_m.y(), -_offset_m.x());
+ SGVec3d eyeOff(-_offset_m.z(), _offset_m.x(), -_offset_m.y());
SGQuatd ec2eye = geodEyeHlOr*geodEyeOr;
SGVec3d eyeCart = SGVec3d::fromGeod(geodEyePos);
eyeCart += (ec2eye*eyeOffsetOr).backTransform(eyeOff);
// the view direction
SGVec3d dir = normalize(atCart - eyeCart);
// the up directon
- SGVec3d up = ec2eye.backTransform(SGVec3d(0, 0, 1));
+ 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);
+ mViewOrientation = SGQuatd::fromRotateTo(-dir, 2, up, 1);
}
void
-FGViewer::dampEyeData (double &roll_deg, double &pitch_deg, double &heading_deg)
+FGViewer::dampEyeData(double &roll_deg, double &pitch_deg, double &heading_deg)
{
const double interval = 0.01;
}
}
}
-
+ recalc();
+ _cameraGroup->update(_absolute_view_pos.osg(), mViewOrientation.osg());
+ _cameraGroup->setCameraParameters(get_v_fov(), get_aspect_ratio());
}