Here's another batch of virtual cockpit stuff.  There is a patch
attached, and the two modified files in full can be found at:

   http://www.plausible.org/andy/vc-20020305.tar.gz

Folks who want to try the patch (it's easy, really!) can just get into
their just-updated FlightGear source directory and do:

   patch -p0 < vc.patch

The virtual cockpit now scrolls correctly using the mouse mechanism.
Really, this is a fix to mouse.cxx to use the "standard" view
direction mechanism and not to the virtual cockpit per se.

The HUD code transforms properly in virtual cockpit mode.  This turned
out not to be so bad at all; the changes largely mirror those to the
panel and don't involve the rendering code.  One significant
difference, however, is that the "compress-fraction" property on the
ladder has changed its meaning.  It used to represent pixels per
degree, which was kinda dumb (it didn't correct for changes in the FOV
due to zoom or whatnot), and was essentially unworkable in a virtual
cockpit where pixels lose their meaning.  Now, it's a a compression
relative to "1".  That is, if set to 1, one degree on the ladder is
one degree in the field of view.  If set to 10, ten degrees of ladder
pitch is represented as one degree of FOV.  This requires new HUD
ladder files for your base package.  Find them here:

   http://www.plausible.org/andy/huds-20020305.tar.gz

The virtual HUDs aren't quite "there" yet, largely for authoring
reasons.  The existing HUD descriptions are much (much) larger than a
real hud, and were designed to fill the screen.  In particular, the
text in the corners (fps counters, etc...) looks really silly in
virtual cockpit mode.  We should come up with smaller, more realistic
ones; typical early generation huds were no more than ten degrees
wide.

Which leads me to a random digression: does anyone have a good
reference on historic HUD symbology?  Not MIL-STD documents about
current fighters, nor research papers on what would be cool, but
actual photos and descriptions of the HUDs installed on (just for the
sake of argument) the Harriers and late model A-4's. :)

Andy

-- 
Andrew J. Ross                NextBus Information Systems
Senior Software Engineer      Emeryville, CA
[EMAIL PROTECTED]              http://www.nextbus.com
"Men go crazy in conflagrations.  They only get better one by one."
  - Sting (misquoted)
? src/Cockpit/panel.cxx-andy
? tests/test-env-map
Index: src/Cockpit/hud.cxx
===================================================================
RCS file: /var/cvs/FlightGear-0.7/FlightGear/src/Cockpit/hud.cxx,v
retrieving revision 1.48
diff -u -r1.48 hud.cxx
--- src/Cockpit/hud.cxx 5 Feb 2002 14:57:46 -0000       1.48
+++ src/Cockpit/hud.cxx 6 Mar 2002 05:54:46 -0000
@@ -169,6 +169,8 @@
 static instr_item * readCard ( const SGPropertyNode * node);
 static instr_item * readLabel( const SGPropertyNode * node);
 static instr_item * readTBI( const SGPropertyNode * node);
+static void drawHUD();
+static void fgUpdateHUDVirtual();
 //$$$ end   - added, Neetha, 28 Nov 2k
 
 void fgHUDalphaInit( void );
@@ -308,6 +310,11 @@
     nadir                      = node->getIntValue("nadir");  //suma
     hat                                = node->getIntValue("hat");
 
+    // The factor assumes a base of 55 degrees per 640 pixels.
+    // Invert to convert the "compression" factor to a
+    // pixels-per-degree number.
+    if(factor == 0) factor = 1;
+    factor = (640./55.) / factor;
 
     SG_LOG(SG_INPUT, SG_INFO, "Done reading instrument " << name);
        
@@ -1032,7 +1039,12 @@
 // all C++.
 //
 void fgUpdateHUD( void ) {
-       
+
+    if(fgGetBool("/sim/virtual-cockpit")) {
+        fgUpdateHUDVirtual();
+        return;
+    }
+    
     static const float normal_aspect = float(640) / float(480);
     // note: aspect_ratio is Y/X
     float current_aspect = 1.0f/globals->get_current_view()->get_aspect_ratio();
@@ -1047,9 +1059,78 @@
     }
 }
 
