Làm thế nào tôi nên thực hiện một máy ảnh đầu tiên?


12

Tôi là một lập trình viên mới bắt đầu và tôi đang tạo một dự án cho phép tôi đi bộ xung quanh các phòng thông qua máy ảnh của người đầu tiên. Cho đến nay, tôi có các tòa nhà được vẽ và bật, nhưng bây giờ tôi bị mắc kẹt và không biết làm thế nào để tạo ra một máy ảnh đầu tiên để cho phép tôi đi bộ xung quanh.

Bất cứ ai có thể chỉ cho tôi một lớp máy ảnh tôi có thể sử dụng, hoặc một số mã hữu ích?


Câu trả lời:


7

Dưới đây là một số lời khuyên về xoay camera (mouselook). Sau khi ngây thơ thực hiện một lớp máy ảnh từ đầu, tôi thấy tôi phải thực hiện một vài điều chỉnh bổ sung để có hành vi xoay tốt:

  1. Đặt lại tọa độ chuột về giữa màn hình trên mỗi khung hình để chuột không bao giờ bị bắt trên viền màn hình

  2. Duy trì vectơ "lên" của máy ảnh (cuộn không cho phép) và tính toán lại vectơ "sang một bên"

  3. Không cho phép nhìn lên qua trục dọc + y hoặc xuống qua trục -y (quá xa lên / xuống)

  4. Lấy thứ tự xoay đúng (lên / xuống trước, sau đó sang trái / phải)

  5. Tái chuẩn hóa các vectơ "lên", "nhắm" và "đi ngang" mỗi khung

Hy vọng rằng bạn có thể sử dụng một số mã này để lợi thế của bạn:

    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();

Lưu ý rằng:

mouseAxisX và mouseAxisY được xác định là +/- 1, tùy thuộc vào việc bạn muốn mouselook trục x hoặc y đảo ngược. Thông thường các trò chơi cung cấp tùy chọn này ít nhất là cho trục dọc.

MIN_UPWARDS_TILT_DEG được xác định là 1,0 độ (vì vậy người xem được phép nhìn từ -89 độ xuống dưới +89 độ trở lên, trông khá thuyết phục như một phạm vi dọc 180 độ đầy đủ - 2 độ bị thiếu ở các thái cực là không đáng kể) .

máy ảnh Y_AXIS là một vectơ cố định (0,1,0).

ASSERT_ORTHONORMAL () là kiểm tra độ sạch chỉ ở chế độ gỡ lỗi, không bao giờ được biên dịch trong chế độ phát hành / tối ưu hóa.

Xin lỗi trước về mã kiểu C ... sau đó, một lần nữa, ở đây bạn đang nhận lời khuyên từ một chàng trai tên Mediocritus! ; ^)


Bạn đang nói về cái gì vậy? Mã kiểu C là nền tảng của tinh thần hacker! 8-)
blissfreak

5

Có một số cách để làm điều này ( ví dụ, xem hướng dẫn ở đây , ở đâyở đây , với nhiều hơn có sẵn trên Internet thông qua Google). Công nghệ được sử dụng trong các tài nguyên bạn có thể tìm thấy trực tuyến có thể thay đổi đôi chút (về D3D, XNA, OpenGL, et cetera), nhưng các nguyên tắc cơ bản sẽ giống nhau:

  • đối tượng máy ảnh của bạn duy trì vị trí và hướng của nó, và tùy ý một cặp vectơ khác, dọc theo hướng, tạo thành cơ sở trực giao cho hệ tọa độ của máy ảnh.
  • API công khai của máy ảnh của bạn hiển thị các phương pháp để ngáp, ném và tùy ý xoay camera xung quanh các vectơ cơ sở của nó - hành động điều chỉnh hướng camera sẽ cập nhật các vectơ cơ sở cho lần sử dụng tiếp theo.

Bạn có thể chọn lưu trữ các vectơ trực tiếp hoặc tính toán lại ma trận khung nhìn bên dưới mỗi lần, khi bạn cần và thích. Kỹ thuật này có rất nhiều tính linh hoạt, vì vậy nếu bạn cần trợ giúp ngoài các bước chung đó, bạn có thể muốn đăng một câu hỏi mới với một truy vấn cụ thể hơn.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.