Wstęp
Jest to mój pierwszy artykuł dla większej liczby odbiorców, choć kilka razy się zabieram, jak na razie tylko ten udało mi się skończyć dlatego proszę o wyrozumiałość. Dowiesz się na czym polega symulacja fizyczna punktu materialnego. Pewnie teraz ktoś wyrwie się z pytaniem dlaczego punktu ? Oczywiście chodzi tu o wielkie uproszczenie ponieważ w grach jedynie korzysta się z obrotu wokół osi wzrostu niezależnie od praw fizyki.
Mówiąc oś wzrostu mam namyśli oś wzdłuż której mierzymy wzrost gracza, bywa iż niektórzy przyjmują za nią oś OZ, lecz my użyjemy układu z osią OY ostatecznie jest to bez większej różnicy jedynie zmienia nam kierunek działania grawitacji, gdyż grawitacje uznajemy jako siłę działająca w kierunku środka Ziemi, a w przypadku gier Ziemia ma nieskończoną rozpiętość, masę, nie jest kulą (Kopernik by się oburzył jak by się dowiedział :D) i znajduje się pod graczem.

Stały czas
Aby cała symulacja fizyczna działała nam w ciągłości bez nagłych skoków czasowych, musimy obliczyć zmianę czasu w kolejnych klatkach. W tym celu napiszemy kilka linijek kodu w głównej pętli programu.

Pierwsza prosta linijka kodu liczy nam średnią arytmetyczną pomiędzy czasem z poprzedniej klatki, a czasem który minął w tej aktualnej dzięki czemu otrzymamy zmianę czasu bez niepotrzebnych większych skoków. Wynik podawany jest w sekundach dlatego mamy tu dzielenie przez 1000.
W następnej kolejności musimy wykonać procedurę Time_Physics , która jest odpowiedzialna za działanie modelu fizycznego w grze. Warto dodać, że jeśli ktoś zechciałby zrobić sobie bullettime rodem z Maxa Payne to wystarczy w tym miejscu przemnożyć dDeltaTime przez dowolny współczynnik zwolnienia u nas ta wartość przechowuje stała sBulletTime.

Na samym początku sprawdzane jest czy czas nie wybiega poza dozwolone ramy, ponieważ mogło by to wywołać błąd symulacji. Ze względu na zbyt dużą ilość powtórzeń pętli, błąd by narastał co klatkę. Kolejna część kodu to liczenie ilości kroków czasowych mieszczących się w przedziale czasu. Zmienna stepcount przechowuje tą wartość w zaokrągleniu do dołu, a steprest resztę z dzielenia. To właśnie tyle razy fizyka będzie przeliczana w czasie jednej klatki. Dalej mamy pętlę odpowiedzialną za kilkukrotne wywołanie obliczeń modelu fizycznego. Teraz wytłumaczę po co to wszystko, bo w końcu można by od razu wywołać Update_Physics(dDeltaTime); i nie kombinować z żadnymi krokami czasowymi. Tak jest, takie rozwiązanie dawało by podobny efekt, ale niestety nie zawsze taki sam, gdyż celem tej procedury jest utrzymanie stabilności zachowań fizycznych oraz takich samych wyników na wszystkich konfiguracjach komputerów.
Tak więc cała stabilizacje czasową mamy wykonaną, wszystko działa w jednym tempie oraz nie pojawiają się nagłe nieprzewidziane skoki spowodowane spadkiem fps 🙂 możemy więc przejść do aktualizacji fizyki którą zajmuje się procedura Update_Physics. Zanim jednak zajmiemy się kodem muszę wytłumaczyć parę rzeczy dotyczących fizyki.

Gracz
Czas przejść do następnej części artykułu. Zajmiemy się tym razem zachowaniem fizycznym w przestrzeni, ale zanim to zrobimy musimy stworzyć ciało fizyczne, które będzie odpowiednikiem naszego gracza, a tak naprawdę będzie to punkt materialny. Zarówno może zostać wykorzystany do robienia particle systemu jak i symulacji ciał miękkich. Oto kod rekordu TPlayer:

W naszej symulacji fizycznej wyróżnimy cztery główne elementy:

1.Model
Jest to najważniejszy aspekt symulacji. Oznacza idealizację przedmiotu, którego zachowanie chcemy symulować. W tym przypadku chodzi o gracza, który tak naprawdę będzie reprezentowany jako punkt materialny w przestrzeni. Tutaj znajdują się siły działające na ciało. Są to:
* siła grawitacji 
Zgodnie z prawami fizyki, na Ziemi grawitacje obliczamy w następujący sposób:

Grawitacja = Przyspieszenie_ziemskie * Masa_ciała

Jeśli ktoś nie rozumie tego równania to niech się wstydzi bo przespał lekcje fizyki (ja tez spałem ale się pźóniej dowiedziałem):P

* siła oporu 
Siła przeciwna do prędkości powstrzymuje ciało przed zbyt dużym ruchem. W tym miejscu także zastosuje pewne uproszczenie ze względu na ilość obliczeń potrzebną do wyliczenia oporu powietrza zależnego od kształtu ciała, a wynik i tak daje niezauważalne różnice, bo nie robimy przecież symulatora lotu :D. Wykorzystamy więc takie równanie:

Opór := Prędkość* -współczynnik_oporu;

Oto kod obliczający siły działające na ciało:

2.Integrator
Ta część symulacji odpowiedzialna jest za zastosowaną metodę całkowania równań różniczkowych ruchu. My zastosujemy najprostszą metodę Eulera o której dowiedzieliśmy się już w na pierwszych lekcjach fizyki w szkole podstawowej. Metoda ta nie daje najlepszych efektów ponieważ naraża symulację na dość duży błąd, ale prostszej nie znajdziemy :).

