1
0
Fork 0

Patch from Andy Ross:

Actually, I think I'm off the hook here; the problem is pre-existing.
What's happening is that the x/y offsets enter the modelview matrix at
line 346 in the current panel.cxx.  But note that the same
transformation also occurs before each instrument rendered at line
403.  What's happening is that the instruments are double-translated
relative to the background.

Unless I'm not understanding something, the one inside the instrument
render loop looks unnecessary.  Removing it fixes the issue and
doesn't cause any bugs that I can find.  It also fixes a bug where you
could scroll the instruments on top of the 3D panel, where the offsets
are supposed to be ignored. :)

Attached is a new panel.cxx which fixes that bug, and substantially
simplifies the virtual panel code (the matrix inversion that I thought
was needed wasn't, but there were some offsetting scale bugs that hid
the problem).
This commit is contained in:
david 2002-03-04 13:27:53 +00:00
parent b9d1cad6f2
commit f477a4603b

View file

@ -400,7 +400,6 @@ FGPanel::update (GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh)
for ( ; current != end; current++) { for ( ; current != end; current++) {
FGPanelInstrument * instr = *current; FGPanelInstrument * instr = *current;
glPushMatrix(); glPushMatrix();
glTranslated(x_offset, y_offset, 0);
glTranslated(instr->getXPos(), instr->getYPos(), 0); glTranslated(instr->getXPos(), instr->getYPos(), 0);
instr->draw(); instr->draw();
glPopMatrix(); glPopMatrix();
@ -419,52 +418,25 @@ FGPanel::update (GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh)
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 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 void
FGPanel::setupVirtualCockpit() FGPanel::setupVirtualCockpit()
{ {
int i; int i;
FGViewer* view = globals->get_current_view(); FGViewer* view = globals->get_current_view();
// Corners for the panel quad. These numbers put a "standard" // Generate corners for the panel quad. Put the top edge of the
// panel at 1m from the eye, with a horizontal size of 60 degrees, // panel 1m in and 6 degrees down from the forward direction, and
// and with its center 5 degrees down. This will work well for // make the whole thing 60 degrees wide. In principle, these
// most typical screen-space panel definitions. In principle, // should be settable per-panel, so that you can have lots of
// these should be settable per-panel, so that you can have lots // panel objects plastered about the cockpit in realistic
// of panel objects plastered about the cockpit in realistic
// positions and orientations. // positions and orientations.
float DY = .0875; // tan(5 degrees) float a[3], b[3], c[3];
float a[] = { -0.5773503, -0.4330172 - DY, -1 }; // bottom left float pw = tan(30*SGD_DEGREES_TO_RADIANS);
float b[] = { 0.5773503, -0.4330172 - DY, -1 }; // bottom right float ph = 2 * pw * (float)_height/(float)_width;
float c[] = { -0.5773503, 0.4330172 - DY, -1 }; // top left 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 // A standard projection, in meters, with especially close clip
// planes. // planes.
@ -476,6 +448,7 @@ FGPanel::setupVirtualCockpit()
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
glLoadIdentity();
// Generate a "look at" matrix using OpenGL (!) coordinate // Generate a "look at" matrix using OpenGL (!) coordinate
// conventions. // conventions.
@ -492,41 +465,28 @@ FGPanel::setupVirtualCockpit()
glTranslatef(a[0], a[1], a[2]); glTranslatef(a[0], a[1], a[2]);
// Generate a matrix to translate unit square coordinates from the // Generate a matrix to translate unit square coordinates from the
// panel to real world coordinates. Use a basis for the panel // panel to real world coordinates. Use a transposed basis for
// quad and invert. Note: this matrix is relatively expensive to // the panel quad. Note: this matrix is relatively expensive to
// compute, and is invariant. Consider precomputing and storing // compute, and is invariant. Consider precomputing and storing
// it. Also, consider using the plib vector math routines, so the // it. Also, consider using the plib vector math routines, so the
// reuse junkies don't yell at me. (Fine, I hard-coded a cross // reuse junkies don't yell at me. (Fine, I hard-coded a cross
// product. Just shoot me and be done with it.) // 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++) u[i] = b[i] - a[i]; // U = B - A
for(i=0; i<3; i++) v[i] = c[i] - a[i]; // V = C - 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[0] = u[1]*v[2] - v[1]*u[2]; // W = U x V
w[1] = u[2]*v[0] - v[2]*u[0]; w[1] = u[2]*v[0] - v[2]*u[0];
w[2] = u[0]*v[1] - v[0]*u[1]; 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. m[0] = u[0]; m[4] = v[0]; m[8] = w[0]; m[12] = 0; // |Ux Vx Wx|
glm[0] = m[0]; glm[4] = m[1]; glm[8] = m[2]; glm[12] = 0; m[1] = u[1]; m[5] = v[1]; m[9] = w[1]; m[13] = 0; // m = |Uy Vy Wy|
glm[1] = m[3]; glm[5] = m[4]; glm[9] = m[5]; glm[13] = 0; m[2] = u[2]; m[6] = v[2]; m[10] = w[2]; m[14] = 0; // |Uz Vz Wz|
glm[2] = m[6]; glm[6] = m[7]; glm[10] = m[8]; glm[14] = 0; m[3] = 0; m[7] = 0; m[11] = 0; m[15] = 1;
glm[3] = 0; glm[7] = 0; glm[11] = 0; glm[15] = 1; glMultMatrixf(m);
glMultMatrixf(glm);
// Finally, a scaling factor to convert the 1024x768 range the // Finally, a scaling factor to map the panel's width and height
// panel uses to a unit square mapped to the panel quad. // to the unit square.
glScalef(1./1024, 1./768, 1); glScalef(1./_width, 1./_height, 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);
// Now, turn off the Z buffer. The panel code doesn't need // Now, turn off the Z buffer. The panel code doesn't need
// it, and we're using different clip planes anyway (meaning we // it, and we're using different clip planes anyway (meaning we