• Nie Znaleziono Wyników

FAKTYWNE OSIE OBROTOWE

W dokumencie Ruch. Podstawy algorytmów ruchu (Stron 142-145)

Częstym problemem związanym z pojazdami poruszającymi się w trzech wymiarach jest ich oś obrotu.

Niezależnie od tego, czy są to statki kosmiczne, czy statki powietrzne, mają one różne prędkości obrotu dla każdej z trzech osi: przechylenie, pochylenie i odchylenie.

Na podstawie zachowania samolotu zakładamy, że przechylenie jest szybsze niż pochylenie, które jest szybsze niż odchylenie. Jeśli jednostka porusza się po linii prostej i musi odchylić się, najpierw przetoczy się tak, aby jej kierunek do góry wskazywał w kierunku skrętu, a następnie może pochylić się w górę, aby skręcić we właściwym kierunku. Tak pilotuje się samoloty i jest to fizyczna konieczność narzucona przez konstrukcję skrzydła i powierzchni sterowych. W kosmosie nie ma takiego ograniczenia, ale chcemy dać graczowi poczucie, że statek podlega prawom fizycznym. Szybkie odchylenie wygląda niewiarygodnie, więc mamy tendencję do narzucania tej samej zasady: przechylenie i nachylenie powodują odchylenie. Większość samolotów nie przechyla się na tyle daleko, aby cały obrót można było wykonać przez przechylenie. W konwencjonalnych samolotach lecących na poziomie, użycie tylko pochylenia do wykonania skrętu w prawo wymagałoby przechylenia o n radianów. Spowodowałoby to gwałtowne opadanie dziobu samolotu w kierunku ziemi, wymagające znacznej kompensacji, aby uniknąć utraty zakrętu (w lekkim samolocie byłaby to beznadziejna próba). Zamiast przechylać lokalny wektor w górę samolotu, tak aby wskazywał bezpośrednio na zakręt, ustawiamy go lekko pod kątem.

Połączenie pochylenia i odchylenia zapewnia zwrot. Wielkość przechylenia zależy od prędkości: im szybszy samolot, tym większe przechyły. Boeing 747 lecący na ląd może przechylić się tylko o | radianów (15 °); F-22 Raptor może przechylić się o | radianów (45 °), lub ten sam obrót w X-Wing może wynosić Λ (75 °). Większość jednostek poruszających się w trzech wymiarach ma oś „góra-dół”. Widać to zarówno w kosmicznych strzelankach 3D, jak iw symulatorach samolotów. Na przykład świat macierzysty miał wyraźny kierunek w górę iw dół, w którym statek będzie się orientował, gdy się nie poruszał. Kierunek w górę jest istotny, ponieważ statki poruszające się w linii prostej, inne niż w kierunku do góry, mają tendencję do ustawiania się w jednej linii. Kierunek w górę jednostki wskazuje tak blisko do góry, na ile pozwala na to kierunek podróży. Znowu jest to konsekwencja fizyki samolotu:

skrzydła samolotu są zaprojektowane tak, aby wytwarzać siłę nośną w górę, więc jeśli nie utrzymasz lokalnego kierunku do góry, w końcu spadniesz z nieba. Prawdą jest, że na przykład podczas walki psów statek będzie się toczyć podczas podróży w linii prostej, aby uzyskać lepszy widok, ale jest to niewielki efekt. W większości przypadków powodem rzutu jest wykonanie skrętu. Możliwe jest przeniesienie całego tego przetwarzania do siłownika, aby obliczyć najlepszy sposób zmiany pochylenia, przechylenia i odchylenia w oparciu o fizyczne właściwości samolotu. Jeśli piszesz sztuczną inteligencję do sterowania fizycznie wymodelowanym samolotem, być może będziesz musiał to zrobić. Jednak w

większości przypadków jest to przesada. Interesuje nas posiadanie wrogów, którzy po prostu wyglądają dobrze. Możliwe jest również dodanie zachowania sterującego, które wymusza trochę przechylenia, gdy występuje obrót. Działa to dobrze, ale ma tendencję do opóźniania. Piloci będą rzucać przed rzuceniem, a nie później. Jeśli zachowanie sterowe polega na monitorowaniu prędkości obrotowej statku i odpowiednim kołysaniu, występuje opóźnienie. Jeśli zachowanie układu kierowniczego działa w każdej ramie, nie stanowi to większego problemu. Jeśli zachowanie występuje tylko kilka razy na sekundę, może wyglądać bardzo dziwnie. Oba powyższe podejścia opierają się na technikach już omówionych w tym rozdziale, więc nie będziemy ich tutaj wracać. Istnieje inne podejście, używane w niektórych grach lotniczych i wielu strzelankach kosmicznych, które udaje obroty w oparciu o liniowy ruch statku. Ma zalety polegające na tym, że reaguje natychmiastowo i nie obciąża układu kierowniczego, ponieważ jest to etap przetwarzania końcowego. Może być zastosowany do sterowania 2 Λ D, dając iluzję pełnego obrotu 3D.

Algorytm

Ruch jest obsługiwany za pomocą normalnych sposobów kierowania. Zachowujemy dwie wartości orientacyjne. Jedna jest częścią danych kinematycznych i jest używana przez układ kierowniczy, a druga jest obliczana do wyświetlania. Ten algorytm oblicza drugą wartość na podstawie danych kinematycznych. Najpierw znajdujemy prędkość pojazdu: wielkość wektora prędkości. Jeśli prędkość wynosi zero, to orientacja kinematyczna jest używana bez modyfikacji. Jeśli prędkość jest poniżej ustalonego progu, wynik pozostałej części algorytmu zostanie zmieszany z orientacją kinematyczną.

