]> git.mxchange.org Git - flightgear.git/commitdiff
Jim Wilson:
authorcurt <curt>
Thu, 18 Apr 2002 16:51:47 +0000 (16:51 +0000)
committercurt <curt>
Thu, 18 Apr 2002 16:51:47 +0000 (16:51 +0000)
These are the updates for the View manager properties.  Removed the last of
items (within the viewer/viewmgr) hard coded to view number.  Added support
for per view configuration of ground level nearplane value.  Tower views look
very nice with little or no z-buffer problem in the models.  Pilot offset
dialog can be used to move eye in all views.

src/GUI/gui.cxx
src/GUI/sgVec3Slider.cxx
src/GUI/sgVec3Slider.hxx
src/Main/main.cxx
src/Main/options.cxx
src/Main/viewer.cxx
src/Main/viewer.hxx
src/Main/viewmgr.cxx
src/Main/viewmgr.hxx

index 019df4bfca5bb4ce120bac6d6c0bdc9c0b3f903b..5d9f2ca0002ecb28af10cc0dd2021f6ff3064405 100644 (file)
@@ -690,10 +690,10 @@ static GlBitmap *b1 = NULL;
 extern FGInterface cur_view_fdm;
 GLubyte *hiResScreenCapture( int multiplier )
 {
-    float oldfov = fgGetDouble("/sim/field-of-view");
+    float oldfov = fgGetDouble("/sim/current-view/field-of-view");
     float fov = oldfov / multiplier;
     FGViewer *v = globals->get_current_view();
-    fgSetDouble("/sim/field-of-view", fov);
+    fgSetDouble("/sim/current-view/field-of-view", fov);
     fgInitVisuals();
     int cur_width = fgGetInt("/sim/startup/xsize");
     int cur_height = fgGetInt("/sim/startup/ysize");
@@ -712,7 +712,7 @@ GLubyte *hiResScreenCapture( int multiplier )
            b1->copyBitmap( &b2, cur_width*x, cur_height*y );
        }
     }
-    fgSetDouble("/sim/field-of-view", oldfov);
+    fgSetDouble("/sim/current-view/field-of-view", oldfov);
     return b1->getBitmap();
 }
 #endif
@@ -1064,4 +1064,3 @@ void guiInit()
         guiToggleMenu(); // Menu off by default
     }
 }
-
index 3ef12ba16961a3734ad57012999fcee33dc84c3b..4c1b469e751a0e1311f1dba8ca1e6d6f29e20084 100644 (file)
@@ -35,9 +35,9 @@ public:
                                  float max = 100.0f, float min = 0.0f);
 
        ~FloatSlider () {;}
-               
-       static void adj( puObject *);
 
+       static void adj( puObject *);
+               
        void updateText() {
                sprintf( _text, "%05.2f", MyValue );
        }
@@ -52,6 +52,9 @@ public:
         // adjust the TmpValue back to 0 to 1 range of pui widget
         void   setTmp() { TmpValue += 0.0f; }
 
