3D 相机移动和旋转
3D camera movement and rotation
我有一个包含三个等距框的 3D 场景,我希望相机能够围绕相机目标旋转并沿任何方向移动,通常就像 3D 建模应用程序中的相机,但我的设置仅适用当我的相机目标位于原点时,每当我在任何方向移动相机时,我的相机位置和相机目标都会正确转换到新位置,但是我的相机仍然围绕场景的原点旋转
下图显示了我的相机目标和坐标系原点的旋转
下图显示我的相机目标向左移动,但相机相对于坐标系的原点旋转
以下是我在 x/y 平面上进行相机旋转和移动的代码:
if (event.type == SDL_MOUSEMOTION && leftMouseButtonPressed == true)
{
New.x = event.button.x;
New.y = event.button.y;
delta = New - prev;
if (delta.x != 0) {
angleX = delta.x / 2.0f;
rotMat = glm::mat4(1);
rotMat = glm::rotate(rotMat, glm::radians(angleX), up);
cameraUp = glm::normalize(glm::vec4(up, 1) * rotMat);
cameraRight = glm::normalize(glm::cross(cameraUp, cameraDirection));
cameraPos = rotMat * glm::vec4(cameraPos, 1) ;
cameraDirection = glm::normalize(cameraPos - cameraTarget);
camera = glm::lookAt(cameraPos, cameraTarget, up);
}
if (event.type == SDL_MOUSEMOTION && rightMouseButtonPressed == true)
{
New.x = event.button.x;
New.y = event.button.y;
delta = New - prev;
if (delta.x != 0) {
delta.x /= 10.0f;
translateMat = glm::mat4(1);
translateMat = glm::translate(translateMat, cameraRight * delta.x);
cameraPos = translateMat * glm::vec4(cameraPos, 1);
cameraTarget = translateMat * glm::vec4(cameraTarget, 1) ;
camera = glm::lookAt(cameraPos, cameraTarget , cameraUp);
}
累加水平和垂直角度(偏航角和俯仰角);每次这些变化:
- 使用
yawPitchRoll
函数创建并缓存旋转矩阵 cameraRot
。
使用此矩阵计算并缓存相机的正面和向上方向:
cameraDirection = cameraRot * glm::vec3(-1.0f, 0.0f, 0.0f);
cameraUp = cameraRot * glm::vec3(0.0f, 1.0f, 0.0f);
除了浮点精度问题,这些都已经标准化。
然后可以使用以下方法根据目标计算相机的位置:
cameraPos = cameraTarget - cameraDistance * cameraDirection;
其中cameraDistance
是目标到相机的距离。
我有一个包含三个等距框的 3D 场景,我希望相机能够围绕相机目标旋转并沿任何方向移动,通常就像 3D 建模应用程序中的相机,但我的设置仅适用当我的相机目标位于原点时,每当我在任何方向移动相机时,我的相机位置和相机目标都会正确转换到新位置,但是我的相机仍然围绕场景的原点旋转
下图显示了我的相机目标和坐标系原点的旋转
下图显示我的相机目标向左移动,但相机相对于坐标系的原点旋转
以下是我在 x/y 平面上进行相机旋转和移动的代码:
if (event.type == SDL_MOUSEMOTION && leftMouseButtonPressed == true)
{
New.x = event.button.x;
New.y = event.button.y;
delta = New - prev;
if (delta.x != 0) {
angleX = delta.x / 2.0f;
rotMat = glm::mat4(1);
rotMat = glm::rotate(rotMat, glm::radians(angleX), up);
cameraUp = glm::normalize(glm::vec4(up, 1) * rotMat);
cameraRight = glm::normalize(glm::cross(cameraUp, cameraDirection));
cameraPos = rotMat * glm::vec4(cameraPos, 1) ;
cameraDirection = glm::normalize(cameraPos - cameraTarget);
camera = glm::lookAt(cameraPos, cameraTarget, up);
}
if (event.type == SDL_MOUSEMOTION && rightMouseButtonPressed == true)
{
New.x = event.button.x;
New.y = event.button.y;
delta = New - prev;
if (delta.x != 0) {
delta.x /= 10.0f;
translateMat = glm::mat4(1);
translateMat = glm::translate(translateMat, cameraRight * delta.x);
cameraPos = translateMat * glm::vec4(cameraPos, 1);
cameraTarget = translateMat * glm::vec4(cameraTarget, 1) ;
camera = glm::lookAt(cameraPos, cameraTarget , cameraUp);
}
累加水平和垂直角度(偏航角和俯仰角);每次这些变化:
- 使用
yawPitchRoll
函数创建并缓存旋转矩阵cameraRot
。 使用此矩阵计算并缓存相机的正面和向上方向:
cameraDirection = cameraRot * glm::vec3(-1.0f, 0.0f, 0.0f); cameraUp = cameraRot * glm::vec3(0.0f, 1.0f, 0.0f);
除了浮点精度问题,这些都已经标准化。
然后可以使用以下方法根据目标计算相机的位置:
cameraPos = cameraTarget - cameraDistance * cameraDirection;
其中
cameraDistance
是目标到相机的距离。