将FPS地面摄像机转换为FPS自由飞行摄像机

时间:2015-09-21 05:15:47

标签: c# opengl

我在OpenGL(openTk)项目中实现了一个摄像头

      //Move(0f, 0.1f, 0f); }    Forward
      //Move(-0.1f, 0f, 0f); }   Left
      //Move(0f, -0.1f, 0f); }   Back
      //Move(0.1f, 0f, 0f); }    Right
      //Move(0f, 0f, 0.1f); }    Up
      //Move(0f, 0f, -0.1f); }   Down
    public static void Move(float x, float y, float z)
    {  
        Vector3 offset = new Vector3();
        Vector3 forward = new Vector3((float)Math.Sin((float)Orientation.X), 0, (float)Math.Cos((float)Orientation.X));
        Vector3 right = new Vector3(-forward.Z,0,forward.X);
        offset += x * right;
        offset += y * forward;
        offset.Y += z;
        offset.NormalizeFast();
        offset = Vector3.Multiply(offset, MoveSpeed);
        Position += offset;
    }

在哪里"定位"是摄像机所朝向的x,y。 "位置"是相机在世界上的位置," MoveSpeed"漂浮。

这款相机效果很好。但它是基于地面的。我的意思是只有相机方向的x值才会影响移动方向。 y值没有。我想制作一个免费的飞行摄像机,所以如果你向上看并向前按,摄像机将飞向空中。

我尝试将前向音译改为:

Vector3 forward = new Vector3((float)Math.Sin((float)Orientation.X), (float)Math.Sin((float)Orientation.Y), (float)Math.Cos((float)Orientation.X));

这部分工作,相机现在可以飞到空中。但它不对,无论距离多远多少,相机都会向前移动相同的数量"你倾斜它。上升并没有取代一些前锋,而是将其加入其中。

我希望这种解释有意义。

由于

2 个答案:

答案 0 :(得分:1)

您可以这样做: 首先从forward获取Orientation向量(您也可以将它用于您的Camera.LookAt)

public Vector3 getForward(Vector2 Orientation)
{  
    Vector3 forward = new Vector3(0, 1, 0);
    //X axis rotation
    forward.Z = (float)Math.Sin((float)Orientation.Y);
    forward.Y = (float)Math.Cos((float)Orientation.Y);
    //Z axis rotation
    forward.X = forward.Y*(float)Math.Sin((float)Orientation.X);
    forward.Y = forward.Y*(float)Math.Cos((float)Orientation.X);

    return forward;
}

然后移动相机:

public void Move(float horizontal, float strafe)
{  
    Vector3 forward=getForward(Orientation);
    //forward vector projected on XoY plane and rotated 90 degrees
    Vector3 leftXoY = new Vector3(-forward.y ,forward.x,0);

    Vector3 moveDirection = Vector3.Multiply(forward,horizontal)+Vector3.Multiply(leftXoY,strafe);
    moveDirection.Normalize();

    Position += Vector3.Multiply(moveDirection,MoveSpeed);
}

因此,如果您致电move(1,-1);,则会向前移动相机(沿forward向量)并向右移动。

答案 1 :(得分:0)

我在摆弄了很长时间之后找到了解决方案。我不知道这是否是一种有效的方式,但它确实有效。

 public static void Move(float x, float y, float z)
    {
        Vector3 CameraTargetVector;
        CameraTargetVector.X = (float)(Math.Sin((float)Orientation.X) * Math.Cos((float)Orientation.Y));
        CameraTargetVector.Y = (float)Math.Sin((float)Orientation.Y);
        CameraTargetVector.Z = (float)(Math.Cos((float)Orientation.X) * Math.Cos((float)Orientation.Y));
        Vector3 offset = new Vector3();
        offset += x * new Vector3(-CameraTargetVector.Z, 0, CameraTargetVector.X);
        offset += y * CameraTargetVector;
        offset.Y += z;
        offset.NormalizeFast();
        Position += Vector3.Multiply(offset, MoveSpeed);
    }