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:
Đặ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
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"
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)
Lấy thứ tự xoay đúng (lên / xuống trước, sau đó sang trái / phải)
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! ; ^)