+        void incTmp() { TmpValue += 0.0001f; setTmp(); }
+        void decTmp() { TmpValue -= 0.0001f; setTmp(); }
+
        // adjust actual "setting" value back to fraction for pui widget
        void init( float f ) {
                 if (f > maxValue) f = maxValue;
@@ -69,7 +72,7 @@ public:
 
 void FloatSlider::adj( puObject *hs )
 {
-       FloatSlider *slider = (FloatSlider *)hs->getUserData();
+       FloatSlider *slider = (FloatSlider *)hs;
        slider->getValue ( slider->getTmp() );
        slider->setTmp();
        slider->set();
@@ -79,17 +82,15 @@ void FloatSlider::adj( puObject *hs )
 FloatSlider::FloatSlider ( int x, int y, int sz, float f, const char *title,
                                                    float max, float min ) :  puSlider( x, y, sz, FALSE )
 {
-       setUserData( this );
        maxValue = max;
         minValue = min;
        origValue = f;
        init(f);
        setDelta    ( 0.01 );
        setCBMode   ( PUSLIDER_DELTA ) ;
-       setCallback ( adj ) ;
        strcpy      ( _title, title);
        setLabel    ( _title );
-       setLabelPlace ( PUPLACE_LEFT  );
+       setLabelPlace ( PUPLACE_LEFT );
        setLegend(_text);
        // setLegendPlace( PUPLACE_RIGHT );
 }
@@ -131,6 +132,9 @@ public:
 
         // adjust the TmpValue back to 0 to 1 range of pui widget
        void   setTmp() { TmpValue += 0.5f; }
+        
+        void incTmp() { TmpValue += 0.0001f; setTmp(); }
+        void decTmp() { TmpValue -= 0.0001f; setTmp(); }
 
        // adjust actual "setting" value back to fraction for pui widget
        // double the range from -max <-> max
@@ -150,7 +154,7 @@ public:
 
 void FloatDial::adj( puObject *hs )
 {
-       FloatDial *dial = (FloatDial *)hs->getUserData();
+       FloatDial *dial = (FloatDial *)hs;
        dial->getValue ( dial->getTmp() );
        dial->setTmp();
        dial->set();
@@ -160,14 +164,12 @@ void FloatDial::adj( puObject *hs )
 FloatDial::FloatDial ( int x, int y, int sz, float f, const char *title,
                                                    float max, float min ) :  puDial( x, y, sz )
 {
-       setUserData( this );
        maxValue = max;
         minValue = min;
        origValue = f;
        init(f);
        setDelta    ( 0.01 );
        setCBMode   ( PUSLIDER_DELTA ) ;
-       setCallback ( adj ) ;
        strcpy      ( _title, title);
        setLabel    ( _title );
        setLabelPlace ( PUPLACE_LEFT  );
@@ -180,6 +182,10 @@ FloatDial::FloatDial ( int x, int y, int sz, float f, const char *title,
 
 class sgVec3Slider : public puDialogBox
 {
+        static void handle_arrow(puObject *p_obj);
+       static void heading_adj(puObject *p_obj);
+       static void pitch_adj(puObject *p_obj);
+       static void radius_adj(puObject *p_obj);
        static void goAway(puObject *p_obj);
        static void reset(puObject *p_obj);
        static void cancel(puObject *p_obj);
@@ -193,6 +199,8 @@ protected:
        puOneShot *OkButton;
        puOneShot *ResetButton;
        puOneShot *CancelButton;
+        puArrowButton *right_arrow;
+        puArrowButton *left_arrow;
        sgVec3 Vec, SaveVec;
        
 public:
@@ -201,10 +209,11 @@ public:
                                   const char *title = "Vector Adjuster",
                                   const char *Xtitle = "Heading",
                                   const char *Ytitle = "Pitch",
-                                  const char *Ztitle = "Radius" );
+                                  const char *Ztitle = "Radius   " );
 
        ~sgVec3Slider () {;}
 
+
        // calc the property Vec with the actual point on sphere
        void setVec()
        {
@@ -238,16 +247,19 @@ public:
 };
 
 // class constructor
-sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 vec, const char *title,
+sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 cart, const char *title,
                              const char *Xtitle,
                              const char *Ytitle,
                              const char *Ztitle ): puDialogBox ( x, y )
 {
        puFont LegendFont, LabelFont;
        puGetDefaultFonts ( &LegendFont, &LabelFont );
-
        int fudge = 20;
 
+        HeadingPitchRadiusFromVec3( Vec, cart);
+        sgVec3 vec;
+        sgSetVec3(vec, Vec[0], Vec[1], Vec[2]);
+
        int labelW = LabelFont.getStringWidth(Xtitle);
        labelW = SG_MAX2( labelW, LabelFont.getStringWidth(Ytitle));
        labelW = SG_MAX2( labelW, LabelFont.getStringWidth(Ztitle));
@@ -284,12 +296,26 @@ sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 vec, const char *title,
         /* heading */
        HS0 = new FloatDial (  dialer_x, dialer_y, dialer_size, vec[0], Xtitle, 180.0f, -180.0f );
         dialer_x = dialer_x + 170;
+        HS0->setUserData (this);
+       HS0->setCallback ( heading_adj ) ;
 
         /* pitch */
        HS1 = new FloatDial (  dialer_x, dialer_y, dialer_size, vec[1], Ytitle, 89.99f, -89.99f );
+        HS1->setUserData (this);
+       HS1->setCallback ( pitch_adj ) ;
 
         /* radius */
-       HS2 = new FloatSlider (  slider_x, slider_y, slider_width, vec[2], Ztitle, 100.0f, 0.0f );
+       HS2 = new FloatSlider (  slider_x+20, slider_y, slider_width-40, vec[2], Ztitle, 100.0f, 0.0f );
+        HS2->setUserData (this);
+       HS2->setCallback ( radius_adj );
+
+        right_arrow = new puArrowButton ( slider_x + slider_width - 20, slider_y + 1, slider_x + slider_width, slider_y+21, PUARROW_RIGHT ) ;
+        right_arrow->setUserData ( HS2 ) ;
+        right_arrow->setCallback ( handle_arrow ) ;
+
+        left_arrow = new puArrowButton ( slider_x, slider_y + 1, slider_x+20, slider_y+21, PUARROW_LEFT ) ;
+        left_arrow->setUserData ( HS2 ) ;
+        left_arrow->setCallback ( handle_arrow ) ;
 
        TitleText = new puText( 130, DialogHeight - 40);
         TitleText->setLabel("Pilot Offset");
@@ -305,14 +331,49 @@ sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 vec, const char *title,
        CancelButton-> setLegend ( gui_msg_CANCEL );
        CancelButton-> setCallback ( cancel );
 
-       ResetButton = new puOneShot ( 220+fudge, 20, 280+fudge, 50 );
-       ResetButton-> setUserData( this );
-       ResetButton-> setLegend ( gui_msg_RESET );
-       ResetButton-> setCallback ( reset );
+// renabling this button requires binding in the sim/view[?]/config/?-offset-m values
+//     ResetButton = new puOneShot ( 220+fudge, 20, 280+fudge, 50 );
+//     ResetButton-> setUserData( this );
+//     ResetButton-> setLegend ( gui_msg_RESET );
+//     ResetButton-> setCallback ( reset );
 
        FG_FINALIZE_PUI_DIALOG( this );
 }
 
+void sgVec3Slider::handle_arrow(puObject *arrow)
+{
+  FloatSlider *slider = (FloatSlider *) arrow->getUserData();
+  if (((puArrowButton *)arrow)->getArrowType() == PUARROW_RIGHT)
+    slider->incTmp();
+  else
+    slider->decTmp();
+  slider->set();
+  slider->init( slider->get() );
+  sgVec3Slider *me = (sgVec3Slider *)slider->getUserData();
+  me->setVec();
+};
+
+void sgVec3Slider::heading_adj(puObject *p_obj)
+{
+  sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
+  me->HS0->adj((puObject *)me ->HS0 );
+  me->setVec();
+};
+
+void sgVec3Slider::pitch_adj(puObject *p_obj)
+{
+  sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
+  me->HS1->adj((puObject *)me ->HS1 );
+  me->setVec();
+};
+
+void sgVec3Slider::radius_adj(puObject *p_obj)
+{
+  sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
+  me ->HS2-> adj((puObject *)me ->HS2 );
+  me->setVec();
+};
+
 void sgVec3Slider::goAway(puObject *p_obj)
 {
        sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
@@ -343,6 +404,23 @@ void sgVec3Slider::cancel(puObject *p_obj)
 void sgVec3Slider::adjust(puObject *p_obj)
 {
        sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
+        heading_adj( me );
+        pitch_adj( me );
+        radius_adj( me );
+
+       sgVec3 cart;
+        sgSetVec3(cart,
+               fgGetFloat("/sim/current-view/x-offset-m"),
+               fgGetFloat("/sim/current-view/y-offset-m"),
+               fgGetFloat("/sim/current-view/z-offset-m")
+        );
+
+        HeadingPitchRadiusFromVec3( me->Vec, cart);
+
+        me -> getHS0() -> init(me->Vec[0]);
+        me -> getHS1() -> init(me->Vec[1]);
+        me -> getHS2() -> init(me->Vec[2]);
+
        me -> getHS0() -> adj((puObject *)me -> getHS0());
        me -> getHS1() -> adj((puObject *)me -> getHS1());
        me -> getHS2() -> adj((puObject *)me -> getHS2());
@@ -360,30 +438,25 @@ void sgVec3SliderAdjust( puObject *p_obj )
 static puObject *PO_vec = 0;
 
 void PilotOffsetInit() {
-       sgVec3 v;
-        sgSetVec3(v,
-               fgGetFloat("/sim/view[1]/default/pilot-offset/heading-deg"),
-               fgGetFloat("/sim/view[1]/default/pilot-offset/pitch-deg"),
-               fgGetFloat("/sim/view[1]/default/pilot-offset/radius-m")
+       sgVec3 cart;
+        sgSetVec3(cart,
+               fgGetFloat("/sim/current-view/x-offset-m"),
+               fgGetFloat("/sim/current-view/y-offset-m"),
+               fgGetFloat("/sim/current-view/z-offset-m")
         );
-
-       PilotOffsetInit(v);
+       PilotOffsetInit(cart);
 }
 
-void PilotOffsetInit( sgVec3 vec )
+void PilotOffsetInit( sgVec3 cart )
 {
        // Only one of these things for now
        if( PO_vec == 0 ) {
-                /* make change so this gets done once for each vector */
-                fgSetFloat("/sim/view[1]/current/pilot-offset/heading-deg",fgGetFloat("/sim/view[1]/default/pilot-offset/heading-deg"));
-                fgSetFloat("/sim/view[1]/current/pilot-offset/pitch-deg",fgGetFloat("/sim/view[1]/default/pilot-offset/pitch-deg"));
-                fgSetFloat("/sim/view[1]/current/pilot-offset/radius-m",fgGetFloat("/sim/view[1]/default/pilot-offset/radius-m"));
-               sgVec3Slider *PO = new sgVec3Slider ( 200, 200, vec, "Pilot Offset" );
+               sgVec3Slider *PO = new sgVec3Slider ( 200, 200, cart, "Pilot Offset" );
                PO_vec = PO;
                // Bindings for Pilot Offset
-                fgTie("/sim/view[1]/current/pilot-offset/heading-deg", getPilotOffsetHeadingDeg, setPilotOffsetHeadingDeg);
-                fgTie("/sim/view[1]/current/pilot-offset/pitch-deg", getPilotOffsetPitchDeg, setPilotOffsetPitchDeg);
-                fgTie("/sim/view[1]/current/pilot-offset/radius-m", getPilotOffsetRadiusM, setPilotOffsetRadiusM);
+                fgTie("/sim/current-view/x-offset-m", getPilotXOffset, setPilotXOffset);
+                fgTie("/sim/current-view/y-offset-m", getPilotYOffset, setPilotYOffset);
+                fgTie("/sim/current-view/z-offset-m", getPilotZOffset, setPilotZOffset);
        }
 }
 
@@ -393,8 +466,8 @@ void PilotOffsetAdjust( puObject * )
                PilotOffsetInit();
        }
        sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
-       me -> stashVec();
        me -> adjust( me );
+       me -> stashVec();
        FG_PUSH_PUI_DIALOG( me );
 }
 
@@ -416,9 +489,11 @@ float PilotOffsetGetSetting(int opt)
                PilotOffsetInit();
        }
        sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
-        if( opt == 0 ) setting = me -> getHS0() -> get();
-        if( opt == 1 ) setting = me -> getHS1() -> get();
-        if( opt == 2 ) setting = me->  getHS2() -> get();
+        sgVec3 vec;
+        sgCopyVec3(vec, (float *) me->getVec());
+        if( opt == 0 ) setting = vec[0];
+        if( opt == 1 ) setting = vec[1];
+        if( opt == 2 ) setting = vec[2];
        return( setting );
 }
 
@@ -429,9 +504,18 @@ void PilotOffsetSet(int opt, float setting)
                PilotOffsetInit();
        }
        sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
-        if( opt == 0 ) me -> getHS0() -> init( setting );
-        if( opt == 1 ) me -> getHS1() -> init( setting );
-        if( opt == 2 ) me->  getHS2() -> init( setting );
+
+        sgVec3 HPR;
+        sgVec3 vec;
+        sgCopyVec3(vec, (float *) me->getVec());
+        if( opt == 0 ) vec[0] = setting;
+        if( opt == 1 ) vec[1] = setting;
+        if( opt == 2 ) vec[2] = setting;
+        HeadingPitchRadiusFromVec3 ( HPR, vec );
+        me -> getHS0() -> init( HPR[0] );
+        me -> getHS1() -> init( HPR[1] );
+        me -> getHS2() -> init( HPR[2] );
+        me -> stashVec();
 }
 
 
