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++) {
FGPanelInstrument * instr = *current;
glPushMatrix();
glTranslated(x_offset, y_offset, 0);
glTranslated(instr->getXPos(), instr->getYPos(), 0);
instr->draw();
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);
}
// 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,6 +448,7 @@ FGPanel::setupVirtualCockpit()
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// Generate a "look at" matrix using OpenGL (!) coordinate
// conventions.
@ -492,41 +465,28 @@ 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);
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 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);
// 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