From f1c03ed9579de0b0f70fb237e63e0cf59f3202ce Mon Sep 17 00:00:00 2001
From: curt <curt>
Date: Thu, 11 Apr 2002 04:25:30 +0000
Subject: [PATCH] This patch includes the FGLocation class, a few fixes,
 cleanup in viewer code.

Synced to CVS 19:36 EDT 2002-04-10 (after this evenings JSMsim and Base
package updates).

Description:
Added FGLocation class which is new home for calculating matrix rotations.
Viewer can now be configured to access rotations created by the model rather
than repeating the same calculations again.

Changed model initialization for the time being so that its location data is
available for the viewer (currently required by other subsystems).  At some
point we can move this back to fg_init along with the viewer initialization.

Seperated the update from the draw function in the model code.  The viewer
code needs the same matrix data, and moving the update portion at this time
does not increase the number of matrix math iterations.

Moved the model draw so that it always appears "in front" of lights and clouds.

Reogranized viewer update routine for using the FGLocation class and
simplified some more tasks.  The routine is fairly easy to follow now, with
the steps ordered and spelled out in comments.

Viewmgr only updates the current (visible) view now, with the exception of an
old reference to "chase view" that will be corrected in forthcoming changes.
Also will be doing some work on the viewmgr outputs.

Model is now clears the z-buffer in all modes.  This will be changed with the
next viewmgr update.  The only side effect is that models always disappear
when over 5km distant from the eye point (can't really see them anyway:-)).

Other than a flag to indicate "internal" view I don't anticipate the
configuration interface for viewmgr/views will be changed a lot for now.  It
is close to done.  The next viewmgr update will however rework the outputs so
you can expect that the data that viewmgr is writing to the property tree
may change location.

This code will run with the previous version of preferences.xml, but will run
faster with the newer version.  I am attaching a preferences.xml that should
not be commited before the code.  All the changes are in the /sim/view section
and should show a simpler view configuration that references model locations.
 Note that I've added a 2nd tower view in "lookfrom" mode for illustration
purposes. You can look around using the mouse.  You may want to remove that or
comment it out.
---
 src/Model/acmodel.cxx |  16 +++--
 src/Model/acmodel.hxx |   3 +
 src/Model/model.cxx   | 141 ++++++------------------------------------
 src/Model/model.hxx   |   8 +++
 4 files changed, 41 insertions(+), 127 deletions(-)

diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx
index 32cdb460e..159969c2a 100644
--- a/src/Model/acmodel.cxx
+++ b/src/Model/acmodel.cxx
@@ -69,11 +69,10 @@ FGAircraftModel::update (int dt)
 
   if (view_number == 0 && !fgGetBool("/sim/view/internal")) {
     _aircraft->setVisible(false);
-    return;
+  } else {
+    _aircraft->setVisible(true);
   }
 
-  _aircraft->setVisible(true);
-
   _aircraft->setPosition(fgGetDouble("/position/longitude-deg"),
 			 fgGetDouble("/position/latitude-deg"),
 			 fgGetDouble("/position/altitude-ft"));
@@ -82,16 +81,21 @@ FGAircraftModel::update (int dt)
 			    fgGetDouble("/orientation/heading-deg"));
   _aircraft->update(dt);
 
+}
+
+void
+FGAircraftModel::draw ()
+{
 				// OK, now adjust the clip planes and draw
 				// FIXME: view number shouldn't be 
 				// hard-coded.
-  if (globals->get_current_view()->getType() == 0) {
+  if (_aircraft->getVisible()) {
     glClearDepth(1);
     glClear(GL_DEPTH_BUFFER_BIT);
     ssgSetNearFar(_nearplane, _farplane);
+    ssgCullAndDraw(_scene);
   }
-  ssgCullAndDraw(_scene);
+
 }
 
-
 // end of model.cxx
diff --git a/src/Model/acmodel.hxx b/src/Model/acmodel.hxx
index 6e785694f..743f162ea 100644
--- a/src/Model/acmodel.hxx
+++ b/src/Model/acmodel.hxx
@@ -33,6 +33,8 @@ public:
   virtual void bind ();
   virtual void unbind ();
   virtual void update (int dt);
+  virtual void draw ();
+  virtual FG3DModel * get3DModel() { return _aircraft; }
 
 private:
 
@@ -45,3 +47,4 @@ private:
 
 #endif // __ACMODEL_HXX
 
+
diff --git a/src/Model/model.cxx b/src/Model/model.cxx
index 5439230ac..9c1369b20 100644
--- a/src/Model/model.cxx
+++ b/src/Model/model.cxx
@@ -20,6 +20,7 @@
 #include <simgear/misc/sg_path.hxx>
 
 #include <Main/globals.hxx>
+#include <Main/location.hxx>
 #include <Scenery/scenery.hxx>
 
 #include "model.hxx"
@@ -121,123 +122,6 @@ set_translation (sgMat4 &matrix, double position_m, sgVec3 &axis)
   sgMakeTransMat4(matrix, xyz);
 }
 
