如何从 4x4 矩阵中获取 gluLookAt 参数

发布于 2024-08-21 22:25:06 字数 768 浏览 1 评论 0 原文

如果这是一个非常基本的 Matrix/OpenGl 问题,请提前抱歉。我遇到一种情况,我想转换为 4x4 矩阵,但不想使用 glMultMatrixf。我宁愿使用我在大多数其他翻译中使用的 gluLookAt 方法。从 4x4 矩阵获取所需的值是否像提取正确的列值一样简单?如果是,哪些列映射到哪些参数?

gluLookAt的签名:

void gluLookAt( GLdouble eyeX,
            GLdouble eyeY,
            GLdouble eyeZ,
            GLdouble centerX,
            GLdouble centerY,
            GLdouble centerZ,
            GLdouble upX,
            GLdouble upY,
            GLdouble upZ )

http://pyopengl.sourceforge.net/documentation/ref /glu/lookat.html http://www.opengl.org/wiki/GluLookAt_code

Sorry in advance if this is a really basic Matrix/OpenGl question. I have a situation where I have a 4x4 matrix that I would like to translate to, but don't want to use glMultMatrixf. I would rather use a gluLookAt method I've been using for most other translations. Is getting the values needed from the 4x4 matrix as simple as just pulling out the proper column values? If so which columns map to which parameters?

The signature of gluLookAt:

void gluLookAt( GLdouble eyeX,
            GLdouble eyeY,
            GLdouble eyeZ,
            GLdouble centerX,
            GLdouble centerY,
            GLdouble centerZ,
            GLdouble upX,
            GLdouble upY,
            GLdouble upZ )

http://pyopengl.sourceforge.net/documentation/ref/glu/lookat.html
http://www.opengl.org/wiki/GluLookAt_code

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

猛虎独行 2024-08-28 22:25:06

这些参数本身并不存在于矩阵中。矩阵是根据它们计算的。它是通过将三个顶点(眼睛、中心和“向上”)乘以当前视图矩阵而生成的。

OpenGL 红皮书(如果您还没有的话,您确实应该得到它)对此进行了更详细的解释。

The parameters don't exist in the matrix, per se. The matrix is calculated from them. It's produced by multiplying the three vertexes (eye, center, and "up") into the current view matrix.