W wielkim skrócie należy wiedzieć, że dla punktu materialnego:

Przyśpieszenie = Siła / masa

Tutaj kłania się druga zasada dynamiki Newtona.
Przyspieszenie z jakim porusza się ciało jest proporcjonalne do działającej siły i odwrotnie proporcjonalne do masy ciała. Kierunek i zwrot przyspieszenia jest zgodny z kierunkiem i zwrotem siły.

Prędkość = Prędkość + (Przyśpieszenie * Zmiana_czasu)

Muszę tutaj wytłumaczyć pewną sprawę ponieważ w szkole od zawsze wpajano nam iż prędkość = droga/czas
Oczywiście to prawda tylko należy dodać, iż w taki sposób nie wyliczymy nic ponieważ to od prędkości zależna jest zmiana połażenia, a wiec droga. W takim wypadku nie pozostaje nam nic innego jak skorzystać z przyspieszenia a wiec zmiany prędkości w czasie.
Prędkość wyznacza nam zmianę pozycji w czasie.

Pozycja = Pozycja + (Prędkość * Zmiana_czasu)

Teraz kod wykonujący zadanie dotyczące integracji Eulera.

3.Kolizje
Ostatni element symulacji odpowiada za kolizje. W następnej części artykułu, który będzie dotyczył kolizji postaram się bardziej przybliżyć to zagadnienie, ale teraz opisze tylko prosty test z pozioma płaszczyzną oraz reakcje obiektu na wykryta kolizję. W tym przypadku siła to pojęcie umowne, ponieważ mam raczej na myśli zmianę prędkości ciała.

* Sprężystość
Jest to 'siła’ działająca wzdłuż normalnej prostopadłej do płaszczyzny kolizji. Elastyczność gracza w zakresie od 0 do 1 da nam zerowe odbicie lub elastyczne bez straty prędkości.

Prędkość.y = -prędkość.y * elastyczność.y;

* Imitacja tarcia 🙂 
Działa wzdłuż rzutu wektora prędkości na płaszczyznę kolizji, ale w przeciwnym kierunku. Musze tu wspomnieć że jest to tylko pewne uproszczenie niezgodne z trzecim prawem tarcia: „Z chwilą wprowadzenia ciała w ruch, siła tarcia nie zależy od prędkości” oraz ze znanymi wzorami:
T = Fn*u
gdzie:
Fn – sił anacisku,
u – współczynnik tarcia.
Nie skorzystamy z tego wzoru ponieważ ośrodek w którym występują kolizje nie jest idealny, a duża zmiana czasu powoduje drgania. Dla uproszczeni skorzystamy z prędkości.
Zakładamy, że ciało z którym kolidujemy ma nieskończoną masę i chcemy zatrzymać gracza jeśli współczynnik tarcia jest równy 1 lub pozwolić na ślizg dla 0.

// Tarcie-wersja niezgodna z prawami fizyki uproszczenie na potrzeby gier
vVelocity.x := vVelocity.x – vVelocity.x * sFriction;
vVelocity.z := vVelocity.z – vVelocity.z * sFriction;

Aby któraś z tych 'sił’ w ogóle mogła zadziałać punkt musi znajdować się wystarczająco blisko podłoża oraz poruszać się w jej kierunku.

4.Wejście użytkownika

Wejście użytkownika to sposób w jaki pozwalamy użytkownikowi wchodzić w interakcję z symulacją tzn. kontrolować to co się dzieje. W naszym przypadku będzie to chodzenie oraz podskakiwanie.
Klawisze:
Strzałka w górę – ruch do przodu
Strzałka w dół – ruch do tyłu
Strzałka w Lewo – ruch w lewo
Strzałka w Prawo – ruch w prawo
Spacja – podskok

Procedura która wykonuje to zadanie:

Myślę że, nie ma co tłumaczyć, jeśli ktoś się przyjrzy na spokojnie to zrozumie jak to działa. Po prostu wciśnięcie danego przycisku może spowodować zmianę prędkości obiektu.

A więc ostatecznie procedura Update_Physics wygląda następująco:

Zbliżamy się do końca mojego pierwszego artykułu pozostało tylko wyświetlenie sceny. Chce to opisać ogólnikowo bo to nie rendering był głównym celem tego artykułu tylko fizyka gracza 🙂 Więc kod rysujący gracza to:

Tuning
Pozostał nam jeszcze tuning, bynajmniej nie chodzi tutaj o samochody co mogło by się tak kojarzyć, a raczej o dostrajanie fizyki. Ustawienie odpowiednich parametrów jest dość ważnym elementem przybliżenia symulacji do realnego świata 🙂 Mówiąc prościej po pierwszym uruchomieniu programu rezultaty nie były zadowalające dopiero po kilkukrotnych próbach otrzymałem taki rezultat.

Do edytowania mamy takie wartości:

Wystarczy zmienić:
sGravity na 1/6*9.80665 i w ten sposób otrzymujemy grawitacje prosto z księżyca.
sElasticity na 0.9 i mamy odbijającą się piłkę
sFriction i sDrag na 0 i ślizgamy się płaszczyźnie jak po lodzie.
Wszystko zależy od Twojej pomysłowości :D.

Reszta kodu znajduje się w załączniku. Mam nadzieję, że ktoś skorzysta z tego artykułu i od teraz jego gry będą miały choć trochę więcej realizmu dzięki podstawowym prawom fizyki 🙂

Pozdrawiam!
Spider ^*^

Modifited by RudolfAK@gmail.com

Załączniki