-/**
- * make model transformation Matrix - based on optimizations by NHV
- */
-static void MakeTRANS( sgMat4 dst, const double Theta,
-			const double Phi, const double Psi, 
-                        const double lon, const double lat)
-{
-    SGfloat cosTheta = (SGfloat) cos(Theta);
-    SGfloat sinTheta = (SGfloat) sin(Theta);
-    SGfloat cosPhi   = (SGfloat) cos(Phi);
-    SGfloat sinPhi   = (SGfloat) sin(Phi);
-    SGfloat sinPsi   = (SGfloat) sin(Psi) ;
-    SGfloat cosPsi   = (SGfloat) cos(Psi) ;
-
-    SGfloat cosLon = SGD_ONE;
-    SGfloat sinLon = SGD_ZERO;
-    SGfloat cosLat = SGD_ONE;
-    SGfloat sinLat = SGD_ZERO;
-
-    if ( lon != SG_ZERO ) { 
-      sinLon = (SGfloat) sin( lon ) ;
-      cosLon = (SGfloat) cos( lon ) ;
-    }
-    if ( lat != SG_ZERO ) {
-      sinLat   = (SGfloat) sin( lat ) ;
-      cosLat   = (SGfloat) cos( lat ) ;
-    }
-
-
-    sgMat4 tmp;
-	
-    tmp[0][0] = cosPhi * cosTheta;
-    tmp[0][1] =	sinPhi * cosPsi + cosPhi * -sinTheta * -sinPsi;
-    tmp[0][2] =	sinPhi * sinPsi + cosPhi * -sinTheta * cosPsi;
-
-    tmp[1][0] = -sinPhi * cosTheta;
-    tmp[1][1] =	cosPhi * cosPsi + -sinPhi * -sinTheta * -sinPsi;
-    tmp[1][2] =	cosPhi * sinPsi + -sinPhi * -sinTheta * cosPsi;
-	
-    tmp[2][0] = sinTheta;
-    tmp[2][1] =	cosTheta * -sinPsi;
-    tmp[2][2] =	cosTheta * cosPsi;
-	
-    float a = cosLon * cosLat;  // world up [0]
-    float b = -sinLon;
-    float c = sinLat * cosLon;
-    dst[2][0] = a*tmp[0][0] + b*tmp[0][1] + c*tmp[0][2] ;
-    dst[1][0] = a*tmp[1][0] + b*tmp[1][1] + c*tmp[1][2] ;
-    dst[0][0] = -(a*tmp[2][0] + b*tmp[2][1] + c*tmp[2][2]) ;
-    dst[3][0] = SG_ZERO ;
-
-    a = cosLat * sinLon;  // world up [1]
-    b = cosLon;
-    c = sinLat * sinLon;
-    dst[2][1] = a*tmp[0][0] + b*tmp[0][1] + c*tmp[0][2] ;
-    dst[1][1] = a*tmp[1][0] + b*tmp[1][1] + c*tmp[1][2] ;
-    dst[0][1] = -(a*tmp[2][0] + b*tmp[2][1] + c*tmp[2][2]) ;
-    dst[3][1] = SG_ZERO ;
-
-    a = -sinLat;  // world up [2]
-    c = cosLat;
-    dst[2][2] = a*tmp[0][0] + c*tmp[0][2] ;
-    dst[1][2] = a*tmp[1][0] + c*tmp[1][2] ;
-    dst[0][2] = -(a*tmp[2][0] + c*tmp[2][2]) ;
-    dst[3][2] = SG_ZERO ;
-
-    dst[2][3] = SG_ZERO ;
-    dst[1][3] = SG_ZERO ;
-    dst[0][3] = SG_ZERO ;
-    dst[3][3] = SG_ONE ;
-
-}
-
-
-// TODO: once this is working, look at Norm's optimized version
-static void
-world_coordinate( sgCoord *obj_pos,
-		  double lat_deg, double lon_deg, double elev_ft,
-		  double roll_deg, double pitch_deg, double hdg_deg)
-{
-  // setup translation
-  double sea_level_radius_m;
-  double lat_geoc_rad;
-
-  // Convert from geodetic to geocentric
-  // coordinates.
-  sgGeodToGeoc(lat_deg * SGD_DEGREES_TO_RADIANS,
-	       elev_ft * SG_FEET_TO_METER,
-	       &sea_level_radius_m,
-	       &lat_geoc_rad);
-
-  Point3D center = scenery.get_center();
-
-  Point3D geod = Point3D(lon_deg * SG_DEGREES_TO_RADIANS,
-			 lat_geoc_rad,
-			 sea_level_radius_m);
-  geod.setz(geod.radius() + elev_ft * SG_FEET_TO_METER);
-	
-  Point3D world_pos = sgPolarToCart3d( geod );
-  Point3D offset = world_pos - center;
-	
-  sgMat4 POS;
-  sgMakeTransMat4( POS, offset.x(), offset.y(), offset.z() );
-
-  sgMat4 TRANS;
-
-  MakeTRANS( TRANS, pitch_deg * SG_DEGREES_TO_RADIANS, 
-                    roll_deg * SG_DEGREES_TO_RADIANS,
-                    -hdg_deg * SG_DEGREES_TO_RADIANS, 
-                    lon_deg * SG_DEGREES_TO_RADIANS, 
-                    -lat_deg * SG_DEGREES_TO_RADIANS );
-
-  sgPostMultMat4( TRANS, POS );
-
-  sgSetCoord( obj_pos, TRANS );
-}
-
 
 
 ////////////////////////////////////////////////////////////////////////