@@ -440,7 +524,7 @@ void PilotOffsetSet(int opt, float setting)
 // input Pitch   == latitude of point on sphere
 // input Radius  == radius of sphere
 
-#define MIN_VIEW_OFFSET 5.0
+#define MIN_VIEW_OFFSET 0.001
 void Vec3FromHeadingPitchRadius ( sgVec3 vec3, float heading, float pitch,
 float radius )
 {
@@ -475,3 +559,44 @@ float radius )
   vec3[1] = (SGfloat)( sh * cp ) * radius ; // Y
   vec3[0] = (SGfloat)(  sp ) * radius ; // Z
 }
+
+// Convert to speherical coordinates for the dials
+
+void HeadingPitchRadiusFromVec3 ( sgVec3 hpr, sgVec3 vec3 )
+{
+  double x = vec3[0];
+  double y = vec3[1];
+  double z = vec3[2];
+  double Zx;
+  double Pr;
+
+  if (z == 0.0f) {
+    hpr[0] = 0;
+    hpr[1] = 0;
+    hpr[2] = 0;
+  } else {
+    if (fabs(y) < 0.001f)
+      y == 0.001f;
+
+    Zx = sqrt(y*y + z*z);
+
+    hpr[2] = sqrt(x*x + y*y + z*z);
+
+    Pr = Zx / hpr[2];
+    if (Pr > 1.0f)
+      hpr[1] = 0.0f;
+    else 
+      hpr[1] = acos(Pr) * SGD_RADIANS_TO_DEGREES;
+    if (x < 0.0f) 
+      hpr[1] *= -SGD_ONE;
+
+    if (z < 0.0f) {
+      hpr[0] = (SGD_PI - asin(y/Zx)) * SGD_RADIANS_TO_DEGREES;
+    } else {
+      hpr[0] = asin(y/Zx) * SGD_RADIANS_TO_DEGREES;
+      if (hpr[0] > 180) {
+        hpr[0] = 180 - hpr[0];
+      }
+    }
+  }
+}
index 448b830d1d7eb6d7d6375c56e9c45bfb9b606320..8772dc6ccd312d537b57d118559e4680c82b3c77 100644 (file)
@@ -18,6 +18,7 @@ void PilotOffsetInit();
 void PilotOffsetInit( sgVec3 vec );
 void PilotOffsetAdjust( puObject * );
 void Vec3FromHeadingPitchRadius( sgVec3 vec3, float heading, float pitch, float radius );