+void fgUpdateHUDVirtual()
+{
+    FGViewer* view = globals->get_current_view();
+
+    // Standard fgfs projection, with essentially meaningless clip
+    // planes (we'll map the whole HUD plane to z=-1)
+    glMatrixMode(GL_PROJECTION);
+    glPushMatrix();
+    glLoadIdentity();
+    gluPerspective(view->get_v_fov(), 1/view->get_aspect_ratio(), 0.1, 10);
+
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glLoadIdentity();
+
+    // Standard fgfs view direction computation
+    float lookat[3];
+    lookat[0] = -sin(view->get_view_offset());
+    lookat[1] = tan(view->get_view_tilt());
+    lookat[2] = -cos(view->get_view_offset());
+    if(fabs(lookat[1]) > 9999) lookat[1] = 9999; // FPU sanity
+    gluLookAt(0, 0, 0, lookat[0], lookat[1], lookat[2], 0, 1, 0);
+
+    // Map the -1:1 square to a 55.0x41.25 degree wide patch at z=1.
+    // This is the default fgfs field of view, which the HUD files are
+    // written to assume.
+    float dx = 0.52056705; // tan(55/2)
+    float dy = dx * 0.75;  // assumes 4:3 aspect ratio
+    float m[16];
+    m[0] = dx; m[4] =  0; m[ 8] = 0; m[12] = 0;
+    m[1] =  0; m[5] = dy; m[ 9] = 0; m[13] = 0;
+    m[2] =  0; m[6] =  0; m[10] = 1; m[14] = 0;
+    m[3] =  0; m[7] =  0; m[11] = 0; m[15] = 1;
+    glMultMatrixf(m);
+    
+    // Convert the 640x480 "HUD standard" coordinate space to a square
+    // about the origin in the range [-1:1] at depth of -1
+    glScalef(1./320, 1./240, 1);
+    glTranslatef(-320, -240, -1);
+    
+    // Do the deed
+    drawHUD();
+
+    // Clean up our mess
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix();
+    glMatrixMode(GL_MODELVIEW);
+    glPopMatrix();
+}
+
 void fgUpdateHUD( GLfloat x_start, GLfloat y_start,
                   GLfloat x_end, GLfloat y_end )
 {
+    glMatrixMode(GL_PROJECTION);
+    glPushMatrix();
+    glLoadIdentity();
+    gluOrtho2D(x_start, x_end, y_start, y_end);
+
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glLoadIdentity();
+
+    drawHUD();
+
+    glMatrixMode(GL_PROJECTION);
+    glPopMatrix();
+    glMatrixMode(GL_MODELVIEW);
+    glPopMatrix();
+}
+
+void drawHUD()
+{
     int brightness;
     // int day_night_sw = current_aircraft.controls->day_night_switch;
     int day_night_sw = global_day_night_switch;
@@ -1069,15 +1150,6 @@
     brightness = pHUDInstr->get_brightness();
     // brightness = HUD_deque.at(0)->get_brightness();
 
-    glMatrixMode(GL_PROJECTION);
-    glPushMatrix();
-
-    glLoadIdentity();
-    gluOrtho2D(x_start, x_end, y_start, y_end);
-    glMatrixMode(GL_MODELVIEW);
-    glPushMatrix();
-    glLoadIdentity();
-
     glDisable(GL_DEPTH_TEST);
     glDisable(GL_LIGHTING);
 
@@ -1229,9 +1301,5 @@
 
     glEnable(GL_DEPTH_TEST);
     glEnable(GL_LIGHTING);
-    glMatrixMode(GL_PROJECTION);
-    glPopMatrix();
-    glMatrixMode(GL_MODELVIEW);
-    glPopMatrix();
 }
 
Index: src/GUI/mouse.cxx
===================================================================
RCS file: /var/cvs/FlightGear-0.7/FlightGear/src/GUI/mouse.cxx,v
retrieving revision 1.23
diff -u -r1.23 mouse.cxx
--- src/GUI/mouse.cxx   8 Feb 2002 16:18:50 -0000       1.23
+++ src/GUI/mouse.cxx   6 Mar 2002 05:54:49 -0000
@@ -107,11 +107,6 @@
 static int MOUSE_XSIZE = 0;
 static int MOUSE_YSIZE = 0;
 
