X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FCockpit%2Fpanel.cxx;h=bee42a477766ecd75ba3cf9e3eaccf26fa62c670;hb=d982efc4c4d166e144023664b8ac1c63233f5f82;hp=1bffd5e7a627d489bdcd4be011e0192a6d36e540;hpb=7e93fca8eeb1e672aa7d8e5f0fa4d71b24f226c4;p=flightgear.git diff --git a/src/Cockpit/panel.cxx b/src/Cockpit/panel.cxx index 1bffd5e7a..bee42a477 100644 --- a/src/Cockpit/panel.cxx +++ b/src/Cockpit/panel.cxx @@ -83,11 +83,16 @@ get_aspect_adjust (int xsize, int ysize) bool fgPanelVisible () { - return (fgGetBool("/sim/virtual-cockpit") || - ((current_panel != 0) && - (current_panel->getVisibility()) && - (globals->get_viewmgr()->get_current() == 0) && - (globals->get_current_view()->get_view_offset() == 0.0))); + if(current_panel == 0) + return false; + if(current_panel->getVisibility() == 0) + return false; + if(globals->get_viewmgr()->get_current() != 0) + return false; + if(globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS != 0 && + !fgGetBool("/sim/virtual-cockpit")) + return false; + return true; } @@ -175,7 +180,6 @@ FGPanel::FGPanel () _mouseInstrument(0), _width(WIN_W), _height(int(WIN_H * 0.5768 + 1)), _x_offset(0), _y_offset(0), _view_height(int(WIN_H * 0.4232)), - _bound(false), _jitter(0.0), _xsize_node(fgGetNode("/sim/startup/xsize", true)), _ysize_node(fgGetNode("/sim/startup/ysize", true)) @@ -189,8 +193,6 @@ FGPanel::FGPanel () */ FGPanel::~FGPanel () { - if (_bound) - unbind(); for (instrument_list_type::iterator it = _instruments.begin(); it != _instruments.end(); it++) { @@ -247,15 +249,10 @@ FGPanel::init () void FGPanel::bind () { - fgTie("/sim/panel/visibility", &_visibility); fgSetArchivable("/sim/panel/visibility"); - fgTie("/sim/panel/x-offset", &_x_offset); fgSetArchivable("/sim/panel/x-offset"); - fgTie("/sim/panel/y-offset", &_y_offset); fgSetArchivable("/sim/panel/y-offset"); - fgTie("/sim/panel/jitter", &_jitter); fgSetArchivable("/sim/panel/jitter"); - _bound = true; } @@ -265,10 +262,6 @@ FGPanel::bind () void FGPanel::unbind () { - fgUntie("/sim/panel/visibility"); - fgUntie("/sim/panel/x-offset"); - fgUntie("/sim/panel/y-offset"); - _bound = false; } @@ -276,8 +269,14 @@ FGPanel::unbind () * Update the panel. */ void -FGPanel::update (int dt) +FGPanel::update (double dt) { + // TODO: cache the nodes + _visibility = fgGetBool("/sim/panel/visibility"); + _x_offset = fgGetInt("/sim/panel/x-offset"); + _y_offset = fgGetInt("/sim/panel/y-offset"); + _jitter = fgGetFloat("/sim/panel/jitter"); + // Do nothing if the panel isn't visible. if ( !fgPanelVisible() ) { return; @@ -400,7 +399,6 @@ FGPanel::update (GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh) for ( ; current != end; current++) { FGPanelInstrument * instr = *current; glPushMatrix(); - glTranslated(x_offset, y_offset, 0); glTranslated(instr->getXPos(), instr->getYPos(), 0); instr->draw(); glPopMatrix(); @@ -419,52 +417,25 @@ FGPanel::update (GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } -// Yanked from the YASim codebase. Should probably be replaced with -// the 4x4 routine from plib, which is more appropriate here. -static void invert33Matrix(float* m) -{ - // Compute the inverse as the adjoint matrix times 1/(det M). - // A, B ... I are the cofactors of a b c - // d e f - // g h i - float a=m[0], b=m[1], c=m[2]; - float d=m[3], e=m[4], f=m[5]; - float g=m[6], h=m[7], i=m[8]; - - float A = (e*i - h*f); - float B = -(d*i - g*f); - float C = (d*h - g*e); - float D = -(b*i - h*c); - float E = (a*i - g*c); - float F = -(a*h - g*b); - float G = (b*f - e*c); - float H = -(a*f - d*c); - float I = (a*e - d*b); - - float id = 1/(a*A + b*B + c*C); - - m[0] = id*A; m[1] = id*D; m[2] = id*G; - m[3] = id*B; m[4] = id*E; m[5] = id*H; - m[6] = id*C; m[7] = id*F; m[8] = id*I; -} - void FGPanel::setupVirtualCockpit() { int i; FGViewer* view = globals->get_current_view(); - // Corners for the panel quad. These numbers put a "standard" - // panel at 1m from the eye, with a horizontal size of 60 degrees, - // and with its center 5 degrees down. This will work well for - // most typical screen-space panel definitions. In principle, - // these should be settable per-panel, so that you can have lots - // of panel objects plastered about the cockpit in realistic + // Generate corners for the panel quad. Put the top edge of the + // panel 1m in and 6 degrees down from the forward direction, and + // make the whole thing 60 degrees wide. In principle, these + // should be settable per-panel, so that you can have lots of + // panel objects plastered about the cockpit in realistic // positions and orientations. - float DY = .0875; // tan(5 degrees) - float a[] = { -0.5773503, -0.4330172 - DY, -1 }; // bottom left - float b[] = { 0.5773503, -0.4330172 - DY, -1 }; // bottom right - float c[] = { -0.5773503, 0.4330172 - DY, -1 }; // top left + float a[3], b[3], c[3]; + float pw = tan(30*SGD_DEGREES_TO_RADIANS); + float ph = 2 * pw * (float)_height/(float)_width; + float ptop = -tan(6*SGD_DEGREES_TO_RADIANS); + a[0] = -pw; a[1] = ptop-ph; a[2] = -1; // bottom left + b[0] = pw; b[1] = ptop-ph; b[2] = -1; // bottom right + c[0] = -pw; c[1] = ptop; c[2] = -1; // top left // A standard projection, in meters, with especially close clip // planes. @@ -476,12 +447,13 @@ FGPanel::setupVirtualCockpit() glMatrixMode(GL_MODELVIEW); glPushMatrix(); + glLoadIdentity(); // Generate a "look at" matrix using OpenGL (!) coordinate // conventions. float lookat[3]; - float pitch = view->get_view_tilt(); - float rot = view->get_view_offset(); + float pitch = view->getPitchOffset_deg() * SGD_DEGREES_TO_RADIANS; + float rot = view->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS; lookat[0] = -sin(rot); lookat[1] = sin(pitch) / cos(pitch); lookat[2] = -cos(rot); @@ -492,42 +464,29 @@ FGPanel::setupVirtualCockpit() glTranslatef(a[0], a[1], a[2]); // Generate a matrix to translate unit square coordinates from the - // panel to real world coordinates. Use a basis for the panel - // quad and invert. Note: this matrix is relatively expensive to + // panel to real world coordinates. Use a transposed basis for + // the panel quad. Note: this matrix is relatively expensive to // compute, and is invariant. Consider precomputing and storing // it. Also, consider using the plib vector math routines, so the // reuse junkies don't yell at me. (Fine, I hard-coded a cross // product. Just shoot me and be done with it.) - float u[3], v[3], w[3], m[9]; + float u[3], v[3], w[3], m[16]; for(i=0; i<3; i++) u[i] = b[i] - a[i]; // U = B - A for(i=0; i<3; i++) v[i] = c[i] - a[i]; // V = C - A w[0] = u[1]*v[2] - v[1]*u[2]; // W = U x V w[1] = u[2]*v[0] - v[2]*u[0]; w[2] = u[0]*v[1] - v[0]*u[1]; - for(int i=0; i<3; i++) { // |Ux Uy Uz|-1 - m[i] = u[i]; // m =|Vx Vy Vz| - m[i+3] = v[i]; // |Wx Wy Wz| - m[i+6] = w[i]; - } - invert33Matrix(m); - - float glm[16]; // Expand to a 4x4 OpenGL matrix. - glm[0] = m[0]; glm[4] = m[1]; glm[8] = m[2]; glm[12] = 0; - glm[1] = m[3]; glm[5] = m[4]; glm[9] = m[5]; glm[13] = 0; - glm[2] = m[6]; glm[6] = m[7]; glm[10] = m[8]; glm[14] = 0; - glm[3] = 0; glm[7] = 0; glm[11] = 0; glm[15] = 1; - glMultMatrixf(glm); - - // Finally, a scaling factor to convert the 1024x768 range the - // panel uses to a unit square mapped to the panel quad. - glScalef(1./1024, 1./768, 1); - - // Scale to the appropriate vertical size. I'm not quite clear on - // this yet; an identical scaling is not appropriate for - // _width, for example. This should probably go away when panel - // coordinates get sanified for virtual cockpits. - glScalef(1, _height/768.0, 1); - + + m[0] = u[0]; m[4] = v[0]; m[8] = w[0]; m[12] = 0; // |Ux Vx Wx| + m[1] = u[1]; m[5] = v[1]; m[9] = w[1]; m[13] = 0; // m = |Uy Vy Wy| + m[2] = u[2]; m[6] = v[2]; m[10] = w[2]; m[14] = 0; // |Uz Vz Wz| + m[3] = 0; m[7] = 0; m[11] = 0; m[15] = 1; + glMultMatrixf(m); + + // Finally, a scaling factor to map the panel's width and height + // to the unit square. + glScalef(1./_width, 1./_height, 1); + // Now, turn off the Z buffer. The panel code doesn't need // it, and we're using different clip planes anyway (meaning we // can't share it without glDepthRange() hackery or much @@ -623,7 +582,7 @@ FGPanel::doMouseAction (int button, int updown, int x, int y) if (updown == 1) { _mouseDown = false; _mouseInstrument = 0; - return true; + return false; } // Scale for the real window size. @@ -654,8 +613,7 @@ FGPanel::doMouseAction (int button, int updown, int x, int y) _mouseX = x - ix; _mouseY = y - iy; // Always do the action once. - _mouseInstrument->doMouseAction(_mouseButton, _mouseX, _mouseY); - return true; + return _mouseInstrument->doMouseAction(_mouseButton, _mouseX, _mouseY); } } return false; @@ -828,10 +786,15 @@ void FGLayeredInstrument::draw () { if (test()) { + float z = 0.1f; + float z_inc = 0.01; + bool vc = fgGetBool("/sim/virtual-cockpit"); for (int i = 0; i < (int)_layers.size(); i++) { glPushMatrix(); - if(!fgGetBool("/sim/virtual-cockpit")) - glTranslatef(0.0, 0.0, (i / 100.0) + 0.1); + if(!vc) { + glTranslatef(0.0, 0.0, z); + z += z_inc; + } _layers[i]->draw(); glPopMatrix(); } @@ -1049,7 +1012,29 @@ FGTextLayer::draw () text_renderer.start3f(0, 0, 0); _now.stamp(); - if (_now - _then > 100000) { + long diff = _now - _then; +#if 0 + // It would be nice to keep this #ifdef'd stuff for (04/18/2002 + + // a couple days) as I verify my solution to the panel text + // drawing problem is actually correct. -CLO + cout << "time diff = " << diff << endl; + if ( _now - _then < 0 ) { + cout << "Eeek, the past is now in the future!" << endl; + cout << "Now = " << _now.get_seconds() << " seconds " + << _now.get_usec() << "usecs" << endl; + cout << "Past = " << _then.get_seconds() << " seconds " + << _then.get_usec() << "usecs" << endl; + exit(-1); + } +#endif + if (diff > 100000 || diff < 0 ) { + // ( diff < 0 ) is a sanity check and indicates our time stamp + // difference math probably overflowed. We can handle a max + // difference of 35.8 minutes since the returned value is in + // usec. So if the panel is left off longer than that we can + // over flow the math with it is turned back on. This (diff < + // 0) catches that situation, get's us out of trouble, and + // back on track. recalc_value(); _then = _now; } @@ -1117,7 +1102,7 @@ FGTextLayer::Chunk::Chunk (const string &text, const string &fmt) : _type(FGTextLayer::TEXT), _fmt(fmt) { _text = text; - if (_fmt == "") + if (_fmt.empty()) _fmt = "%s"; } @@ -1125,7 +1110,7 @@ FGTextLayer::Chunk::Chunk (ChunkType type, const SGPropertyNode * node, const string &fmt, float mult) : _type(type), _fmt(fmt), _mult(mult) { - if (_fmt == "") { + if (_fmt.empty()) { if (type == TEXT_VALUE) _fmt = "%s"; else @@ -1138,12 +1123,13 @@ const char * FGTextLayer::Chunk::getValue () const { if (test()) { + _buf[0] = '\0'; switch (_type) { case TEXT: sprintf(_buf, _fmt.c_str(), _text.c_str()); return _buf; case TEXT_VALUE: - sprintf(_buf, _fmt.c_str(), _node->getStringValue().c_str()); + sprintf(_buf, _fmt.c_str(), _node->getStringValue()); break; case DOUBLE_VALUE: sprintf(_buf, _fmt.c_str(), _node->getFloatValue() * _mult); @@ -1191,3 +1177,4 @@ FGSwitchLayer::draw () // end of panel.cxx +