+void HeadingPitchRadiusFromVec3( sgVec3 hpr, sgVec3 vec3 );
 //void PilotOffsetGet( float *po );
 sgVec3 *PilotOffsetGet();
 void PilotOffsetSet( int opt, float setting);
@@ -28,40 +29,39 @@ float PilotOffsetGetSetting( int opt );
 /* binding functions for chase view offset */
 
 static void
-setPilotOffsetHeadingDeg (float value)
+setPilotXOffset (float value)
 {
        PilotOffsetSet(0, value);
 }
 
 static float
-getPilotOffsetHeadingDeg ()
+getPilotXOffset ()
 {
        return( PilotOffsetGetSetting(0) );
 }
 
 
 static void
-setPilotOffsetPitchDeg (float value)
+setPilotYOffset (float value)
 {
        PilotOffsetSet(1, value);
 }
 
 static float
-getPilotOffsetPitchDeg ()
+getPilotYOffset ()
 {
        return( PilotOffsetGetSetting(1) );
 }
 
 
 static void
-setPilotOffsetRadiusM (float value)
+setPilotZOffset (float value)
 {
        PilotOffsetSet(2, value);
 }
 
 static float
-getPilotOffsetRadiusM ()
+getPilotZOffset ()
 {
        return( PilotOffsetGetSetting(2) );
 }
