我在子弹物理学中要求使用Opengl,其中我有模型视图矩阵,但需要通过调用gluLookAt获得相同的矩阵。提前谢谢。
答案 0 :(得分:1)
从任何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;
}