@@ -332,6 +216,11 @@ FG3DModel::init (const string &path)
 				// Set up the selector node
   _selector->addKid(_position);
   _selector->clrTraversalMaskBits(SSGTRAV_HOT);
+
+
+				// Set up a location class
+  _location = (FGLocation *) new FGLocation;
+
 }
 
 void
@@ -340,11 +229,19 @@ FG3DModel::update (int dt)
   for (unsigned int i = 0; i < _animations.size(); i++)
     _animations[i]->update(dt);
 
-  _selector->select(true);
-
   sgCoord obj_pos;
-  world_coordinate(&obj_pos, _lat_deg, _lon_deg, _elev_ft,
-		   _roll_deg, _pitch_deg, _heading_deg);
+
+  sgMat4 POS, TRANS;
+
+  _location->setPosition( _lon_deg, _lat_deg, _elev_ft );
+  _location->setOrientation( _roll_deg, _pitch_deg, _heading_deg );
+  sgCopyMat4(TRANS, _location->getTransformMatrix());
+  sgMakeTransMat4( POS, _location->get_view_pos() );
+
+  sgPostMultMat4( TRANS, POS );
+
+  sgSetCoord( &obj_pos, TRANS );
+
   _position->setTransform(&obj_pos);
 }
 
@@ -672,3 +569,5 @@ FG3DModel::TranslateAnimation::update (int dt)
 // end of model.cxx
 
 
+
+
diff --git a/src/Model/model.hxx b/src/Model/model.hxx
index 08aa4bafb..78417d08f 100644
--- a/src/Model/model.hxx
+++ b/src/Model/model.hxx
@@ -11,10 +11,12 @@
 #endif
 
 #include <vector>
+#include <plib/ssg.h>
 
 SG_USING_STD(vector);
 
 #include <Main/fg_props.hxx>
+#include <Main/location.hxx>
 
 // Has anyone done anything *really* stupid, like making min and max macros?
 #ifdef min
@@ -52,6 +54,8 @@ public:
 
   virtual ssgEntity * getSceneGraph () const { return _selector; }
 
+  virtual FGLocation * getFGLocation () const { return _location; }
+
 private:
 
   class Animation;
@@ -77,6 +81,8 @@ private:
   ssgSelector * _selector;
   ssgTransform * _position;
 
+				// Location
+  FGLocation * _location;
 
   
   //////////////////////////////////////////////////////////////////////
@@ -223,3 +229,5 @@ private:
 
 #endif // __MODEL_HXX
 
+
+