Jak uchronić mój aparat FPS korzystający z Quaternion przed przechyleniem i zepsuciem?

17

Używam aparatu podobnego do FPS i wykorzystuje on czwartorzędy. Ale ilekroć spróbuję spojrzeć w górę, a następnie na boki, przechyla się, a czasem może się odwrócić. Jak mogę to naprawić?

Aeodyn
źródło
3
(Samo odpowiedzieć za 7 godzin) ...
Aeodyn

Odpowiedzi:

16

Możesz rozłożyć czwartorzęd na zestaw kątów odchylenia / pochylenia / przechyłu, ale zwykle jest to przesada.

Zamiast tworzyć takie czwartorzędy w ten sposób:

cameraOrientation = cameraOrientation * framePitch * frameYaw;

Spróbuj tego:

cameraOrientation = framePitch * cameraOrientation * frameYaw;

Wówczas nigdy nie będzie generować przechylenia / przechyłu i jest to równoważne z przechowywaniem odchylenia i pochylenia osobno

ltjax
źródło
3
To. Właśnie tego szukałem. Rozwiązałem mój problem w jednej linijce. Ładny!
aardvarkk
1
Czy framePitchi frameYaw floatrodzaje? Byłbym również wdzięczny za wyjaśnienie pierwszego zdania.
sirdank
1
@sirdank cameraOrientation, framePitchi frameYawto wszystkie kwaterniony (każdy quaternion wynosi 4 pływaków lub dwuosobowe).
Dan.
8

To był problem, który miałem przez jakiś czas i nie mogłem znaleźć żadnych odpowiedzi, więc pomyślałem, że opublikuję go tutaj.

To jest właściwie dość proste. Najprawdopodobniej wykonujesz rotacje w następujący sposób:

currentDirection * newRotation;

Ale robienie tego w ten sposób też nie działa.

newRotation * currentDirection;

Co musisz zrobić, to zrobić to w pierwszej kolejności dla obrotów w górę iw dół, a w drugiej kolejności dla obrotów w bok.

Dla mnie było tak:

        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;

Z tego powodu, pierwszy sposób ma obrót w stosunku do bieżącego kierunku na boki, który chcesz w górę i w dół, ale nie chcesz tego dla obrotów na boki, dlatego potrzebna jest druga kolejność.

Aeodyn
źródło
Musiałem poczekać 7 godzin, aby odpowiedzieć na własne ...
Aeodyn,
przepraszam, czy możesz to wyjaśnić za pomocą niektórych zrzutów ekranu? „pierwsze zamówienie” i „drugie zamówienie” jest trochę mylące - dzięki!
Atav32
Podczas pracy z Quaternions kolejność ma znaczenie, jak zawsze w przypadku obracania 3D. W moim przykładzie „Direction * = newRotation” jest taki sam jak „Direction = Direction * newRotation”. Ale przy obrotach w lewo i w prawo chcemy tego na odwrót. To sprawia, że ​​nie zależy to od przechyłu w górę i w dół, co powoduje przechylenie.
Aeodyn
Och, myślałem, że chodziło o to, że omijał blokadę gimbala, a wszystkie obroty były niezależne, ale mogłem źle odczytać podręcznik. Czyli dla wyjaśnienia, czy mówisz, że jeśli odwrócisz kolejność transformacji obrotu, możesz zapobiec przechyleniu kamery? A może ręcznie ustawiasz transformację przechyłu i pochylenia na 0 podczas obracania odchylenia?
Atav32,
5

W przypadku kamery FPS zwykle nie chcesz się przechylać i są ograniczone do skoku +/- 90 stopni, więc po prostu śledzę bieżący stan za pomocą kątów odchylenia i pochylenia. Pełna moc czwartorzędów nie jest w tym naprawdę pomocna.

Nadal możesz przekonwertować kąty odchylenia / skoku na i od czwartorzędów, na wypadek gdybyś chciał przejść między kamerą FPS a kamerami animowanymi przy użyciu interpolacji klatek kluczowych czwartorzędu lub czegoś podobnego.

Nathan Reed
źródło
0

Inną prostą sztuczką jest umieszczenie kamery w GameObject, a obrót Yaw kontroluje obiekt gry, podczas gdy kamera podrzędna jest skonfigurowana ze współrzędnymi Pitch:

playerCameraHolder.transform.Rotate(0, rotationYaw, 0);
playerCamera.transform.Rotate(rotationPitch, 0, 0);
Victor S.
źródło