XNA 摄像机绕 Z 轴旋转

本文关键字:旋转 摄像机 XNA | 更新日期: 2023-09-27 18:37:26

我正在为3D游戏创建一个相机。相机由以下变量组成:

static Vector3 cameraLookAt = new Vector3(0, 0, 0);
static Vector3 cameraPosition;
static float cameraZoom = 25; // Field of view 
const int cameraZoomNear = 3; // The furthest the camera can zoom in 
const int cameraZoomFar = 45; // The furthest the camera can zoom out 
static float cameraPitch; // Amount to change the pitch 
static float cameraRotation; // Amount to change the rotation
默认情况下,"cameraLookAt"位于(0,0,0),"

cameraPosition"位于(0,0,10),这意味着相机位于"cameraLookAt"位置的正上方,可以鸟瞰下方的物体(红色绿色和蓝色xyz平面测试对象)

"cameraLookAt"可以沿x轴和y轴移动,然后相对于"cameraLookAt"位置以及"cameraPitch"和"cameraRotate"的当前值计算"cameraPosition"

目前,您可以围绕 x/y 轴精细移动,并将摄像机的俯仰更改为从鸟瞰图变为地面视图。我遇到的问题是让相机旋转工作。

当旋转值被改变时,它只有在音高发生变化时才有任何影响 - 从程序启动时的默认值(直接向下看"cameraLookAt")

当值发生变化时,您可以围绕 Z 轴旋转,但视图也会滚动,因此当您旋转 180 度时,相机也已滚动 180 度,并且您的视图是颠倒的。

下面是计算"

cameraPosition"位置的代码,我确定这些行中的固定行。

        cameraPosition = cameraLookAt + new Vector3(0, 0, 10);
        Vector3 temp = Vector3.Normalize(cameraPosition - cameraLookAt); //creates a unit length vector that points in the direction from 'lookAt' to 'position'
        cameraPosition = Vector3.Transform(cameraPosition - cameraLookAt, Matrix.CreateRotationX(cameraPitch)) + cameraLookAt;
        cameraPosition = Vector3.Transform(cameraPosition - cameraLookAt, Matrix.CreateRotationZ(cameraRotation)) + cameraLookAt;
        view = Matrix.CreateLookAt(cameraPosition, cameraLookAt, new Vector3(0.0f, 1.0f, 0.0f));
        projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(cameraZoom), graphics.GraphicsDevice.Viewport.AspectRatio, nearClip, farClip);

另外,这是我发现的一个问答,可以帮助我首先编写代码XNA旋转相机周围的CreateLookAt "目标"

XNA 摄像机绕 Z 轴旋转

旋转偏移量而不更改其长度,然后将其添加到相机位置。

我认为应该是这样的:

   offset = new Vector3(0, 0, 10);
   Vector3 rotatedOffset = Vector3.Transform( offset, 
                                      Matrix.CreateRotationX(cameraPitch) 
                                      * Matrix.CreateRotationZ(cameraRotation));
   cameraPosition = cameraLookAt + rotatedOffset;