Powyżej progu algorytm ma pełną kontrolę. Gdy spada poniżej progu, następuje mieszanka orientacji algorytmicznej i orientacji kinematycznej, aż przy prędkości zerowej używana jest orientacja kinematyczna. Przy zerowej prędkości ruch pojazdu nie może spowodować żadnej rozsądnej orientacji;

to się nie rusza. Będziemy więc musieli użyć orientacji generowanej przez układ kierowniczy. Próg i mieszanie są po to, aby upewnić się, że orientacja pojazdu nie przeskakuje, gdy zwalnia do zatrzymania.

Jeśli Twoja aplikacja nigdy nie ma stacjonarnych pojazdów (na przykład samolotów bez możliwości zawisu), to połączenie można usunąć. Algorytm generuje orientację wyjściową w trzech etapach. Ten wynik można następnie połączyć z orientacją kinematyczną, jak opisano powyżej. Po pierwsze, orientacja pojazdu względem wektora w górę (jego orientacja 2D w układzie 2 Λ D) jest określana na podstawie orientacji kinematycznej. Nazwijmy tę wartość 9. Po drugie, przechylenie pojazdu można znaleźć, patrząc na składową prędkości pojazdu w kierunku do góry. Orientacja wyjścia ma kąt nad horyzontem określony przez:

gdzie v jest jego prędkością (pobraną z danych kinematycznych), a u jest wektorem jednostkowym w kierunku do góry. Po trzecie, przechylenie pojazdu można znaleźć, patrząc na prędkość obrotu pojazdu wokół kierunku do góry (tj. Obrót 2D w układzie 2ΛD). Rolkę podaje:

gdzie r jest rotacją, a k jest stałą, która kontroluje, ile powinno być chudych. Kiedy obrót jest równy fc, pojazd będzie miał przechylenie | radianów. Korzystając z tego równania, pojazd nigdy nie osiągnie przechyłu π radianów, ale bardzo szybki obrót spowoduje bardzo strome przechyły. Orientację wyjścia oblicza się, łącząc trzy obroty w kolejności 9, 0, yjr

Pseudo kod

Po wdrożeniu algorytm ma następującą strukturę:

def getFakeOrientation ( kinematic , speedThreshold , rollScale) :

# Find the speed

speed = kinematic.velocity.length ( )

# Find the blend factors if speed < speedThreshold :

# Check for all kinematic if speed == 0:

return kinematic.orientation el se:

kinematicBlend = speed / speedThreshold fakeBlend = 1.0 - kinematicBlend

el se:

# We ' re completely faked fakeBlend = 1.0

kinematicBlend = 0.0

# Find the y-axis orientation yaw = kinematic .orientation

# Find the t i l t

pitch = asin ( kinematic.velocity.y / speed )

# Find the roll

roll = atan2 ( kinematic . rotation , rollScale)

# Find the output orientation by combining the three

# component quaternions

result = orientationInDirection ( roll , Vector ( 0 ,0 , l ) ) result *= orientationInDirection ( pitch , Vector ( l , 0 , 0) ) result *= orientationInDirection (yaw, Vector (0 , l , 0) ) return result

Struktury danych i interfejsy

Kod opiera się na dostępnych procedurach matematycznych wektorów i kwaternionów i założyliśmy, że możemy utworzyć wektor przy użyciu konstruktora trójargumentowego. Większość operacji jest dość standardowa i będzie obecna w każdej wektorowej bibliotece matematycznej. OrientacjalnDirecti na funkcji kwaternionu jest mniej powszechna. Zwraca kwaternion orientacji reprezentujący obrót o dany kąt wokół ustalonej osi. Można to zaimplementować w następujący sposób:

def orientationInDirection i ( angle, axis ) : result = new QuaternionQ

result .r = cos (angle*0.5) sinAngle = sin (angle*0.5) result .i = axis .x * sinAngle result .j = axis .y * sinAngle result .k = axis .z * sinAngle return result

Uwagi dotyczące implementacji

Ten sam algorytm przydaje się również w innych sytuacjach. Odwracając kierunek przechyłu (0), pojazd potoczy się na zewnątrz z zakrętem. Można to zastosować do podwozi jeżdżących samochodów (z wyłączeniem komponentu 0, ponieważ nie będzie kontrolowanej prędkości pionowej), aby sfałszować efekt mokrego zawieszenia. W tym przypadku potrzebna jest wysoka wartość k.

Wydajność

Algorytm ma wartość 0(1) zarówno w pamięci, jak i czasie. Zawiera wywołanie arcus sinus i arcus tangens oraz trzy wywołania funkcji recti on orientallnDi. Wywołania Arcsine i Arctan są zazwyczaj powolne, nawet w porównaniu z innymi funkcjami trygonometrycznymi. Dostępne są różne szybsze implementacje. W szczególności implementacja wykorzystująca tablicę przeglądową o niskiej rozdzielczości (około 256 wpisów) byłaby całkowicie odpowiednia dla naszych potrzeb. Zapewniałby 256 różnych poziomów nachylenia lub przechylenia, co normalnie wystarczyłoby, aby gracz nie zauważył, że przechylenie nie jest całkowicie płynne.

W dokumencie Ruch. Podstawy algorytmów ruchu (Stron 142-145)

Powiązane dokumenty