İşte kamera döndürme (mouselook) ile ilgili bazı ipuçları. Bir kamera sınıfını sıfırdan uyguladıktan sonra, iyi dönme davranışı için birkaç ek ayar yapmak zorunda kaldım:
Fare koordinatlarını her karede ekranın ortasına sıfırlayın, böylece fare asla ekran kenarlıklarına takılmaz
Kameranın "yukarı" vektörünü (ruloya izin verme) koruyun ve "yana doğru" vektörü yeniden hesaplayın
Dikey + y eksenini geçmeye veya -y eksenini geçmeye izin verme (çok yukarı / aşağı)
Dönüş sırası doğru olsun (önce yukarı / aşağı, sonra sola / sağa)
Her kareyi "yukarı", "amaç" ve "yana doğru" vektörleri yeniden normalleştirin
Umarım bu kodlardan bazılarını kendi yararınıza kullanabilirsiniz:
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();
Bunu not et:
mouseAxisX ve mouseAxisY, x veya y eksenli fare görüntüsünün ters çevrilmesini isteyip istemediğinize bağlı olarak +/- 1 olarak tanımlanır. Genellikle oyunlar bu seçeneği en azından dikey eksen için sunar.
MIN_UPWARDS_TILT_DEG 1.0 derece olarak tanımlanır (bu nedenle izleyicinin -89 dereceden aşağıya doğru +89 dereceye kadar bakmasına izin verilir, bu da tam 180 derece dikey bir aralığa oldukça ikna edici görünür - aşırı uçlarda eksik 2 derece oldukça önemsizdir) .
camera.aim_, camera.right_ ve camera.up_, elbette 3B vektörler ve rotateAboutAxis () yöntemiyle wikipedia'dan ve istediğiniz sayıda çevrimiçi kaynaktan birlikte toparlayabilirsiniz. Y_AXIS sabit bir sabit (0,1,0) vektörüdür.
ASSERT_ORTHONORMAL (), hiçbir zaman optimize edilmiş / serbest bırakma modunda derlenmeyen bir hata ayıklama modu yalnızca sağlık kontrolüdür.
C tarzı kod için şimdiden özür dileriz ... o zaman yine Mediocritus adlı bir adamdan tavsiye alıyorsunuz! ; ^)