-// uncomment this for view to exactly follow mouse in MOUSE_VIEW mode
-// else smooth out the view panning to .01 radian per frame
-// see view_offset smoothing mechanism in main.cxx
-#define NO_SMOOTH_MOUSE_VIEW
-
 // uncomment following to
 #define RESET_VIEW_ON_LEAVING_MOUSE_VIEW
 
@@ -191,6 +186,20 @@
        return globals->get_current_view()->get_goal_view_offset();
 }
 
+static inline void set_goal_view_tilt( float tilt )
+{
+       globals->get_current_view()->set_goal_view_tilt(tilt);
+}
+
+static inline void set_view_tilt( float tilt )
+{
+       globals->get_current_view()->set_view_tilt(tilt);
+}
+
+static inline float get_view_tilt() {
+       return globals->get_current_view()->get_view_tilt();
+}
+
 static inline void move_brake(float offset) {
        globals->get_controls()->move_brake(FGControls::ALL_WHEELS, offset);
 }
@@ -416,19 +425,10 @@
                 
             case MOUSE_VIEW:
                 if( y <= 0 ) {
-#define CONTRAINED_MOUSE_VIEW_Y
-#ifdef CONTRAINED_MOUSE_VIEW_Y
                     y = 1;
-#else
-                    y = wh-2;
-#endif // CONTRAINED_MOUSE_VIEW_Y
                     need_warp = 1;
                 } else if( y >= wh-1) {
-#ifdef CONTRAINED_MOUSE_VIEW_Y
                     y = wh-2;
-#else
-                    y = 1;
-#endif // CONTRAINED_MOUSE_VIEW_Y
                     need_warp = 1;
                 }
                 // wrap MOUSE_VIEW mode cursor x position
@@ -439,49 +439,20 @@
                     need_warp = 1;
                     x = 1;
                 }
-                // try to get SGD_PI movement in each half of screen
-                // do spherical pan
-                W = ww;
-                H = wh;
-                if( middle_button() ) {
-                    trackball(lastGuiQuat,
-                              (2.0f * _mX - W) / W,
-                              0, //(H - 2.0f * y) / H,         // 3
-                              (2.0f * x - W) / W,
-                              0 //(H - 2.0f * _mY) / H       // 1
-                             );
-                    x = _mX;
-                    y = _mY;
-                    need_warp = 1;
-                } else {
-                    trackball(lastGuiQuat,
-                              0, //(2.0f * _mX - W) / W,  // 0
-                              (H - 2.0f * y) / H,         // 3
-                              0, //(2.0f * x - W) / W,    // 2
-                              (H - 2.0f * _mY) / H        // 1 
-                             );
-                }
-                add_quats(lastGuiQuat, curGuiQuat, curGuiQuat);
-                build_rotmatrix(GuiQuat_mat, curGuiQuat);
-                
-                // do horizontal pan
-                // this could be done in above quat
-                // but requires redoing view pipeline
-                offset = get_goal_view_offset();
-                offset += ((_mX - x) * SGD_2PI / W );
-                while (offset < 0.0) {
-                    offset += SGD_2PI;
-                }
-                while (offset > SGD_2PI) {
-                    offset -= SGD_2PI;
-                }
-                set_goal_view_offset(offset);
-#ifdef NO_SMOOTH_MOUSE_VIEW
-                set_view_offset(offset);
-#endif
-                break;
-            
-            default:
+
+               {
+                   float scale = SGD_PI / MOUSE_XSIZE;
+                   float dx = (_mX - x) * scale;
+                   float dy = (_mY - y) * scale;
+                   
+                   float newOffset = get_view_offset() + dx;
+                   set_goal_view_offset(newOffset);
+                   set_view_offset(newOffset);
+                   
+                   float newTilt = get_view_tilt() + dy;
+                   set_goal_view_tilt(newTilt);
+                   set_view_tilt(newTilt);
+               }
                 break;
         }
     }

Reply via email to