Hi Mathias,

this reminds me that I had implemented the attached cleanup-patch for 
SGLocation (as part of the abstract terrain API).  I currently don't have the
time to finish the API, so the patch is a bit out of context (requires some
small changes in flightgear), but if you are currently working on the
transform system you might find parts of it useful...

It does take care of a few oddities in SGLocation [e.g. getAbsolutePosition() 
required the scenery_center as parameter (but does not depend on it), while 
get_relative_pos took no argument etc.]. Dunno if these oddities really 
manifest as bugs, but IMO they made the placement/transform system quite hard
to understand and use.

cheers,

 Manuel
? SGLocation.diff
Index: location.cxx
===================================================================
RCS file: /var/cvs/SimGear-0.3/SimGear/simgear/scene/model/location.cxx,v
retrieving revision 1.6
diff -C2 -r1.6 location.cxx
*** location.cxx	19 Nov 2004 21:44:17 -0000	1.6
--- location.cxx	28 Apr 2005 15:42:43 -0000
***************
*** 94,98 ****
      dst[0][3] = SG_ZERO ;
      dst[3][3] = SG_ONE ;
- 
  }
  
--- 94,97 ----
***************
*** 104,108 ****
  // Constructor
  SGLocation::SGLocation( void ):
!     _dirty(true),
      _lon_deg(-1000),
      _lat_deg(0),
--- 103,107 ----
  // Constructor
  SGLocation::SGLocation( void ):
!     _position_dirty(true), _orientation_dirty(true),
      _lon_deg(-1000),
      _lat_deg(0),
***************
*** 111,120 ****
      _pitch_deg(0),
      _heading_deg(0),
!     _cur_elev_m(0),
!     _tile_center(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 );
--- 110,116 ----
      _pitch_deg(0),
      _heading_deg(0),
