From 00ab198c9f06e61d3c64ea02d06e9ed9bfa9b13b Mon Sep 17 00:00:00 2001 From: ehofman Date: Mon, 5 Sep 2005 13:23:55 +0000 Subject: [PATCH] =?utf8?q?Mathias=20Fr=F6hlich:?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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. --- simgear/scene/model/location.cxx | 159 +++++++++++------------------- simgear/scene/model/location.hxx | 94 +++++++----------- simgear/scene/model/placement.cxx | 22 +---- simgear/scene/model/placement.hxx | 21 +--- 4 files changed, 100 insertions(+), 196 deletions(-) diff --git a/simgear/scene/model/location.cxx b/simgear/scene/model/location.cxx index e7f2022c..274c99ce 100644 --- a/simgear/scene/model/location.cxx +++ b/simgear/scene/model/location.cxx @@ -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(); -} - -void -SGLocation::recalcPosition( double lon_deg, double lat_deg, double alt_ft, - const Point3D scenery_center ) 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; - - sgGeodToCart(lat, lon, alt, _absolute_view_pos); - - 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]; - - // 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]; + -_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::update (int dt) +SGLocation::recalcAbsolutePosition() const { + 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); + + // 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] ); + + // 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; + } } diff --git a/simgear/scene/model/location.hxx b/simgear/scene/model/location.hxx index f1da39ca..9abcda3f 100644 --- a/simgear/scene/model/location.hxx +++ b/simgear/scene/model/location.hxx @@ -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; }; diff --git a/simgear/scene/model/placement.cxx b/simgear/scene/model/placement.cxx index 38a622ad..f5c483fc 100644 --- a/simgear/scene/model/placement.cxx +++ b/simgear/scene/model/placement.cxx @@ -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 diff --git a/simgear/scene/model/placement.hxx b/simgear/scene/model/placement.hxx index 99919a41..8130c490 100644 --- a/simgear/scene/model/placement.hxx +++ b/simgear/scene/model/placement.hxx @@ -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 -- 2.39.5