Come devo implementare una fotocamera in prima persona?


12

Sono un programmatore principiante e sto creando un progetto che mi permette di camminare per le stanze tramite una videocamera in prima persona. Finora ho gli edifici disegnati e accesi, ma ora sono bloccato e non so come realizzare una macchina fotografica in prima persona per permettermi di camminare.

Qualcuno potrebbe indirizzarmi verso una classe di telecamere che potrei usare o un codice utile?


Risposte:


7

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:

  1. 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

  2. Mantenere il vettore "su" della fotocamera (non consentire il rollio) e ricalcolare il vettore "lateralmente"

  3. Non consentire di guardare in alto oltre l'asse verticale + y o in basso oltre l'asse -y (troppo in alto / in basso)

  4. Ottieni l'ordine delle rotazioni corretto (prima su / giù, poi a sinistra / a destra)

  5. 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! ; ^)


Di cosa stai parlando? Il codice C-style è la pietra angolare dello spirito degli hacker! 8-)
blissfreak

5

Esistono diversi modi per farlo (vedi tutorial qui , qui e qui ad esempio, con molti altri disponibili su Internet via Google). La tecnologia utilizzata nelle risorse che è possibile trovare online può variare leggermente (in termini di D3D, XNA, OpenGL, eccetera), ma i principi sottostanti saranno gli stessi:

  • l'oggetto della videocamera mantiene la sua posizione e la sua direzione e, facoltativamente, un'altra coppia di vettori che, insieme alla direzione, formano una base ortogonale per il sistema di coordinate della videocamera.
  • L'API pubblica della fotocamera espone metodi per imbardata, inclinazione e facoltativamente ruotare la videocamera attorno ai suoi vettori di base: l'atto di regolare l'orientamento della videocamera aggiornerà i vettori di base per un uso successivo.

Puoi scegliere di memorizzare direttamente i vettori o ricalcolare la matrice di visualizzazione sottostante ogni volta che desideri e preferisci. C'è molta flessibilità nella tecnica, quindi se hai bisogno di aiuto oltre quei passaggi generali potresti voler pubblicare una nuova domanda con una query più specifica.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.