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; } }