Voici quelques conseils sur la rotation de la caméra (mouselook). Après avoir implémenté naïvement une classe de caméra à partir de zéro, j'ai trouvé que je devais faire quelques ajustements supplémentaires pour un bon comportement en rotation:
Réinitialisez les coordonnées de la souris au centre de l'écran sur chaque image, afin que la souris ne se coince jamais sur les bordures de l'écran
Maintenir le vecteur "up" de la caméra (interdire le roulement) et recalculer le vecteur "sideways"
Interdit de regarder vers le haut au-delà de l'axe vertical + y, ou vers le bas au-delà de l'axe -y (trop haut / bas)
Obtenez l'ordre des rotations correct (haut / bas d'abord, puis gauche / droite)
Renormaliser les vecteurs "haut", "viser" et "latéralement" à chaque image
J'espère que vous pourrez utiliser une partie de ce code à votre avantage:
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();
Notez que:
mouseAxisX et mouseAxisY sont définis comme étant +/- 1, selon que vous souhaitez inverser le regard de la souris sur les axes x ou y. Habituellement, les jeux offrent cette option au moins pour l'axe vertical.
MIN_UPWARDS_TILT_DEG est défini comme étant de 1,0 degré (de sorte que le spectateur est autorisé à regarder de -89 degrés vers le bas à +89 degrés vers le haut, ce qui ressemble de manière assez convaincante à une plage verticale complète de 180 degrés - les 2 degrés manquants aux extrêmes sont assez négligeables) .
camera.aim_, camera.right_ et camera.up_ sont bien sûr des vecteurs 3D, et la méthode rotationAboutAxis () vous permet de bricoler à partir de wikipedia et de nombreuses sources en ligne. Y_AXIS est un vecteur constant constant (0,1,0).
ASSERT_ORTHONORMAL () est une vérification d'esprit uniquement en mode débogage, qui n'est jamais compilée en mode optimisé / de libération.
Toutes mes excuses à l'avance pour le code de style C ... encore une fois, ici, vous suivez les conseils d'un gars nommé Mediocritus! ; ^)