模型lookAt Matrix - C++,OpenGL

Cha*_*son 5 c++ math 3d vector matrix

我成功地为相机实现了lookAt矩阵,因为有很多来源描述它.

我一直试图将其从相机外观转换为模型外观.我似乎无法让它工作,我认为我对如何构建矩阵有一点误解.我假设我不需要更改模型的翻译来查看某个点,因为它的位置应保持不变.

首先,这是相关的代码.lookAtRadians函数应该查看在相同的referance框架中指定的点和它的平移(即 - position = direction).但是,有一些问题,我将通过屏幕截图显示.它不检查direction.y()是1.0f还是-1.0f,但这是微不足道的.

void TransformMatrix3D::lookAtRadians(float atX, float atY, float atZ, float toZRadians)
{
    Vector3D direction(atX - x(), atY - y(), atZ - z());
    direction.normalize();

    Vector3D up(0.0f, 1.0f, 0.0f);

    Vector3D right(direction.crossProduct(up));
    right.normalize();
    up = direction.crossProduct(right);

    mMatrix[0] = right.x();
    mMatrix[4] = right.y();
    mMatrix[8] = right.z();
    mMatrix[1] = up.x();
    mMatrix[5] = up.y();
    mMatrix[9] = up.z();
    mMatrix[2] = direction.x();
    mMatrix[6] = direction.y();
    mMatrix[10] = direction.z();
}
Run Code Online (Sandbox Code Playgroud)

以下是交叉产品和规范化函数,以防它们不正确.

Vector3D Vector3D::crossProduct(const Vector3D& rightVector) const
{
    const float NEW_X(y() * rightVector.z() - z() * rightVector.y());
    const float NEW_Y(z() * rightVector.x() - x() * rightVector.z());
    const float NEW_Z(x() * rightVector.y() - y() * rightVector.x());

    return Vector3D(NEW_X, NEW_Y, NEW_Z);
}


void Vector3D::normalize()
{
    float length(x() * x() + y() * y() + z() * z());

    if(fabs(length) == 1.0f)
        return;

    length = 1.0f / sqrt(length);
    moveTo(x() * length, y() * length, z() * length);
}
Run Code Online (Sandbox Code Playgroud)

以下是一些描述我的问题的截图.白色球体表示lookAt点.

我创建了一个沿Z轴向下转换-10.0f的立方体(这将设置mMatrix[12],mMatrix[13]mMatrix[14]分别设置为0.0f,0.0f,-10.0f.矩阵的其余部分是标识.我已经检查过这种情况)我会用于证明问题.

截图:无旋转

如果我沿着X和Y轴移动lookAt点,lookAt似乎正常工作.

屏幕截图:X轴(Y旋转)

屏幕截图:Y轴(X旋转)

但是,当我组合两者时(即移动lookAt点使X和Y都不是0.0f),应用了一些Z旋转,这不应该发生,因为UP x DIRECTION应该总是导致RIGHT.y()是0.0f.将使用toZRadians(尚未实现)Z旋转.

屏幕截图:添加了Z旋转

另外我发现如果然后我将lookAt点向下移动到Y轴,模型仍然遵循lookAt点,但它实际上围绕全局X轴旋转(或至少等于那个).

截图:全局X旋转

现在,当lookAt点移动到-Z时,模型具有正确的Y旋转,但它的X旋转被反转.我在这一点上检查了我的向量,我发现UP.y()是负的,这是不可能的(它可以是0.0f,但不是负的),因为DIRECTION和RIGHT应该总是以相同的方式缠绕(即顺时针方向)方向右).UP.y()可能是负面的唯一方法是,如果RIGHT实际上是LEFT.

屏幕截图:倒置X旋转

模型仍然围绕全局X轴旋转,就像lookAt点为+ Z时一样.

截图:全局X旋转(lookAt -Z)

正如我所提到的,这可能是对矩阵工作方式的误解,但它可能是另一回事.我环顾了几天,我似乎只能找到基于相机的lookAt功能.解释矩阵中包含的轴的任何来源都会导致本文中提供的代码.

Cha*_*son 5

啊,我发现了问题.这么简单我忽略了它.

我的矩阵:

mMatrix[0] = right.x();
mMatrix[4] = right.y();
mMatrix[8] = right.z();
mMatrix[1] = up.x();
mMatrix[5] = up.y();
mMatrix[9] = up.z();
mMatrix[2] = direction.x();
mMatrix[6] = direction.y();
mMatrix[10] = direction.z();
Run Code Online (Sandbox Code Playgroud)

在内存中定义列主要.它应该是:

mMatrix[0] = right.x();
mMatrix[1] = right.y();
mMatrix[2] = right.z();
mMatrix[4] = up.x();
mMatrix[5] = up.y();
mMatrix[6] = up.z();
mMatrix[8] = direction.x();
mMatrix[9] = direction.y();
mMatrix[10] = direction.z();
Run Code Online (Sandbox Code Playgroud)

而且效果很好.非常愚蠢的错误,我甚至没想过要检查.这也解释了轴上的奇怪倒置.