我应该如何安装第一人称相机?


12

我是一名初学者程序员,正在创建一个项目,该项目使我可以通过第一人称相机在房间中走动。到目前为止,我已经绘制了建筑物并继续进行,但现在我受困了,不知道如何制作第一人称视角的相机让我走来走去。

谁能指出我可以使用的相机类别或一些有用的代码?


Answers:


7

以下是有关相机旋转(mouselook)的一些技巧。从头开始天真地实现了相机类之后,我发现我必须做一些其他的调整才能获得良好的旋转性能:

  1. 将鼠标坐标重置为每一帧的屏幕中心,以使鼠标永远不会卡在屏幕边框上

  2. 保持相机的“向上”矢量(禁止滚动)并重新计算“横向”矢量

  3. 禁止在垂直+ y轴上方向上或向下-y轴下方(向上/向下太远)向上查找

  4. 正确获得旋转顺序(先向上/向下,然后向左/右)

  5. 每帧重新标准化“上”,“目标”和“侧身”矢量

希望您可以使用其中一些代码来发挥自己的优势:

    const int mouseDeltaX = mouseAxisX * (input.GetMouseX() - int(app.GetWidth()/2));
    const int mouseDeltaY = -mouseAxisY * (input.GetMouseY() - int(app.GetHeight()/2));  // mouse y-offsets are upside-down!

    // HACK:  reset the cursor pos.:
    app.SetCursorPosition(app.GetWidth()/2, app.GetHeight()/2);

    float lookRightRads = mouseDeltaX * CAMERA_ANGULAR_SPEED_DEG * DEG_TO_RAD;
    float lookUpRads    = mouseDeltaY * CAMERA_ANGULAR_SPEED_DEG * DEG_TO_RAD;

    // Limit the aim vector in such a way that the 'up' vector never drops below the horizon:
    static const float zenithMinDeclination = DEG_TO_RAD * MIN_UPWARDS_TILT_DEG;
    static const float zenithMaxDeclination = DEG_TO_RAD * (180.0f - MIN_UPWARDS_TILT_DEG);

    const float currentDeclination = std::acosf(camera.aim_.y_);  ///< declination from vertical y-axis
    const float requestedDeclination = currentDeclination - lookUpRads;

    // Clamp the up/down rotation to at most the min/max zenith:
    if(requestedDeclination < zenithMinDeclination)
        lookUpRads = currentDeclination - zenithMinDeclination;
    else if(requestedDeclination > zenithMaxDeclination)
        lookUpRads = currentDeclination - zenithMaxDeclination;

    // Rotate both the "aim" vector and the "up" vector ccw by 
    // lookUpRads radians within their common plane -- which should 
    // also contain the y-axis:  (i.e. no diagonal tilt allowed!)
    camera.aim_.rotateAboutAxis(camera.right_, lookUpRads);
    camera.up_.rotateAboutAxis(camera.right_, lookUpRads);
    ASSERT_ORTHONORMAL(camera.aim_, camera.up_, camera.right_);

    // Rotate both the "aim" and the "up" vector ccw about the vertical y-axis:
    // (again, this keeps the y-axis in their common plane, and disallows diagonal tilt)
    camera.aim_.rotateAboutAxis(Y_AXIS, -lookRightRads);
    camera.up_.rotateAboutAxis(Y_AXIS, -lookRightRads);
    camera.updateRightAxis();

注意:

mouseAxisX和mouseAxisY定义为+/- 1,具体取决于您是否希望将mouselook的x轴或y轴反转。通常,游戏至少在垂直轴上提供此选项。

MIN_UPWARDS_TILT_DEG的定义为1.0度(因此,允许观看者从-89度向下观看到+89度向上,这看起来非常令人信服,就像完整的180度垂直范围-极端情况下丢失的2度几乎可以忽略不计) 。

camera.aim_,camera.right_和camera.up_当然是3D向量,您可以从Wikipedia和任何数量的在线资源中整理出rotateAboutAxis()方法。Y_AXIS是固定常数(0,1,0)。

ASSERT_ORTHONORMAL()是仅调试模式的完整性检查,永远不会在优化/发布模式下进行编译。

预先为C样式的代码表示歉意...然后,再次,您从一个叫Mediocritus的家伙那里获得建议!; ^)


你在说什么?C风格的代码是黑客精神的基石!8
blissfreak

5

有几种解决方法(例如,请参见此处此处此处的教程,以及通过Google在互联网上提供的更多功能)。您可以在网上找到的资源中使用的技术可能略有不同(就D3D,XNA,OpenGL等而言),但是基本原理将是相同的:

  • 您的相机对象将保持其位置和方向,并保持另一对矢量,这些矢量与该方向并排形成相机坐标系的正交基础。
  • 您的相机的公共API公开了用于偏航,俯仰和有选择地围绕相机的基本向量滚动相机的方法-调整相机方向的操作将更新基本向量,以备后用。

您可以选择直接存储向量,或者根据需要和偏好每次都重新计算基础视图矩阵。该技术具有很大的灵活性,因此,如果您需要常规步骤之外的其他帮助,则可以使用更具体的查询发布新问题。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.