-
index 69292a3c23501cdf51184617b946b7c7f6c85840..2dcc30f77d15907646df228a308cf3d48a80fb50 100644 (file)
@@ -407,6 +407,8 @@ void fgRenderFrame( void ) {
        = fgGetNode("/position/latitude-deg");
     static const SGPropertyNode *altitude
        = fgGetNode("/position/altitude-ft");
+    static const SGPropertyNode *groundlevel_nearplane
+       = fgGetNode("/sim/current-view/ground-level-nearplane-m");
 
     // Update the default (kludged) properties.
     fgUpdateProps();
@@ -592,15 +594,11 @@ void fgRenderFrame( void ) {
        double agl = current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER
            - scenery.get_cur_elev();
 
-//     if (fgGetBool("/sim/view/internal"))
-//       ssgSetNearFar( 0.2f, 120000.0f );
-//     else if ( agl > 10.0)
-
         if ( agl > 10.0 ) {
             scene_nearplane = 10.0f;
             scene_farplane = 120000.0f;
        } else {
-            scene_nearplane = 0.5f;
+            scene_nearplane = groundlevel_nearplane->getDoubleValue();
             scene_farplane = 120000.0f;
         }
 
index e6257c4a53290838512db58f0a968ce9e4ac066b..4f37eeb630da43b1347ae7926ffa9322a4ac68b0 100644 (file)
@@ -177,7 +177,7 @@ fgSetDefaults ()
     fgSetInt("/sim/startup/ysize", 600);
     fgSetInt("/sim/rendering/bits-per-pixel", 16);
     fgSetString("/sim/view-mode", "pilot");
-    fgSetDouble("/sim/view/offset-deg", 0);
+    fgSetDouble("/sim/current-view/heading-offset-deg", 0);
     fgSetDouble("/environment/visibility-m", 20000);
 
                                // HUD options
@@ -427,7 +427,7 @@ parse_fov( const string& arg ) {
     if ( fov < FG_FOV_MIN ) { fov = FG_FOV_MIN; }
     if ( fov > FG_FOV_MAX ) { fov = FG_FOV_MAX; }
 
-    fgSetDouble("/sim/field-of-view", fov);
+    fgSetDouble("/sim/current-view/field-of-view", fov);
 
     // printf("parse_fov(): result = %.4f\n", fov);
 
@@ -886,7 +886,8 @@ parse_option (const string& arg)
            (FGViewer *)globals->get_viewmgr()->get_view( 0 );
        pilot_view->setHeadingOffset_deg( default_view_offset * SGD_RADIANS_TO_DEGREES );
        pilot_view->setGoalHeadingOffset_deg( default_view_offset * SGD_RADIANS_TO_DEGREES );
-       fgSetDouble("/sim/view/offset-deg", default_view_offset  * SGD_RADIANS_TO_DEGREES );
+       fgSetDouble( "/sim/current-view/heading-offset-deg",
+                     default_view_offset  * SGD_RADIANS_TO_DEGREES );
     // $$$ end - added VS Renganathan, 14 Oct 2K
     } else if ( arg.find( "--visibility=" ) == 0 ) {
        fgSetDouble("/environment/visibility-m", atof(arg.substr(13)));
@@ -1290,6 +1291,3 @@ fgUsage ()
          << "                                  instances allowed." << endl
          << endl;
 }
-
-
-
index 2c3fde7467ba848c9e9039e281444b1d06dc94c3..f28a4dad859efcc8a6b733a671456271b74afedd 100644 (file)
 // Norman's Optimized matrix rotators!                          //
 //////////////////////////////////////////////////////////////////
 
-static void fgMakeLOCAL( sgMat4 dst, const double Theta,
-                               const double Phi, const double Psi)
-{
-    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) ;
-       
-    dst[0][0] = cosPhi * cosTheta;
-    dst[0][1] =        sinPhi * cosPsi + cosPhi * -sinTheta * -sinPsi;
-    dst[0][2] =        sinPhi * sinPsi + cosPhi * -sinTheta * cosPsi;
-    dst[0][3] =        SG_ZERO;
-
-    dst[1][0] = -sinPhi * cosTheta;
-    dst[1][1] =        cosPhi * cosPsi + -sinPhi * -sinTheta * -sinPsi;
-    dst[1][2] =        cosPhi * sinPsi + -sinPhi * -sinTheta * cosPsi;
-    dst[1][3] = SG_ZERO ;
-       
-    dst[2][0] = sinTheta;
-    dst[2][1] =        cosTheta * -sinPsi;
-    dst[2][2] =        cosTheta * cosPsi;
-    dst[2][3] = SG_ZERO;
-       
-    dst[3][0] = SG_ZERO;
-    dst[3][1] = SG_ZERO;
-    dst[3][2] = SG_ZERO;
-    dst[3][3] = SG_ONE ;
-}
-
 
 // Since these are pure rotation matrices we can save some bookwork
 // by considering them to be 3x3 until the very end -- NHV
@@ -156,48 +125,13 @@ static void MakeVIEW_OFFSET( sgMat4 dst,
     dst[3][3] = SG_ONE;
 }
 
-// Taking advantage of the 3x3 nature of this -- NHV
-inline static void MakeWithWorldUp( sgMat4 dst, const sgMat4 UP, const sgMat4 LOCAL )
-{
-    sgMat4 tmp;
-
-    float a = UP[0][0];
-    float b = UP[1][0];
-    float c = UP[2][0];
-    tmp[0][0] = a*LOCAL[0][0] + b*LOCAL[0][1] + c*LOCAL[0][2] ;
-    tmp[1][0] = a*LOCAL[1][0] + b*LOCAL[1][1] + c*LOCAL[1][2] ;
-    tmp[2][0] = a*LOCAL[2][0] + b*LOCAL[2][1] + c*LOCAL[2][2] ;
-    tmp[3][0] = SG_ZERO ;
-
-    a = UP[0][1];
-    b = UP[1][1];
-    c = UP[2][1];
-    tmp[0][1] = a*LOCAL[0][0] + b*LOCAL[0][1] + c*LOCAL[0][2] ;
-    tmp[1][1] = a*LOCAL[1][0] + b*LOCAL[1][1] + c*LOCAL[1][2] ;
-    tmp[2][1] = a*LOCAL[2][0] + b*LOCAL[2][1] + c*LOCAL[2][2] ;
-    tmp[3][1] = SG_ZERO ;
-
-    a = UP[0][2];
-    c = UP[2][2];
-    tmp[0][2] = a*LOCAL[0][0] + c*LOCAL[0][2] ;
-    tmp[1][2] = a*LOCAL[1][0] + c*LOCAL[1][2] ;
-    tmp[2][2] = a*LOCAL[2][0] + c*LOCAL[2][2] ;
-    tmp[3][2] = SG_ZERO ;
-
-    tmp[0][3] = SG_ZERO ;
-    tmp[1][3] = SG_ZERO ;
-    tmp[2][3] = SG_ZERO ;
-    tmp[3][3] = SG_ONE ;
-    sgCopyMat4(dst, tmp);
-}
-
 
 ////////////////////////////////////////////////////////////////////////
 // Implementation of FGViewer.
 ////////////////////////////////////////////////////////////////////////
 
 // Constructor
-FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index, bool at_model, int at_model_index ):
+FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index, bool at_model, int at_model_index, double x_offset_m, double y_offset_m, double z_offset_m, double near_m ):
     _scaling_type(FG_SCALING_MAX),
     _fov_deg(55.0),
     _dirty(true),
@@ -210,9 +144,6 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index, bool
     _roll_deg(0),
     _pitch_deg(0),
     _heading_deg(0),
-    _x_offset_m(0),
-    _y_offset_m(0),
-    _z_offset_m(0),
     _heading_offset_deg(0),
     _pitch_offset_deg(0),
     _roll_offset_deg(0),
@@ -225,6 +156,10 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index, bool
     _from_model_index = from_model_index;
     _at_model = at_model;
     _at_model_index = at_model_index;
+    _x_offset_m = x_offset_m;
+    _y_offset_m = y_offset_m;
+    _z_offset_m = z_offset_m;
+    _ground_level_nearplane_m = near_m;
     //a reasonable guess for init, so that the math doesn't blow up
 }
 
@@ -551,6 +486,7 @@ FGViewer::recalc ()
   sgVec3 minus_z, right, forward, tilt;
   sgMat4 tmpROT;  // temp rotation work matrices
   sgVec3 eye_pos, at_pos;
+  sgVec3 position_offset; // eye position offsets (xyz)
 
   // The position vectors originate from the view point or target location
   // depending on the type of view.
@@ -628,11 +564,6 @@ FGViewer::recalc ()
   sgSetVec3( right, LOCAL[1][0], LOCAL[1][1], LOCAL[1][2] );
   sgSetVec3( forward, -LOCAL[0][0], -LOCAL[0][1], -LOCAL[0][2] );
 
