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:
parent
b9d1cad6f2
commit
f477a4603b
1 changed files with 24 additions and 64 deletions
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue