Ecco alcuni suggerimenti sulla rotazione della fotocamera (mouselook). Dopo aver implementato una classe di telecamere da zero, ho scoperto che dovevo fare alcune modifiche aggiuntive per un buon comportamento rotazionale:
Ripristina le coordinate del mouse al centro dello schermo su ciascun fotogramma, in modo che il mouse non venga mai catturato dai bordi dello schermo
Mantenere il vettore "su" della fotocamera (non consentire il rollio) e ricalcolare il vettore "lateralmente"
Non consentire di guardare in alto oltre l'asse verticale + y o in basso oltre l'asse -y (troppo in alto / in basso)
Ottieni l'ordine delle rotazioni corretto (prima su / giù, poi a sinistra / a destra)
Rinormalizza i vettori "su", "mira" e "lateralmente" per ciascun fotogramma
Spero che tu possa usare un po 'di questo codice a tuo vantaggio:
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();
Nota che:
mouseAxisX e mouseAxisY sono definiti come +/- 1, a seconda che si desideri invertire il mouselook dell'asse x o y. Di solito i giochi offrono questa opzione almeno per l'asse verticale.
MIN_UPWARDS_TILT_DEG è definito come 1,0 gradi (quindi lo spettatore può guardare da -89 gradi verso il basso a +89 gradi verso l'alto, che sembra abbastanza convincente come una gamma verticale completa di 180 gradi - i 2 gradi mancanti agli estremi sono abbastanza trascurabili) .
camera.aim_, camera.right_ e camera.up_ sono ovviamente vettori 3D e il metodo rotateAboutAxis () che puoi mettere insieme da Wikipedia e da qualsiasi numero di fonti online. Y_AXIS è un vettore costante costante (0,1,0).
ASSERT_ORTHONORMAL () è un controllo di integrità solo in modalità debug, che non viene mai compilato in modalità ottimizzata / rilascio.
Ci scusiamo in anticipo per il codice in stile C ... poi di nuovo, qui stai ricevendo consigli da un ragazzo di nome Mediocritus! ; ^)