opengl场景中的面向对象

时间:2014-05-21 20:47:26

标签: opengl

我很难从场景中的物体中获得正确的方向。对象在标准笛卡尔坐标中以与我定义场景相同的单位定义。

然后我用以下代码定义我的场景矩阵:

void SVIS_SetLookAt (double eyePos[3], double center[3], double up[3])
{
  // Determine the new n
  double vN[3] = {eyePos[0] - center[0], eyePos[1] - center[1], eyePos[2] - center[2]};
  // Don't I need to normalize the above?

  // Determine the new up by crossing witht he Up Vector. 
  double vU[3];
  MATH_crossproduct(up, vN, vU);
  MATH_NormalizeVector(vN);
  MATH_NormalizeVector(vU);

  // Determine V by crossing n and u...
  double vV[3];
  MATH_crossproduct(vN, vU, vV);
  MATH_NormalizeVector(vV);

  // Create the model view matrix.
  double modelView[16] = {
    vU[0],                   vV[0],                  vN[0],                 0,
    vU[1],                   vV[1],                  vN[1],                 0,
    vU[2],                   vV[2],                  vN[2],                 0,
//    -MATH_Dotd(eyePos, vU), -MATH_Dotd(eyePos, vV), -MATH_Dotd(eyePos, vN), 1
    0,                       0,                      0,                     1
  };

  // Load the modelview matrix. The model view matrix shoudl already be active.
  glLoadMatrixd(modelView);
}

我试图显示n-1个对象,使每个对象面向它前面的对象,不包括未显示的第一个对象。因此,对于每个对象,我将向上,向右和向前矢量定义为:

lal_to_ecef(curcen, pHits->u); // up vector is our position normalized
MATH_subtractVec3D((SVN_VEC3D*) prevcenter, (SVN_VEC3D*) curcen, (SVN_VEC3D*) pHits->f);
MATH_NormalizeVector(pHits->u);
MATH_NormalizeVector(pHits->f);
MATH_crossproduct(pHits->u, pHits->f, pHits->r);
MATH_NormalizeVector(pHits->r);
MATH_crossproduct(pHits->f, pHits->r, pHits->u);
MATH_NormalizeVector(pHits->u);

然后我继续使用以下代码显示每个对象:

double p[3] = {pHits->cen[0] - position[0], 
               pHits->cen[1] - position[1],
               pHits->cen[2] - position[2]};


glPushMatrix();
SVIS_LookAt(pHits->u, pHits->f, pHits->r, p);
glCallList(G_svisHitsListId);
glPopMatrix();

void SVIS_LookAt (double u[3], double f[3], double l[3], double pos[3])
{
  double model[16] = {
    l[0], u[0], f[0], 0,
    l[1], u[1], f[1], 0,
    l[2], u[2], f[2], 0, 
    pos[0], pos[1], pos[2], 1
  };

  glMultMatrixd(model);
}

我希望这适用于任何对象,使得输出将是在笛卡尔坐标系中定义的任何内容将出现在给定的点上,使得它指向前进的对象0,1,0和来自定义对象的0,-1,0将在屏幕上垂直对齐。我所看到的(通过使用简单的矩形作为要显示的对象)是对象始终围绕前轴旋转。

有谁可以指出我在这里做错了什么?

[编辑]

我已经显示了一个没有平移的轴网格,方法是将三个矢量乘以一个标量并将其加到/减去中心点。这样做,轴就像我期望的那样对齐。覆盖上述对象显示对象不以相同的方式对齐。对象空间向前,向右和向上向量与我想要的世界空间向量之间是否存在关系?关于我的旋转平移矩阵,我是否完全偏离了标记?

2 个答案:

答案 0 :(得分:1)

  

你在这里有冲突;该矩阵的一部分是转置的​​并且是其中的一部分   这是正确的......你有第4列正确但你的左上角3x3   矩阵被转置。 3x3矩阵的每一列(该数组中的行)   16双)应该是你的一个轴。它应该是:   l [0],l [1],l [2],0,u [0],u [1],u [2],0,f [0],f [1],f [2],0 ,   POS [0],POS [1],POS [2],1。 - Andon M. Coleman

这已经死了。谢谢Andon。

答案 1 :(得分:0)

使用' lookat'从头开始构建一个全新的模型视图矩阵。坦率地说,每个对象的实现都是疯狂的(或者至少会让你发疯)。你正在做的就等于试图通过一组总是在固定位置的物体来建造一个场景,并不断地重新定位一个摄像机以从不同的角度捕捉它们。

应该调用一次外观样式函数来设置相机(模型视图矩阵的视图部分)位置,然后您应该使用矩阵堆栈来定位场景中的对象(模型视图矩阵的模型部分) )。这就是为什么它称为 modelview 矩阵,而不仅仅是视图矩阵。

在代码方面,它看起来像这样

// Set up camera position
SVIS_LookAt(....);

for (int i = 0; i < n; ++i) {
  glPushMatrix();
  // move the object to it's location relative to the world coordinate system
  glTranslate(...);
  // rotate the object to have the correct orientation
  glRotate(...);
  // render the geometry
  glCallList(...);
  glPopMatrix();
}

当然,这假设一切都在世界坐标中定义了它的位置。如果您有一个对象层次结构,那么您需要下降到glCallListglPopMatrix之间的对象子项,以便相对于其父对象应用它们的位置。