对于学校项目,我们正在修改我们在早期课程中构建的游戏引擎,以支持Oculus Rift。然而,我们一直遇到的一个问题是,当我们移动鼠标时,世界似乎在旋转。在正常的第一人称场景中,人们可以毫无困难地使用相机移动,但在我们的引擎中,随机移动鼠标最终会使世界颠倒过来。用圆圈移动鼠标会再次拉直它。
我猜这是因为,由于相机是静止的,轴的位置永远不会改变,这反过来会导致不必要的旋转。有没有办法补偿这种旋转,例如通过确定一个任意轴并围绕它旋转?或者问题是完全不同的,我们是否完全在错误的区域寻找?
我们不允许在渲染器之外使用DirectX方法,因此我们自己进行所有矩阵乘法。
编辑:这是我们用来旋转相机的代码。它包含在两个类中。首先,Camera.cpp中的旋转代码(我们之前的作业要求我们处理相机中的输入):
void Camera::rotateByX(float angle)
{
float rotX = -1.0f * angle / 1000.0f;
xAngle = angle;
//This is the calculation with the Rotion Matrix values of X
matrixRotateX[5] = cos(rotX);
matrixRotateX[6] = sin(rotX);
matrixRotateX[9] = -sin(rotX);
matrixRotateX[10] = cos(rotX);
//The for loop to multiply the matrices
float matrix[16];
for(int i = 0; i < 16; ++i)
{
matrix[i] = matrixMultiply(changeMatrix, matrixRotateX)[i];
}
setChangeMatrix(matrix);
};
void Camera::rotateByY(float angle)
{
float rotY = -1.0f * angle / 1000.0f;
//This is the calculation with the Rotion Matrix values of Y
matrixRotateY[0] = cos(rotY);
matrixRotateY[2] = -sin(rotY);
matrixRotateY[8] = sin(rotY);
matrixRotateY[10] = cos(rotY);
//The for loop Multiply the matrices
float matrix[16];
for(int i = 0; i < 16; ++i)
{
matrix[i] = matrixMultiply(changeMatrix, matrixRotateY)[i];
}
setChangeMatrix(matrix);
};
矩阵乘法发生在这个怪物:
float* Camera::matrixMultiply(float matrix1[16], float matrix2[16])
{
if(matrix1 != NULL && matrix2 != NULL)
{
float matrix[16];
float coord = (matrix1[0] * matrix2[0] + matrix1[1] * matrix2[4] + matrix1[2] * matrix2[8] + matrix1[3] * matrix2[12]);
matrix[0] = coord;
coord = (matrix1[0] * matrix2[1] + matrix1[1] * matrix2[5] + matrix1[2] * matrix2[9] + matrix1[3] * matrix2[13]);
matrix[1] = coord;
coord = (matrix1[0] * matrix2[2] + matrix1[1] * matrix2[6] + matrix1[2] * matrix2[10] + matrix1[3] * matrix2[14]);
matrix[2] = coord;
coord = (matrix1[0] * matrix2[3] + matrix1[1] * matrix2[7] + matrix1[2] * matrix2[11] + matrix1[3] * matrix2[15]);
matrix[3] = coord;
coord = (matrix1[4] * matrix2[0] + matrix1[5] * matrix2[4] + matrix1[6] * matrix2[8] + matrix1[7] * matrix2[12]);
matrix[4] = coord;
coord = (matrix1[4] * matrix2[1] + matrix1[5] * matrix2[5] + matrix1[6] * matrix2[9] + matrix1[7] * matrix2[13]);
matrix[5] = coord;
coord = (matrix1[4] * matrix2[2] + matrix1[5] * matrix2[6] + matrix1[6] * matrix2[10] + matrix1[7] * matrix2[14]);
matrix[6] = coord;
coord = (matrix1[4] * matrix2[3] + matrix1[5] * matrix2[7] + matrix1[6] * matrix2[11] + matrix1[7] * matrix2[15]);
matrix[7] = coord;
coord = (matrix1[8] * matrix2[0] + matrix1[9] * matrix2[4] + matrix1[10] * matrix2[8] + matrix1[11] * matrix2[12]);
matrix[8] = coord;
coord = (matrix1[8] * matrix2[1] + matrix1[9] * matrix2[5] + matrix1[10] * matrix2[9] + matrix1[11] * matrix2[13]);
matrix[9] = coord;
coord = (matrix1[8] * matrix2[2] + matrix1[9] * matrix2[6] + matrix1[10] * matrix2[10] + matrix1[11] * matrix2[14]);
matrix[10] = coord;
coord = (matrix1[8] * matrix2[3] + matrix1[9] * matrix2[7] + matrix1[10] * matrix2[11] + matrix1[11] * matrix2[15]);
matrix[11] = coord;
coord = (matrix1[12] * matrix2[0] + matrix1[13] * matrix2[4] + matrix1[14] * matrix2[8] + matrix1[15] * matrix2[12]);
matrix[12] = coord;
coord = (matrix1[12] * matrix2[1] + matrix1[13] * matrix2[5] + matrix1[14] * matrix2[9] + matrix1[15] * matrix2[13]);
matrix[13] = coord;
coord = (matrix1[12] * matrix2[2] + matrix1[13] * matrix2[6] + matrix1[14] * matrix2[10] + matrix1[15] * matrix2[14]);
matrix[14] = coord;
coord = (matrix1[12] * matrix2[3] + matrix1[13] * matrix2[7] + matrix1[14] * matrix2[11] + matrix1[15] * matrix2[15]);
matrix[15] = coord;
return matrix;
}
else
{
Logger::getInstance()->logWarning("Matrix is invalid.", __LINE__, "Camera");
}
};
然后,在Scene.cpp文件中,通过以下方法调用这些乘法的结果:
void Scene::updateMatrices()
{
//Change the matrices of all the Entities
for (unsigned int i = 0; i < entities.size(); ++i)
{
float matrix[16];
for (int j = 0; j < 16; ++j)
{
matrix[j] = entities[i]->matrixMultiply(camera->getChangeMatrix())[j];
}
entities[i]->setMatrix(matrix);
}
//Change the matrices of the Terrain
float trMatrix[16];
for (int i = 0; i < 16; ++i)
{
trMatrix[i] = terrain->matrixMultiply(camera->getChangeMatrix())[i];
}
terrain->setMatrix(trMatrix);
//Change the matrices of the Skybox
float skyMatrix[16];
for (int i = 0; i < 12; ++i)
{
skyMatrix[i] = skybox->matrixMultiply(camera->getChangeMatrix())[i];
}
//The skybox does not move. Therefore we set its translation values to zero.
//This is necessary because the change matrix does contain trnaslation values.
skyMatrix[12] = 0.0f;
skyMatrix[13] = 0.0f;
skyMatrix[14] = 0.0f;
skyMatrix[15] = 1.0f;
skybox->setMatrix(skyMatrix);
//Resets the Change Matrix of the Camera
camera->resetMatrix();
};
从这段代码可以清楚地看出,我们更像是英国的Top Gear:雄心勃勃但却很垃圾。我希望从这个混乱中可以学到任何东西。提前谢谢!