-  // create the (xyz) eye Position offsets Vector
-  sgVec3 position_offset;
-  sgSetVec3( position_offset, -_z_offset_m, _x_offset_m, _y_offset_m );
-
-
   if (_type == FG_LOOKAT) {
 
     // Note that when in "lookat" view the "world up" vector is always applied
@@ -644,10 +575,10 @@ FGViewer::recalc ()
       (_heading_offset_deg -_heading_deg) * SG_DEGREES_TO_RADIANS, _world_up,
       _pitch_offset_deg * SG_DEGREES_TO_RADIANS, right );
    
-    // Eye Position Offsets to vector
-    sgXformVec3( position_offset, position_offset, UP );
-
     // add in the Orientation Offsets here
+    sgSetVec3( position_offset, _x_offset_m, _y_offset_m, _z_offset_m );
+    sgXformVec3( position_offset, position_offset, UP);
+
     sgXformVec3( position_offset, position_offset, VIEW_OFFSET );
 
     // add the Position offsets from object to the eye position
@@ -671,17 +602,26 @@ FGViewer::recalc ()
       _heading_offset_deg  * SG_DEGREES_TO_RADIANS, _view_up,
       _pitch_offset_deg  * SG_DEGREES_TO_RADIANS, right );
 
-    // Eye Position Offsets to vector
-    sgXformVec3( position_offset, position_offset, LOCAL);
-
-    // add the offsets including rotations to the translation vector
-    sgAddVec3( _view_pos, position_offset );
-
     // Make the VIEW matrix.
     sgSetVec4(VIEW[0], right[0], right[1], right[2],SG_ZERO);
     sgSetVec4(VIEW[1], forward[0], forward[1], forward[2],SG_ZERO);
     sgSetVec4(VIEW[2], _view_up[0], _view_up[1], _view_up[2],SG_ZERO);
     sgSetVec4(VIEW[3], SG_ZERO, SG_ZERO, SG_ZERO,SG_ONE);
+
+    // rotate matrix to get a matrix to apply Eye Position Offsets
+    sgMat4 VIEW_UP; // L0 forward L1 right L2 up
+    sgCopyVec4(VIEW_UP[0], LOCAL[1]); 
+    sgCopyVec4(VIEW_UP[1], LOCAL[2]);
+    sgCopyVec4(VIEW_UP[2], LOCAL[0]);
+    sgZeroVec4(VIEW_UP[3]);
+
+    // Eye Position Offsets to vector
+    sgSetVec3( position_offset, _x_offset_m, _y_offset_m, _z_offset_m );
+    sgXformVec3( position_offset, position_offset, VIEW_UP);
+
+    // add the offsets including rotations to the translation vector
+    sgAddVec3( _view_pos, position_offset );
+
     // multiply the OFFSETS (for heading and pitch) into the VIEW
     sgPostMultMat4(VIEW, VIEW_OFFSET);
 
@@ -832,10 +772,3 @@ FGViewer::update (int dt)
     }
   }
 }
-
-
-
-
-
-
-
index ce321645038447800f7027c55b57fea1ca980850..0fc7125d98e7e51678826e56606d45e47bba2615 100644 (file)
@@ -62,7 +62,9 @@ public:
     };
 
     // Constructor
-    FGViewer( fgViewType Type, bool from_model, int from_model_index, bool at_model, int at_model_index );
+    FGViewer( fgViewType Type, bool from_model, int from_model_index,
+              bool at_model, int at_model_index, double x_offset_m,
+              double y_offset_m, double z_offset_m, double near_m );
 
     // Destructor
     virtual ~FGViewer( void );
@@ -216,7 +218,7 @@ public:
     virtual const sgVec4 *get_UP() { if ( _dirty ) { recalc(); } return UP; }
 
     //////////////////////////////////////////////////////////////////////
-    // Part 4: frustrum data setters and getters
+    // Part 4: View and frustrum data setters and getters
     //////////////////////////////////////////////////////////////////////
 
     virtual void set_fov( double fov_deg ) {
@@ -231,6 +233,11 @@ public:
     }
     virtual double get_aspect_ratio() const { return _aspect_ratio; }
 
+    virtual double getNear_m () const { return _ground_level_nearplane_m; }
+    inline void setNear_m (double near_m) {
+        _ground_level_nearplane_m = near_m;
+    }
+
     //////////////////////////////////////////////////////////////////////
     // Part 5: misc setters and getters
     //////////////////////////////////////////////////////////////////////
@@ -281,6 +288,9 @@ private:
     double _goal_pitch_offset_deg;
     double _goal_heading_offset_deg;
 
+    // used to set nearplane when at ground level for this view
+    double _ground_level_nearplane_m;
+
     fgViewType _type;
     fgScalingType _scaling_type;
 
index 971480647f466d320985a4f1955a6219ae761576..56bd8ed5436f78ae0afeb711288a9e20ae8b15b6 100644 (file)
@@ -54,6 +54,8 @@ FGViewMgr::init ()
   bool at_model = false;
   int from_model_index = 0;
   int at_model_index = 0;
+  double x_offset_m, y_offset_m, z_offset_m;
+  double near_m;
 
   for (int i = 0; i < fgGetInt("/sim/number-views"); i++) {
     viewpath = "/sim/view";
@@ -94,12 +96,33 @@ FGViewMgr::init ()
       }
     }
 
+    nodepath = viewpath;
+    nodepath += "/config/x-offset-m";
+    x_offset_m = fgGetDouble(nodepath.c_str());
+    nodepath = viewpath;
+    nodepath += "/config/y-offset-m";
+    y_offset_m = fgGetDouble(nodepath.c_str());
+    nodepath = viewpath;
+    nodepath += "/config/z-offset-m";
+    z_offset_m = fgGetDouble(nodepath.c_str());
+
+    nodepath = viewpath;
+    nodepath += "/config/ground-level-nearplane-m";
+    near_m = fgGetDouble(nodepath.c_str());
+
     // supporting two types now "lookat" = 1 and "lookfrom" = 0
     if ( strcmp("lookat",strdata.c_str()) == 0 )
