Come impedire alla mia videocamera FPS che utilizza Quaternion di inclinarsi e incasinare?


17

Sto usando una fotocamera simile a FPS e utilizza quaternioni. Ma ogni volta che provo a guardare in alto e poi lateralmente, si inclina e talvolta può capovolgere. Come posso risolvere questo problema?


3
(Risponderà da solo in 7 ore) ...
Aeodyn,

Risposte:


16

Potresti scomporre il tuo quaternione in una serie di angoli di imbardata / beccheggio / rollio, ma di solito è eccessivo.

Invece di comporre i tuoi quaternioni in questo modo:

cameraOrientation = cameraOrientation * framePitch * frameYaw;

Prova questo:

cameraOrientation = framePitch * cameraOrientation * frameYaw;

Quindi non genererà mai inclinazione / rollio ed equivale a memorizzare separatamente imbardata e inclinazione


3
Questo. Questo e 'esattamente quello che stavo cercando. Risolto il mio problema in una linea. Bello!
aardvarkk,

1
Sono framePitche frameYaw floattipi? Inoltre, sarei grato per alcuni chiarimenti sulla tua prima frase.
sirdank,

1
@sirdank cameraOrientation, framePitche frameYawsono tutti quaternioni (ogni quaternione è composto da 4 float o doppi).
Dan,

8

Questo è un problema che ho avuto per un po ', e non sono riuscito a trovare alcuna risposta, quindi ho pensato di pubblicarlo qui.

In realtà è abbastanza semplice. Il modo in cui molto probabilmente stai facendo le rotazioni è come questo:

currentDirection * newRotation;

Ma farlo in questo modo non funziona neanche.

newRotation * currentDirection;

Quello che devi fare è farlo nel primo ordine per le rotazioni su e giù e nel secondo ordine per le rotazioni laterali.

Per me è stato così:

        if (keyboard.IsKeyDown(Keys.Up))
            Direction = Direction * Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), TurnSpeed);
        if (keyboard.IsKeyDown(Keys.Down))
            Direction = Direction * Quaternion.CreateFromAxisAngle(new Vector3(-1, 0, 0), TurnSpeed);
        if (keyboard.IsKeyDown(Keys.Left))
            Direction = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), TurnSpeed) * Direction;
        if (keyboard.IsKeyDown(Keys.Right))
            Direction = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, -1), TurnSpeed) * Direction;

Per un motivo, il primo modo ha la rotazione relativa all'attuale direzione laterale, che si desidera per su e giù, ma che non si desidera per le rotazioni laterali, motivo per cui è necessario il secondo ordine.


Ho dovuto aspettare 7 ore per rispondere al mio ...
Aeodyn,

scusa, puoi spiegarlo con alcuni screenshot? "primo ordine" e "secondo ordine" sono un po 'confusi - grazie!
Atav32,

Quando si lavora con i Quaternioni, l'ordine conta, come sempre con le rotazioni 3D. Nel mio esempio, "Direction * = newRotation" è uguale a "Direction = Direction * newRotation". Ma, con rotazioni sinistra e destra, lo vogliamo al contrario. Ciò non dipende dall'inclinazione su e giù, che provoca il rollio.
Aeodyn,

Oh, anche se il punto dei quarternioni era che evitava il blocco del gimbal e le rotazioni erano tutte indipendenti, ma potrei aver letto male il libro di testo. Quindi, per chiarire, stai dicendo che se inverti l'ordine delle trasformazioni di rotazione, puoi impedire l'inclinazione della videocamera? Oppure stai impostando manualmente le trasformazioni di rollio e beccheggio su 0 quando ruoti l'imbardata?
Atav32,

5

Per una fotocamera FPS di solito non si desidera il rollio e sono limitati a un angolo di +/- 90 gradi, quindi terrei solo traccia dello stato corrente usando gli angoli di imbardata e di imbardata. Il pieno potere dei quaternioni non è davvero utile per questo.

È comunque possibile convertire gli angoli di imbardata / inclinazione da e verso i quaternioni nel caso in cui si desideri eseguire la transizione tra la videocamera FPS e le videocamere animate utilizzando l'interpolazione del fotogramma chiave quaternione o qualcosa del genere.


0

Un altro semplice trucco è quello di mettere la telecamera in un GameObject e far controllare la rotazione dell'imbardata all'oggetto del gioco, mentre la camera del bambino è configurata con le coordinate Pitch:

playerCameraHolder.transform.Rotate(0, rotationYaw, 0);
playerCamera.transform.Rotate(rotationPitch, 0, 0);
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.