The OpenGL Red Book (which you really should get, if you don't have it already) explains it in more detail.

三五鸿雁 2024-08-28 22:25:06

查看 DirectX 版本:

http://msdn.microsoft .com/en-gb/library/ee417299(VS.85).aspx

http://msdn.microsoft.com/en-gb/library/ee417302(VS.85).aspx

这些解释了外观是如何制作的。

由此您应该能够逆转该过程,或者至少确定它是否可能。

你到底想做什么?为什么你需要能够做到这一点?

这个问题给人的印象是您有一个 LookAt 矩阵,但您不想直接应用该矩阵,而是想提取参数以便将它们传递给 gluLookAt?

我只是想知道为什么你想从 LookAt 矩阵中提取参数?

check out the DirectX versions:

http://msdn.microsoft.com/en-gb/library/ee417299(VS.85).aspx

http://msdn.microsoft.com/en-gb/library/ee417302(VS.85).aspx

those explain how the look ats are made.

from that you should be able to reverse the process, or at least determine if it's possible.

What are you trying to do exactly? why do you need to be able to do this?

the question gives the impression that you have a lookAt matrix, but rather than just directly applying that matrix, you want to pull out the parameters just so you can pass them to gluLookAt?

I'm just interested to know why exactly you want to pull the parameters out of a lookAt matrix?

痴梦一场 2024-08-28 22:25:06

在这里你可以找到答案:
如何将 modelview 矩阵转换为 gluLookAt 参数?

粘贴这里的解决方案相同:

从任何 4x4 矩阵中,我们可以获得 gluLookAt 参数,即 CameraPos、CameraTarget、UpVector。
以下是从 ModelView 矩阵获取 CameraPos、CameraTarget、UpVector 的代码。

float modelViewMat[16];
glGetFloatv(GL_MODELVIEW_MATRIX, modelViewMat);

// Here instead of model view matrix we can pass any 4x4 matrix.
float params[9];
GetGluLookAtParameters(modelViewMat, params);

CameraPos.x = params[0];
CameraPos.y = params[1];
CameraPos.z = params[2];

CameraTarget.x = params[3];
CameraTarget.y = params[4];
CameraTarget.z = params[5];

UpVector.x = params[6];
UpVector.y = params[7];
UpVector.z = params[8];


void GetGluLookAtParameters(float* m, float* gluLookAtParams)
{
    VECTOR3D sideVector(m[0], m[4], m[8]);
    VECTOR3D upVector(m[1], m[5], m[9]);
    VECTOR3D forwardVector(-m[2], -m[6], -m[10]);

    sideVector.Normalize();
    upVector.Normalize();
    forwardVector.Normalize();

    float rotMat[16];
    memcpy(rotMat, m, 16*sizeof(float));
    rotMat[12] = rotMat[13] = rotMat[14] = rotMat[3] = rotMat[7] = rotMat[11] = 0.0f;
    rotMat[15] = 1.0f;
    float rotInvert[16];
    __gluInvertMatrixd(rotMat, rotInvert);

    float transMat[16];
    memset(transMat, 0, 16*sizeof(float));
    transMat[0] = transMat[5] = transMat[10] = transMat[15] = 1.0f;
    MultMat(rotInvert, m, transMat);

    gluLookAtParams[0] = -transMat[12];
    gluLookAtParams[1] = -transMat[13];
    gluLookAtParams[2] = -transMat[14];

    gluLookAtParams[3] = -transMat[12] + forwardVector.x;
    gluLookAtParams[4] = -transMat[13] + forwardVector.y;
    gluLookAtParams[5] = -transMat[14] + forwardVector.z;

    gluLookAtParams[6] = upVector.x;
    gluLookAtParams[7] = upVector.y;
    gluLookAtParams[8] = upVector.z;
}


void MultMat(float* a, float* b, float* result)
{
    result[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3];
    result[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3];
    result[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3];
    result[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3];

    result[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7];
    result[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7];
    result[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7];
    result[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7];

    result[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11];
    result[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11];
    result[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11];
    result[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11];

    result[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15];
    result[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15];
    result[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15];
    result[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15];
}


int __gluInvertMatrixd(const float src[16], float inverse[16])
{
    int i, j, k, swap;
    float t;
    GLfloat temp[4][4];

    for (i=0; i<4; i++)
        for (j=0; j<4; j++)
            temp[i][j] = src[i*4+j];

    for(int i=0;i<16;i++)
        inverse[i] = 0;
    inverse[0] = inverse[5] = inverse[10] = inverse[15] = 1.0f;

    for(i=0; i<4; i++)
    {
        swap = i;
        for (j = i + 1; j < 4; j++)
            if (fabs(temp[j][i]) > fabs(temp[i][i]))
                swap = j;

        if (swap != i) {
            //Swap rows.
            for (k = 0; k < 4; k++) {
                t = temp[i][k];
                temp[i][k] = temp[swap][k];
                temp[swap][k] = t;

                t = inverse[i*4+k];
                inverse[i*4+k] = inverse[swap*4+k];
                inverse[swap*4+k] = t;
            }
        }

        if (temp[i][i] == 0)
            return 0;

        t = temp[i][i];
        for (k = 0; k < 4; k++) {
            temp[i][k] /= t;
            inverse[i*4+k] /= t;
        }

        for (j = 0; j < 4; j++) {
            if (j != i) {
                t = temp[j][i];
                for (k = 0; k < 4; k++) {
                    temp[j][k] -= temp[i][k]*t;
                    inverse[j*4+k] -= inverse[i*4+k]*t;
                }
            }
        }
    }

    return 1;
}

Here you can find the answer:
how to convert modelview matrix to gluLookAt parameters?

or

Pasted the same solution here:

From any 4x4 matrix we can get gluLookAt parameters which are CameraPos, CameraTarget, UpVector.
Here is the code to get CameraPos, CameraTarget, UpVector from ModelView matrix.

float modelViewMat[16];
glGetFloatv(GL_MODELVIEW_MATRIX, modelViewMat);

// Here instead of model view matrix we can pass any 4x4 matrix.
float params[9];
GetGluLookAtParameters(modelViewMat, params);

CameraPos.x = params[0];
CameraPos.y = params[1];
CameraPos.z = params[2];

CameraTarget.x = params[3];
CameraTarget.y = params[4];
CameraTarget.z = params[5];

UpVector.x = params[6];
UpVector.y = params[7];
UpVector.z = params[8];


void GetGluLookAtParameters(float* m, float* gluLookAtParams)
{
    VECTOR3D sideVector(m[0], m[4], m[8]);
    VECTOR3D upVector(m[1], m[5], m[9]);
    VECTOR3D forwardVector(-m[2], -m[6], -m[10]);

    sideVector.Normalize();
    upVector.Normalize();
    forwardVector.Normalize();

    float rotMat[16];
    memcpy(rotMat, m, 16*sizeof(float));
    rotMat[12] = rotMat[13] = rotMat[14] = rotMat[3] = rotMat[7] = rotMat[11] = 0.0f;
    rotMat[15] = 1.0f;
    float rotInvert[16];
    __gluInvertMatrixd(rotMat, rotInvert);

    float transMat[16];
    memset(transMat, 0, 16*sizeof(float));
    transMat[0] = transMat[5] = transMat[10] = transMat[15] = 1.0f;
    MultMat(rotInvert, m, transMat);

    gluLookAtParams[0] = -transMat[12];
    gluLookAtParams[1] = -transMat[13];
    gluLookAtParams[2] = -transMat[14];

    gluLookAtParams[3] = -transMat[12] + forwardVector.x;
    gluLookAtParams[4] = -transMat[13] + forwardVector.y;
    gluLookAtParams[5] = -transMat[14] + forwardVector.z;

    gluLookAtParams[6] = upVector.x;
    gluLookAtParams[7] = upVector.y;
    gluLookAtParams[8] = upVector.z;
}


void MultMat(float* a, float* b, float* result)
{
    result[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3];
    result[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3];
    result[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3];
    result[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3];

    result[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7];
    result[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7];
    result[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7];
    result[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7];

    result[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11];
    result[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11];
    result[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11];
    result[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11];

    result[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15];
    result[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15];
    result[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15];
    result[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15];
}


int __gluInvertMatrixd(const float src[16], float inverse[16])
{
    int i, j, k, swap;
    float t;
    GLfloat temp[4][4];

    for (i=0; i<4; i++)
        for (j=0; j<4; j++)
            temp[i][j] = src[i*4+j];

    for(int i=0;i<16;i++)
        inverse[i] = 0;
    inverse[0] = inverse[5] = inverse[10] = inverse[15] = 1.0f;

    for(i=0; i<4; i++)
    {
        swap = i;
        for (j = i + 1; j < 4; j++)
            if (fabs(temp[j][i]) > fabs(temp[i][i]))
                swap = j;

        if (swap != i) {
            //Swap rows.
            for (k = 0; k < 4; k++) {
                t = temp[i][k];
                temp[i][k] = temp[swap][k];
                temp[swap][k] = t;

                t = inverse[i*4+k];
                inverse[i*4+k] = inverse[swap*4+k];
                inverse[swap*4+k] = t;
            }
        }

        if (temp[i][i] == 0)
            return 0;

        t = temp[i][i];
        for (k = 0; k < 4; k++) {
            temp[i][k] /= t;
            inverse[i*4+k] /= t;
        }

        for (j = 0; j < 4; j++) {
            if (j != i) {
                t = temp[j][i];
                for (k = 0; k < 4; k++) {
                    temp[j][k] -= temp[i][k]*t;
                    inverse[j*4+k] -= inverse[i*4+k]*t;
                }
            }
        }
    }

    return 1;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文