-      add_view(new FGViewer ( FG_LOOKAT, from_model, from_model_index, at_model, at_model_index ));
+      add_view(new FGViewer ( FG_LOOKAT, from_model, from_model_index,
+                              at_model, at_model_index, x_offset_m, y_offset_m,
+                              z_offset_m, near_m ));
     else
-      add_view(new FGViewer ( FG_LOOKFROM, from_model, from_model_index, false, 0 ));
+      add_view(new FGViewer ( FG_LOOKFROM, from_model, from_model_index, false,
+                              0, x_offset_m, y_offset_m, z_offset_m, near_m ));
+
   }
+
+  copyToCurrent();
+  
 }
 
 typedef double (FGViewMgr::*double_getter)() const;
@@ -107,36 +130,33 @@ typedef double (FGViewMgr::*double_getter)() const;
 void
 FGViewMgr::bind ()
 {
-  // FIXME:
-  // need to redo these bindings to the new locations (move to viewer?)
-  fgTie("/sim/view/offset-deg", this,
+  // these are bound to the current view properties
+  fgTie("/sim/current-view/heading-offset-deg", this,
        &FGViewMgr::getViewOffset_deg, &FGViewMgr::setViewOffset_deg);
-  fgSetArchivable("/sim/view/offset-deg");
-  fgTie("/sim/view/goal-offset-deg", this,
+  fgSetArchivable("/sim/current-view/heading-offset-deg");
+  fgTie("/sim/current-view/goal-heading-offset-deg", this,
        &FGViewMgr::getGoalViewOffset_deg, &FGViewMgr::setGoalViewOffset_deg);
-  fgSetArchivable("/sim/view/goal-offset-deg");
-  fgTie("/sim/view/tilt-deg", this,
+  fgSetArchivable("/sim/current-view/goal-heading-offset-deg");
+  fgTie("/sim/current-view/pitch-offset-deg", this,
        &FGViewMgr::getViewTilt_deg, &FGViewMgr::setViewTilt_deg);
-  fgSetArchivable("/sim/view/tilt-deg");
-  fgTie("/sim/view/goal-tilt-deg", this,
+  fgSetArchivable("/sim/current-view/pitch-offset-deg");
+  fgTie("/sim/current-view/goal-pitch-offset-deg", this,
        &FGViewMgr::getGoalViewTilt_deg, &FGViewMgr::setGoalViewTilt_deg);
-  fgSetArchivable("/sim/view/goal-tilt-deg");
-  fgTie("/sim/view/pilot/x-offset-m", this,
-       &FGViewMgr::getPilotXOffset_m, &FGViewMgr::setPilotXOffset_m);
-  fgSetArchivable("/sim/view/pilot/x-offset-m");
-  fgTie("/sim/view/pilot/y-offset-m", this,
-       &FGViewMgr::getPilotYOffset_m, &FGViewMgr::setPilotYOffset_m);
-  fgSetArchivable("/sim/view/pilot/y-offset-m");
-  fgTie("/sim/view/pilot/z-offset-m", this,
-       &FGViewMgr::getPilotZOffset_m, &FGViewMgr::setPilotZOffset_m);
-  fgSetArchivable("/sim/view/pilot/z-offset-m");
-  fgTie("/sim/field-of-view", this,
-       &FGViewMgr::getFOV_deg, &FGViewMgr::setFOV_deg);
-  fgSetArchivable("/sim/field-of-view");
-  fgTie("/sim/view/axes/long", this,
+  fgSetArchivable("/sim/current-view/goal-pitch-offset-deg");
+
+  fgTie("/sim/current-view/axes/long", this,
        (double_getter)0, &FGViewMgr::setViewAxisLong);
-  fgTie("/sim/view/axes/lat", this,
+  fgTie("/sim/current-view/axes/lat", this,
        (double_getter)0, &FGViewMgr::setViewAxisLat);
+
+  fgTie("/sim/current-view/field-of-view", this,
+       &FGViewMgr::getFOV_deg, &FGViewMgr::setFOV_deg);
+  fgSetArchivable("/sim/current-view/field-of-view");
+
+  fgTie("/sim/current-view/ground-level-nearplane-m", this,
+       &FGViewMgr::getNear_m, &FGViewMgr::setNear_m);
+  fgSetArchivable("/sim/current-view/ground-level-nearplane-m");
+
 }
 
 void
@@ -144,16 +164,13 @@ FGViewMgr::unbind ()
 {
   // FIXME:
   // need to redo these bindings to the new locations (move to viewer?)
-  fgUntie("/sim/view/offset-deg");
-  fgUntie("/sim/view/goal-offset-deg");
-  fgUntie("/sim/view/tilt-deg");
-  fgUntie("/sim/view/goal-tilt-deg");
-  fgUntie("/sim/view/pilot/x-offset-m");
-  fgUntie("/sim/view/pilot/y-offset-m");
-  fgUntie("/sim/view/pilot/z-offset-m");
+  fgUntie("/sim/current-view/heading-offset-deg");
+  fgUntie("/sim/current-view/goal-heading-offset-deg");
+  fgUntie("/sim/current-view/pitch-offset-deg");
+  fgUntie("/sim/current-view/goal-pitch-offset-deg");
   fgUntie("/sim/field-of-view");
-  fgUntie("/sim/view/axes/long");
-  fgUntie("/sim/view/axes/lat");
+  fgUntie("/sim/current-view/axes/long");
+  fgUntie("/sim/current-view/axes/lat");
 }
 
 void
@@ -235,27 +252,25 @@ FGViewMgr::update (int dt)
       loop_view->set_dirty();
     }
   }
+  setPilotXOffset_m(fgGetDouble("/sim/current-view/x-offset-m"));
+  setPilotYOffset_m(fgGetDouble("/sim/current-view/y-offset-m"));
+  setPilotZOffset_m(fgGetDouble("/sim/current-view/z-offset-m"));
 
-                               // Set up the chase view
-  // FIXME:
-  // Gotta change sgVec3Slider so that it takes xyz values as inputs 
-  // instead of spherical coordinates.
-  FGViewer *chase_view = (FGViewer *)get_view( 1 );
-
-  // get xyz Position offsets directly from GUI/sgVec3Slider
-  // FIXME: change GUI/sgVec3Slider to store the xyz in properties
-  // it would probably be faster than the way PilotOffsetGet()
-  // triggers a recalc all the time.
-  sgVec3 *pPO = PilotOffsetGet();
-  sgVec3 zPO;
-  sgCopyVec3( zPO, *pPO );
-  chase_view->setPositionOffsets(zPO[1], zPO[2], zPO[0] );
-
-                               // Update the current view
+                               // Update the current view
   do_axes();
   view->update(dt);
+  double tmp;
 }
 
+void
+FGViewMgr::copyToCurrent()
+{
+    fgSetDouble("/sim/current-view/x-offset-m", getPilotXOffset_m());
+    fgSetDouble("/sim/current-view/y-offset-m", getPilotYOffset_m());
+    fgSetDouble("/sim/current-view/z-offset-m", getPilotZOffset_m());
+}
+
+
 double
 FGViewMgr::getViewOffset_deg () const
 {
@@ -323,10 +338,9 @@ FGViewMgr::setGoalViewTilt_deg (double tilt)
 double
 FGViewMgr::getPilotXOffset_m () const
 {
-                               // FIXME: hard-coded pilot view position
-  const FGViewer * pilot_view = get_view(0);
-  if (pilot_view != 0) {
-    return ((FGViewer *)pilot_view)->getXOffset_m();
+  const FGViewer * view = get_current_view();
+  if (view != 0) {
+    return ((FGViewer *)view)->getXOffset_m();
   } else {
     return 0;
   }
@@ -335,20 +349,18 @@ FGViewMgr::getPilotXOffset_m () const
 void
 FGViewMgr::setPilotXOffset_m (double x)
 {
-                               // FIXME: hard-coded pilot view position
-  FGViewer * pilot_view = get_view(0);
-  if (pilot_view != 0) {
-    pilot_view->setXOffset_m(x);
+  FGViewer * view = get_current_view();
+  if (view != 0) {
+    view->setXOffset_m(x);
   }
 }
 
 double
 FGViewMgr::getPilotYOffset_m () const
 {
-                               // FIXME: hard-coded pilot view position
-  const FGViewer * pilot_view = get_view(0);
-  if (pilot_view != 0) {
-    return ((FGViewer *)pilot_view)->getYOffset_m();
+  const FGViewer * view = get_current_view();
+  if (view != 0) {
+    return ((FGViewer *)view)->getYOffset_m();
   } else {
     return 0;
   }
@@ -357,20 +369,18 @@ FGViewMgr::getPilotYOffset_m () const
 void
 FGViewMgr::setPilotYOffset_m (double y)
 {
-                               // FIXME: hard-coded pilot view position
-  FGViewer * pilot_view = get_view(0);
-  if (pilot_view != 0) {
-    pilot_view->setYOffset_m(y);
+  FGViewer * view = get_current_view();
+  if (view != 0) {
+    view->setYOffset_m(y);
   }
 }
 
 double
 FGViewMgr::getPilotZOffset_m () const
 {
-                               // FIXME: hard-coded pilot view position
-  const FGViewer * pilot_view = get_view(0);
-  if (pilot_view != 0) {
-    return ((FGViewer *)pilot_view)->getZOffset_m();
+  const FGViewer * view = get_current_view();
+  if (view != 0) {
+    return ((FGViewer *)view)->getZOffset_m();
   } else {
     return 0;
   }
@@ -379,10 +389,9 @@ FGViewMgr::getPilotZOffset_m () const
 void
 FGViewMgr::setPilotZOffset_m (double z)
 {
-                               // FIXME: hard-coded pilot view position
-  FGViewer * pilot_view = get_view(0);
-  if (pilot_view != 0) {
-    pilot_view->setZOffset_m(z);
+  FGViewer * view = get_current_view();
+  if (view != 0) {
+    view->setZOffset_m(z);
   }
 }
 
@@ -401,6 +410,21 @@ FGViewMgr::setFOV_deg (double fov)
     view->set_fov(fov);
 }
 
+double
+FGViewMgr::getNear_m () const
+{
+  const FGViewer * view = get_current_view();
+  return (view == 0 ? 0.5f : view->getNear_m());
+}
+
+void
+FGViewMgr::setNear_m (double near_m)
+{
+  FGViewer * view = get_current_view();
+  if (view != 0)
+    view->setNear_m(near_m);
+}
+
 void
 FGViewMgr::setViewAxisLong (double axis)
 {
@@ -456,4 +480,3 @@ FGViewMgr::do_axes ()
 
   get_current_view()->setGoalHeadingOffset_deg(viewDir);
 }
-
index e1dcff32bd2d0c1ce6bcf7ee01d579a09255f7f0..6101f2aef8b10f72d047bb27de40b9a6311cc6a8 100644 (file)
@@ -93,6 +93,7 @@ public:
        if ( current >= (int)views.size() ) {
            current = 0;
        }
+        copyToCurrent();
        return views[current];
     }
     inline FGViewer *prev_view() {
@@ -134,8 +135,11 @@ private:
     void setPilotZOffset_m (double z);
     double getFOV_deg () const;
     void setFOV_deg (double fov);
+    double getNear_m () const;
+    void setNear_m (double near_m);
     void setViewAxisLong (double axis);
     void setViewAxisLat (double axis);
+    void copyToCurrent ();
 
     typedef vector < FGViewer * > viewer_list;
     viewer_list views;