Mathias Frhlich:
There was a patch from Manuel Masing a few months ago which cleaned up SGLocation's way depending on input values. That means that with that patch SGLocation does no longer have calls with unneeded input arguments. I took his patch and integrated that into flightgear and made maximum use of that changes.
This commit is contained in:
@@ -93,7 +93,6 @@ static void MakeTRANS( sgMat4 dst, const double Theta,
|
||||
dst[1][3] = SG_ZERO ;
|
||||
dst[0][3] = SG_ZERO ;
|
||||
dst[3][3] = SG_ONE ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -103,19 +102,16 @@ static void MakeTRANS( sgMat4 dst, const double Theta,
|
||||
|
||||
// Constructor
|
||||
SGLocation::SGLocation( void ):
|
||||
_dirty(true),
|
||||
_position_dirty(true), _orientation_dirty(true),
|
||||
_lon_deg(-1000),
|
||||
_lat_deg(0),
|
||||
_alt_ft(0),
|
||||
_roll_deg(0),
|
||||
_pitch_deg(0),
|
||||
_heading_deg(0),
|
||||
_cur_elev_m(0),
|
||||
_tile_center(0)
|
||||
_cur_elev_m(0)
|
||||
{
|
||||
sgdZeroVec3(_absolute_view_pos);
|
||||
sgZeroVec3(_relative_view_pos);
|
||||
sgZeroVec3(_zero_elev_view_pos);
|
||||
sgMakeRotMat4( UP, 0.0, 0.0, 0.0 );
|
||||
sgMakeRotMat4( TRANS, 0.0, 0.0, 0.0 );
|
||||
}
|
||||
@@ -125,25 +121,10 @@ SGLocation::SGLocation( void ):
|
||||
SGLocation::~SGLocation( void ) {
|
||||
}
|
||||
|
||||
void
|
||||
SGLocation::init ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SGLocation::bind ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SGLocation::unbind ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SGLocation::setPosition (double lon_deg, double lat_deg, double alt_ft)
|
||||
{
|
||||
_dirty = true;
|
||||
_position_dirty = true;
|
||||
_lon_deg = lon_deg;
|
||||
_lat_deg = lat_deg;
|
||||
_alt_ft = alt_ft;
|
||||
@@ -152,105 +133,83 @@ SGLocation::setPosition (double lon_deg, double lat_deg, double alt_ft)
|
||||
void
|
||||
SGLocation::setOrientation (double roll_deg, double pitch_deg, double heading_deg)
|
||||
{
|
||||
_dirty = true;
|
||||
_orientation_dirty = true;
|
||||
_roll_deg = roll_deg;
|
||||
_pitch_deg = pitch_deg;
|
||||
_heading_deg = heading_deg;
|
||||
}
|
||||
|
||||
double *
|
||||
SGLocation::get_absolute_view_pos( const Point3D scenery_center )
|
||||
SGLocation::get_absolute_view_pos()
|
||||
{
|
||||
if ( _dirty ) {
|
||||
recalc( scenery_center );
|
||||
}
|
||||
recalcAbsolutePosition();
|
||||
return _absolute_view_pos;
|
||||
}
|
||||
|
||||
float *
|
||||
SGLocation::getRelativeViewPos( const Point3D scenery_center )
|
||||
SGLocation::get_view_pos( const Point3D& scenery_center )
|
||||
{
|
||||
if ( _dirty ) {
|
||||
recalc( scenery_center );
|
||||
}
|
||||
recalcAbsolutePosition();
|
||||
for (int i = 0; i < 3; i++)
|
||||
_relative_view_pos[i] = _absolute_view_pos[i] - scenery_center[i];
|
||||
return _relative_view_pos;
|
||||
}
|
||||
|
||||
float *
|
||||
SGLocation::getZeroElevViewPos( const Point3D scenery_center )
|
||||
{
|
||||
if ( _dirty ) {
|
||||
recalc( scenery_center );
|
||||
}
|
||||
return _zero_elev_view_pos;
|
||||
}
|
||||
|
||||
|
||||
// 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.
|
||||
void
|
||||
SGLocation::recalc( const Point3D scenery_center )
|
||||
SGLocation::recalcOrientation() const
|
||||
{
|
||||
if (_orientation_dirty) {
|
||||
// Make sure UP matrix is up-to-date.
|
||||
recalcAbsolutePosition();
|
||||
|
||||
recalcPosition( _lon_deg, _lat_deg, _alt_ft, scenery_center );
|
||||
|
||||
// Make the world up rotation matrix for eye positioin...
|
||||
sgMakeRotMat4( UP, _lon_deg, 0.0, -_lat_deg );
|
||||
|
||||
|
||||
// get the world up radial vector from planet center for output
|
||||
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.
|
||||
MakeTRANS( TRANS, _pitch_deg * SG_DEGREES_TO_RADIANS,
|
||||
// Create local matrix with current geodetic position. Converting
|
||||
// the orientation (pitch/roll/heading) to vectors.
|
||||
MakeTRANS( TRANS, _pitch_deg * SG_DEGREES_TO_RADIANS,
|
||||
_roll_deg * SG_DEGREES_TO_RADIANS,
|
||||
-_heading_deg * SG_DEGREES_TO_RADIANS,
|
||||
UP);
|
||||
|
||||
// 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".
|
||||
sgVec3 minus_z;
|
||||
sgSetVec3( minus_z, 0.0, 0.0, -1.0 );
|
||||
|
||||
sgmap_vec_onto_cur_surface_plane(_world_up, _relative_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);
|
||||
|
||||
set_clean();
|
||||
-_heading_deg * SG_DEGREES_TO_RADIANS,
|
||||
UP );
|
||||
_orientation_dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update values derived from the longitude, latitude and altitude parameters
|
||||
* of this instance. This encompasses absolute position in cartesian
|
||||
* coordinates, the local up, east and south vectors and the UP Matrix.
|
||||
*/
|
||||
void
|
||||
SGLocation::recalcPosition( double lon_deg, double lat_deg, double alt_ft,
|
||||
const Point3D scenery_center ) const
|
||||
SGLocation::recalcAbsolutePosition() const
|
||||
{
|
||||
double lat = lat_deg * SGD_DEGREES_TO_RADIANS;
|
||||
double lon = lon_deg * SGD_DEGREES_TO_RADIANS;
|
||||
double alt = alt_ft * SG_FEET_TO_METER;
|
||||
if (_position_dirty) {
|
||||
double lat = _lat_deg * SGD_DEGREES_TO_RADIANS;
|
||||
double lon = _lon_deg * SGD_DEGREES_TO_RADIANS;
|
||||
double alt = _alt_ft * SG_FEET_TO_METER;
|
||||
|
||||
sgGeodToCart(lat, lon, alt, _absolute_view_pos);
|
||||
sgGeodToCart(lat, lon, alt, _absolute_view_pos);
|
||||
|
||||
// Make the world up rotation matrix for eye positioin...
|
||||
sgMakeRotMat4( UP, _lon_deg, 0.0, -_lat_deg );
|
||||
|
||||
int i;
|
||||
double ground[3];
|
||||
sgGeodToCart(lat, lon, 0, ground);
|
||||
for(i=0; i<3; i++)
|
||||
_zero_elev_view_pos[i] = ground[i] - _tile_center[i];
|
||||
// get the world up radial vector from planet center for output
|
||||
sgSetVec3( _world_up, UP[0][0], UP[0][1], UP[0][2] );
|
||||
|
||||
// FIXME: view position should ONLY be calculated in the viewer...
|
||||
// Anything else should calculate their own positions relative to the
|
||||
// viewer's tile_center.
|
||||
for(i=0; i<3; i++)
|
||||
_relative_view_pos[i] = _absolute_view_pos[i] - scenery_center[i];
|
||||
}
|
||||
|
||||
void
|
||||
SGLocation::update (int dt)
|
||||
{
|
||||
// Calculate the surface east and south vectors using the (normalized)
|
||||
// partial derivatives of the up vector Could also be fetched and
|
||||
// normalized from the UP rotation matrix, but I doubt this would
|
||||
// be more efficient.
|
||||
float sin_lon = sin(_lon_deg * SGD_DEGREES_TO_RADIANS);
|
||||
float sin_lat = sin(_lat_deg * SGD_DEGREES_TO_RADIANS);
|
||||
float cos_lon = cos(_lon_deg * SGD_DEGREES_TO_RADIANS);
|
||||
float cos_lat = cos(_lat_deg * SGD_DEGREES_TO_RADIANS);
|
||||
|
||||
_surface_south[0] = (sin_lat*cos_lon);
|
||||
_surface_south[1] = (sin_lat*sin_lon);
|
||||
_surface_south[2] = - cos_lat;
|
||||
|
||||
_surface_east[0] = -sin_lon;
|
||||
_surface_east[1] = cos_lon;
|
||||
_surface_east[2] = 0.f;
|
||||
|
||||
_position_dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,23 +41,12 @@ class SGLocation
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
SGLocation( void );
|
||||
|
||||
// Destructor
|
||||
virtual ~SGLocation( void );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Part 1: standard FGSubsystem implementation.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual void init ();
|
||||
virtual void bind ();
|
||||
virtual void unbind ();
|
||||
void update (int dt);
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Part 2: user settings.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@@ -88,49 +77,42 @@ public:
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Vectors and positions...
|
||||
|
||||
// Get zero view_pos
|
||||
virtual float * get_view_pos() { return _relative_view_pos; }
|
||||
// Get the absolute view position in fgfs coordinates.
|
||||
virtual double * get_absolute_view_pos( const Point3D scenery_center );
|
||||
// Get zero elev
|
||||
virtual float * get_zero_elev() { return _zero_elev_view_pos; }
|
||||
|
||||
//! Get the absolute view position in fgfs coordinates.
|
||||
virtual double * get_absolute_view_pos( );
|
||||
|
||||
//! Return the position relative to the given scenery center.
|
||||
virtual float * get_view_pos( const Point3D& scenery_center );
|
||||
|
||||
// Get world up vector
|
||||
virtual float *get_world_up() { return _world_up; }
|
||||
// Get the relative (to scenery center) view position in fgfs coordinates.
|
||||
virtual float * getRelativeViewPos( const Point3D scenery_center );
|
||||
// Get the absolute zero-elevation view position in fgfs coordinates.
|
||||
virtual float * getZeroElevViewPos( const Point3D scenery_center );
|
||||
virtual float *get_world_up()
|
||||
{ recalcAbsolutePosition(); return _world_up; }
|
||||
|
||||
// Get surface east vector
|
||||
virtual float *get_surface_east() { return _surface_east; }
|
||||
virtual float *get_surface_east()
|
||||
{ recalcAbsolutePosition(); return _surface_east; }
|
||||
|
||||
// Get surface south vector
|
||||
virtual float *get_surface_south() { return _surface_south; }
|
||||
virtual float *get_surface_south()
|
||||
{ recalcAbsolutePosition(); return _surface_south; }
|
||||
|
||||
// Elevation of ground under location (based on scenery output)...
|
||||
void set_cur_elev_m ( double elev ) { _cur_elev_m = elev; }
|
||||
inline double get_cur_elev_m () { return _cur_elev_m; }
|
||||
// Interface to current buckets for use with tilemgr...
|
||||
void set_tile_center ( Point3D tile_center ) { set_dirty(); _tile_center = tile_center; }
|
||||
inline Point3D get_tile_center () { return _tile_center; }
|
||||
|
||||
void set_cur_elev_m ( double elev ) { _cur_elev_m = elev; }
|
||||
inline double get_cur_elev_m () { return _cur_elev_m; }
|
||||
|
||||
// Matrices...
|
||||
virtual const sgVec4 *getTransformMatrix( const Point3D scenery_center ) {
|
||||
if ( _dirty || scenery_center != _scenery_center ) {
|
||||
_scenery_center = scenery_center;
|
||||
recalc( scenery_center );
|
||||
}
|
||||
return TRANS;
|
||||
virtual const sgVec4 *getTransformMatrix() {
|
||||
recalcOrientation();
|
||||
return TRANS;
|
||||
}
|
||||
virtual const sgVec4 *getCachedTransformMatrix() { return TRANS; }
|
||||
virtual const sgVec4 *getUpMatrix( const Point3D scenery_center ) {
|
||||
if ( _dirty || scenery_center != _scenery_center ) {
|
||||
_scenery_center = scenery_center;
|
||||
recalc( scenery_center );
|
||||
}
|
||||
return UP;
|
||||
|
||||
virtual const sgVec4 *getUpMatrix(const Point3D& scenery_center) {
|
||||
recalcAbsolutePosition();
|
||||
return UP;
|
||||
}
|
||||
virtual const sgVec4 *getCachedUpMatrix() { return UP; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
@@ -138,11 +120,10 @@ private:
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// flag forcing a recalc of derived view parameters
|
||||
bool _dirty;
|
||||
mutable bool _orientation_dirty, _position_dirty;
|
||||
|
||||
mutable sgdVec3 _absolute_view_pos;
|
||||
mutable sgVec3 _relative_view_pos;
|
||||
mutable sgVec3 _zero_elev_view_pos;
|
||||
|
||||
double _lon_deg;
|
||||
double _lat_deg;
|
||||
@@ -154,34 +135,27 @@ private:
|
||||
|
||||
// elevation of ground under this location...
|
||||
double _cur_elev_m;
|
||||
Point3D _tile_center;
|
||||
Point3D _scenery_center;
|
||||
|
||||
// surface vector heading south
|
||||
sgVec3 _surface_south;
|
||||
mutable sgVec3 _surface_south;
|
||||
|
||||
// surface vector heading east (used to unambiguously align sky
|
||||
// with sun)
|
||||
sgVec3 _surface_east;
|
||||
mutable 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;
|
||||
// surface at the spot we are directly above)
|
||||
mutable sgVec3 _world_up;
|
||||
|
||||
// sg versions of our friendly matrices
|
||||
sgMat4 TRANS, UP;
|
||||
mutable sgMat4 TRANS, UP;
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// private functions //
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
void recalc( const Point3D scenery_center );
|
||||
void recalcPosition( double lon_deg, double lat_deg, double alt_ft,
|
||||
const Point3D scenery_center ) const;
|
||||
|
||||
inline void set_dirty() { _dirty = true; }
|
||||
inline void set_clean() { _dirty = false; }
|
||||
|
||||
void recalcOrientation() const;
|
||||
void recalcAbsolutePosition() const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -54,28 +54,14 @@ SGModelPlacement::init( ssgBranch * model )
|
||||
}
|
||||
|
||||
void
|
||||
SGModelPlacement::update( const Point3D scenery_center )
|
||||
SGModelPlacement::update()
|
||||
{
|
||||
_location->setPosition( _lon_deg, _lat_deg, _elev_ft );
|
||||
_location->setOrientation( _roll_deg, _pitch_deg, _heading_deg );
|
||||
|
||||
sgCopyMat4( POS, _location->getTransformMatrix(scenery_center) );
|
||||
|
||||
sgVec3 trans;
|
||||
sgCopyVec3(trans, _location->get_view_pos());
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
float tmp = POS[i][3];
|
||||
for( int j=0; j<3; j++ ) {
|
||||
POS[i][j] += (tmp * trans[j]);
|
||||
}
|
||||
}
|
||||
// _position->setTransform(POS);
|
||||
_position->setTransform(_location->get_absolute_view_pos(scenery_center), POS);
|
||||
sgdVec3 center;
|
||||
sgdSetVec3(center,
|
||||
scenery_center.x(), scenery_center.y(), scenery_center.z());
|
||||
_position->setSceneryCenter(center);
|
||||
sgMat4 rotation;
|
||||
sgCopyMat4( rotation, _location->getTransformMatrix() );
|
||||
_position->setTransform(_location->get_absolute_view_pos(), rotation);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -46,12 +46,9 @@ public:
|
||||
SGModelPlacement ();
|
||||
virtual ~SGModelPlacement ();
|
||||
|
||||
virtual void SGModelPlacement::init( ssgBranch * model );
|
||||
/* virtual void init( const string &fg_root,
|
||||
const string &path,
|
||||
SGPropertyNode *prop_root,
|
||||
double sim_time_sec, int dummy ); */
|
||||
virtual void update( const Point3D scenery_center );
|
||||
virtual void SGModelPlacement::init( ssgBranch * model );
|
||||
|
||||
virtual void update();
|
||||
|
||||
virtual ssgEntity * getSceneGraph () { return (ssgEntity *)_selector; }
|
||||
|
||||
@@ -79,10 +76,6 @@ public:
|
||||
virtual void setOrientation (double roll_deg, double pitch_deg,
|
||||
double heading_deg);
|
||||
|
||||
// Addition by Diarmuid Tyson for Multiplayer Support
|
||||
// Allows multiplayer to get players position transform
|
||||
virtual const sgVec4 *get_POS() { return POS; }
|
||||
|
||||
ssgPlacementTransform * getTransform(void)
|
||||
{ return _position; }
|
||||
|
||||
@@ -99,18 +92,10 @@ private:
|
||||
double _heading_deg;
|
||||
|
||||
ssgSelector * _selector;
|
||||
// ssgTransform * _position;
|
||||
ssgPlacementTransform * _position;
|
||||
|
||||
// Location
|
||||
SGLocation * _location;
|
||||
|
||||
|
||||
// Addition by Diarmuid Tyson for Multiplayer Support
|
||||
// Moved from update method
|
||||
// POS for transformation Matrix
|
||||
sgMat4 POS;
|
||||
|
||||
};
|
||||
|
||||
#endif // _SG_PLACEMENT_HXX
|
||||
|
||||
Reference in New Issue
Block a user