Matrix 3D DirectX-如何使用静态相机进行正确旋转?

Matrix 3D DirectX-如何使用静态相机进行正确旋转?,matrix,rotation,directx,Matrix,Rotation,Directx,对于一个学校项目,我们正在修改我们在早期课程中构建的游戏引擎,以支持Oculus Rift。然而,我们一直面临的一个问题是,当我们移动鼠标时,世界似乎在旋转。在一个普通的第一人称场景中,一个人可以毫无困难地用相机四处移动,但是在我们的引擎中,随机移动鼠标最终会把世界颠倒过来。在圆圈中移动鼠标将使其再次变直 我的猜测是,这是因为,由于相机是静态的,轴的位置永远不会改变,这反过来会导致不必要的旋转。有没有办法补偿这种旋转,例如通过确定任意轴并围绕该轴旋转?或者问题完全是另外一回事,我们是不是找错了方

对于一个学校项目,我们正在修改我们在早期课程中构建的游戏引擎,以支持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);
};
然后,在文件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:雄心勃勃但毫无价值。我希望能从这场混乱中学到什么。提前谢谢

请演示如何旋转相机。这段代码可能包含一些错误。不要纠正错误,你应该试着一开始就不要犯错误。Oculus Rift在学校项目中?不错!无论如何,我们需要看到相关的代码。程序员不应该猜测,但我的猜测是相机逻辑、数学函数或CPU-GPU数据交换,如恒定缓冲区更新。一般建议:广泛使用调试器:监视变量、设置条件断点和测试,直到找到旋转出错的地方。您可以尝试将自己的数学实现临时替换为某种已知的工作实现,例如DirectX数学。还可以查看DirectX数学源代码以获得灵感,这是一个只包含标题的库,所有函数都是内联的。
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();
};