!     _cur_elev_m(0)
  {
      sgdZeroVec3(_absolute_view_pos);
      sgMakeRotMat4( UP, 0.0, 0.0, 0.0 );
      sgMakeRotMat4( TRANS, 0.0, 0.0, 0.0 );
***************
*** 127,148 ****
  
  void
- SGLocation::init ()
- {
- }
- 
- void
- SGLocation::bind ()
- {
- }
- 
- void
- SGLocation::unbind ()
- {
- }
- 
- void
  SGLocation::setPosition (double lon_deg, double lat_deg, double alt_ft)
  {
!   _dirty = true;
    _lon_deg = lon_deg;
    _lat_deg = lat_deg;
--- 123,129 ----
  
  void
  SGLocation::setPosition (double lon_deg, double lat_deg, double alt_ft)
  {
!   _position_dirty = true;
    _lon_deg = lon_deg;
    _lat_deg = lat_deg;
***************
*** 153,157 ****
  SGLocation::setOrientation (double roll_deg, double pitch_deg, double heading_deg)
  {
!   _dirty = true;
    _roll_deg = roll_deg;
    _pitch_deg = pitch_deg;
--- 134,138 ----
  SGLocation::setOrientation (double roll_deg, double pitch_deg, double heading_deg)
  {
!   _orientation_dirty = true;
    _roll_deg = roll_deg;
    _pitch_deg = pitch_deg;
***************
*** 160,256 ****
  
  double *
! SGLocation::get_absolute_view_pos( const Point3D scenery_center ) 
  {
!     if ( _dirty ) {
!         recalc( scenery_center );
!     }
      return _absolute_view_pos;
  }
  
  float *
! SGLocation::getRelativeViewPos( const Point3D scenery_center ) 
  {
!     if ( _dirty ) {
!         recalc( scenery_center );
!     }
      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 )
  {
! 
!   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,
                        _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];
! }
! 
! void
! SGLocation::update (int dt)
! {
  }
--- 141,212 ----
  
  double *
! SGLocation::get_absolute_view_pos()
  {
!     recalcAbsolutePosition();
      return _absolute_view_pos;
  }
  
  float *
! SGLocation::get_view_pos( const Point3D scenery_center ) 
  {
!     recalcAbsolutePosition();
!     for (int i = 0; i < 3; i++)
!       _relative_view_pos[i] = _absolute_view_pos[i] - (double)scenery_center[i];
      return _relative_view_pos;
  }
  
! void SGLocation::recalcOrientation() const
  {
!   if (_orientation_dirty) {
!     // Make sure UP matrix is up-to-date.
!     recalcAbsolutePosition();
! 
!     // 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 );
!     _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::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: location.hxx
===================================================================
RCS file: /var/cvs/SimGear-0.3/SimGear/simgear/scene/model/location.hxx,v
retrieving revision 1.3
diff -C2 -r1.3 location.hxx
*** location.hxx	13 May 2003 03:18:36 -0000	1.3
--- location.hxx	28 Apr 2005 15:42:44 -0000
***************
*** 42,46 ****
  
  public:
- 
      // Constructor
      SGLocation( void );
--- 42,45 ----
***************
*** 50,63 ****
  
      //////////////////////////////////////////////////////////////////////
-     // Part 1: standard FGSubsystem implementation.
-     //////////////////////////////////////////////////////////////////////
- 
-     virtual void init ();
-     virtual void bind ();
-     virtual void unbind ();
-     void update (int dt);
- 
- 
-     //////////////////////////////////////////////////////////////////////
      // Part 2: user settings.
      //////////////////////////////////////////////////////////////////////
--- 49,52 ----
***************
*** 89,129 ****
  
      // 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 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 );
      // Get surface east vector
!     virtual float *get_surface_east() {	return _surface_east; }
      // Get surface south vector
!     virtual float *get_surface_south() { 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 ) { _tile_center = tile_center; }
!     inline Point3D get_tile_center () { return _tile_center; }
  
      // Matrices...
!     virtual const sgVec4 *getTransformMatrix( const Point3D scenery_center ) {
!         if ( _dirty ) {
!             recalc( scenery_center );
!         }
! 	return TRANS;
      }
      virtual const sgVec4 *getCachedTransformMatrix() { return TRANS; }
!     virtual const sgVec4 *getUpMatrix( const Point3D scenery_center )  {
!         if ( _dirty ) {
!             recalc( scenery_center );
!         }
! 	return UP;
      }
      virtual const sgVec4 *getCachedUpMatrix() { return UP; }
--- 78,115 ----
  
      // Vectors and positions...
!     
!     //! 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()            { recalcAbsolutePosition(); return _world_up; }
!     
      // Get surface east vector
!     virtual float *get_surface_east()        { recalcAbsolutePosition(); return _surface_east; }
!     
      // Get surface south vector
!     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 ) { _tile_center = tile_center; }
!     //inline Point3D get_tile_center () { return _tile_center; }
  
      // Matrices...
!     virtual const sgVec4 *getTransformMatrix() {
!         recalcOrientation();
!         return TRANS;
      }
      virtual const sgVec4 *getCachedTransformMatrix() { return TRANS; }
!     
!     virtual const sgVec4 *getUpMatrix()  {
!         recalcAbsolutePosition();
!         return UP;
      }
      virtual const sgVec4 *getCachedUpMatrix() { return UP; }
***************
*** 137,145 ****
  
      // flag forcing a recalc of derived view parameters
!     bool _dirty;
  
      mutable sgdVec3 _absolute_view_pos;
      mutable sgVec3 _relative_view_pos;
-     mutable sgVec3 _zero_elev_view_pos;
  
      double _lon_deg;
--- 123,130 ----
  
      // flag forcing a recalc of derived view parameters
!     mutable bool _orientation_dirty, _position_dirty;
  
      mutable sgdVec3 _absolute_view_pos;
      mutable sgVec3 _relative_view_pos;
  
      double _lon_deg;
***************
*** 153,171 ****
      // elevation of ground under this location...
      double _cur_elev_m;
!     Point3D _tile_center;
  
      // surface vector heading south
!     sgVec3 _surface_south;
  
      // surface vector heading east (used to unambiguously align sky
      // with sun)
!     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;
  
      // sg versions of our friendly matrices
!     sgMat4 TRANS, UP;
  
      //////////////////////////////////////////////////////////////////
--- 138,156 ----
      // elevation of ground under this location...
      double _cur_elev_m;
!     //Point3D _tile_center;
  
      // surface vector heading south
!     mutable sgVec3 _surface_south;
  
      // surface vector heading east (used to unambiguously align sky
      // with sun)
!     mutable sgVec3 _surface_east;
  
      // world up vector (normal to the plane tangent to the earth's
!     // surface at the spot we are directly above)
!     mutable sgVec3 _world_up;
  
      // sg versions of our friendly matrices
!     mutable sgMat4 TRANS, UP;
  
      //////////////////////////////////////////////////////////////////
***************
*** 173,183 ****
      //////////////////////////////////////////////////////////////////
  
!     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; }
! 
  };
  
--- 158,164 ----
      //////////////////////////////////////////////////////////////////
  
!     void recalcRelativePosition( const Point3D scenery_center ) const;
!     void recalcOrientation() const;
!     void recalcAbsolutePosition() const;
  };
  
Index: placement.cxx
===================================================================
RCS file: /var/cvs/SimGear-0.3/SimGear/simgear/scene/model/placement.cxx,v
retrieving revision 1.4
diff -C2 -r1.4 placement.cxx
*** placement.cxx	15 May 2003 21:35:31 -0000	1.4
--- placement.cxx	28 Apr 2005 15:42:44 -0000
***************
*** 63,70 ****
    _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++) {
--- 63,70 ----
    _location->setOrientation( _roll_deg, _pitch_deg, _heading_deg );
  
!   sgCopyMat4( POS, _location->getTransformMatrix() );
  
    sgVec3 trans;
!   sgCopyVec3(trans, _location->get_view_pos(scenery_center));
  
    for(int i = 0; i < 4; i++) {
_______________________________________________
Flightgear-devel mailing list
Flightgear-devel@flightgear.org
http://mail.flightgear.org/mailman/listinfo/flightgear-devel
2f585eeea02e2c79d7b1d8c4963bae2d

Reply via email to