opengl场景中的对象定向

opengl场景中的对象定向,opengl,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]};

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

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

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与定义的对象将在屏幕上垂直对齐。相反,我看到的是(通过使用简单的矩形作为要显示的对象),对象始终围绕前向轴旋转

有人能指出我做错了什么吗

[编辑]


我已经显示了一个轴网格,通过将三个向量乘以一个标量并将其加/减到中心点,而不进行平移。这样,轴就会像我预期的那样对齐。覆盖上面描述的对象会显示对象不以相同的方式对齐。对象空间向前、向右和向上向量与我缺少的所需世界空间向量之间是否存在关系?我是否完全偏离了旋转-平移矩阵的标准?

坦白地说,为每个对象使用“lookat”实现从头开始构建一个全新的modelview矩阵是疯狂的(或者至少会让你疯狂)。你所做的无异于试图构建一个场景,通过拥有一组始终位于固定位置的对象,并不断重新定位摄影机以从不同角度捕捉它们

应调用lookat style函数一次以设置摄影机(modelview矩阵的视图部分)位置,然后应使用矩阵堆栈在场景中定位对象(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();
}
//设置摄像机位置
SVIS_注视(……);
对于(int i=0;i
当然,这是假设所有东西都在世界坐标系中定义了它的位置。如果您有一个对象层次结构,那么您需要在
glCallList
glPopMatrix
之间的子对象中找到一个对象,以便相对于其父对象应用它们的位置


你在这里很矛盾;该矩阵的一部分是转置的,另一部分是 这是正确的。。。您的第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, 位置[0],位置[1],位置[2],位置1.-安东·M·科尔曼


这是完全正确的。谢谢你,安顿。

你在这里很矛盾;那个矩阵的一部分是转置的,一部分是正确的。。。第4列正确,但左上角的3x3矩阵已转置。3x3矩阵的每一列(16
double
数组中的行)都应该是您的一个轴。它应该是:
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
。谢谢你,这就是我所缺少的。旋转矩阵现在工作正常。由于场景轴是用于本次讨论的任意轴,我无法在没有大量工作的情况下以euler角度描述对象的方向。然而,我可以用几乎不太多的工作量来确定对象的前向、上向和右向向量,因此我需要一种利用这些向量的方法。另外,据我所知,glTranslate和glRotate调用被贬低(正如我在示例中使用的drawlist一样,但这是一个简化的测试用例,将被删除),我无法继续使用具有不确定保存期限的东西。所有矩阵函数都被弃用,包括glPushMatrix、glPopMatrix、glLoadMatrix,等等。如果您正在使用其中任何一个,那么您正在使用较旧版本的OpenGL,或者在允许使用它们的兼容模式下工作。如果其中任何一个可用,则所有可用。