นี่คือเคล็ดลับบางอย่างเกี่ยวกับการหมุนกล้อง (mouselook) หลังจากใช้คลาสกล้องตั้งแต่เริ่มแรกฉันพบว่าฉันต้องปรับแต่งเพิ่มเติมสองสามครั้งเพื่อพฤติกรรมการหมุนที่ดี:
รีเซ็ตพิกัดของเมาส์ไปที่กึ่งกลางของหน้าจอในแต่ละเฟรมเพื่อไม่ให้เมาส์ติดกับขอบของหน้าจอ
รักษาเวกเตอร์ "up" ของกล้อง (ไม่อนุญาตให้ม้วน) และคำนวณ "เวกเตอร์" ด้านข้างใหม่
ไม่อนุญาตให้มองผ่านแกนแนวตั้ง + y หรือเลื่อนผ่านแกน -y (ไกลเกินไปขึ้น / ลง)
รับลำดับการหมุนที่ถูกต้อง (ขึ้น / ลงก่อนจากนั้นซ้าย / ขวา)
ปรับภาพเวกเตอร์ "up", "aim" และ "Sideways" ใหม่แต่ละเฟรม
หวังว่าคุณสามารถใช้รหัสนี้เพื่อประโยชน์ของคุณ:
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 ขึ้นอยู่กับว่าคุณต้องการให้ x หรือ y แกน mouselook กลับด้าน โดยปกติเกมจะเสนอตัวเลือกนี้อย่างน้อยแกนแนวตั้ง
MIN_UPWARDS_TILT_DEG ถูกกำหนดให้เป็น 1.0 องศา (ดังนั้นผู้ชมจะได้รับอนุญาตให้ดูจาก -89 องศาลงไปที่ +89 องศาขึ้นไปซึ่งดูเหมือนจะค่อนข้างมั่นใจเหมือนช่วงแนวตั้งเต็ม 180 องศา - ที่หายไป 2 องศาที่ปลายสุดนั้นค่อนข้างเล็กน้อย) .
camera.aim_, camera.right_ และ camera.up_ แน่นอนว่าเป็นเวกเตอร์ 3 มิติและวิธี rotateAboutAxis () ที่คุณสามารถใช้ร่วมกันจากวิกิพีเดียและแหล่งข้อมูลออนไลน์จำนวนเท่าใดก็ได้ Y_AXIS เป็นค่าคงที่เวกเตอร์คงที่ (0,1,0)
ASSERT_ORTHONORMAL () เป็นการตรวจสอบสติในโหมดดีบักเท่านั้นซึ่งไม่เคยถูกคอมไพล์ในโหมดออปติไมซ์ / รีลีส
ขออภัยล่วงหน้าสำหรับโค้ดสไตล์ C ... จากนั้นอีกครั้งที่นี่คุณกำลังรับคำแนะนำจากผู้ชายที่ชื่อ Mediocritus! ; ^)