]> git.mxchange.org Git - simgear.git/commitdiff
Mathias Fröhlich:
authorehofman <ehofman>
Mon, 5 Sep 2005 13:23:55 +0000 (13:23 +0000)
committerehofman <ehofman>
Mon, 5 Sep 2005 13:23:55 +0000 (13:23 +0000)
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
simgear/scene/model/location.hxx
simgear/scene/model/placement.cxx
simgear/scene/model/placement.hxx

index e7f2022cdaddd0190369717fd9509f6ddd8ac760..274c99ce4a18929fcc7c63f6f1401aeb0e6f6ac1 100644 (file)
@@ -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;
+  }
 }
index f1da39caa763ee07c63851818ee540f298685b2d..9abcda3f8c491ad81365dadec67bc22db1da8893 100644 (file)
@@ -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;
 };
 
 
index 38a622adfa5902ac32546c98ee446b4b024261ea..f5c483fc6d583c815dec812c6190e2f1856930aa 100644 (file)
@@ -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
index 99919a413c43aa1badd754947be29edda72c6c2f..8130c4905f6a6ba04f489b5715a573f5eaf38e06 100644 (file)
@@ -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