Obsługa PhysX

PhysX jest silnikiem fizyki. Zadaniem silnika fizyki jest przeprowadzenie obliczeń związanych z symulacją zjawisk fizycznych jak dynamika brył sztywnych, płynów lub soft body dynamics. Wyręcza on twórcę gry w samodzielnej implementacji fizyki.

Innymi popularnymi silnikami fizyki są:

My wykorzystamy PhysXa do symulacji dynamiki brył sztywnych. Dokumentację można znaleźć w poniższych linkach

https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/Index.html https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxapi/files/index.html

Inicjalizacja PhysX

W tej części przejdziemy po istniejącym kodzie i omówimy jego działanie.

Zaczniemy od klasy Physics, która zawiera atrybut scene, (która zawiera naszą scenę, czyli obiekty aktorów, które mają ze sobą fizycznie reagować i ich własności.) oraz atrybut physics, który służy do tworzenia tych obiektów.

Jej konstruktor wygląda następująco:

 

Następnie mamy funkcję step, która wykonuje symulację, składa się ona z 2 kroków; najpierw wykonywana jest symulacja, następnie pobierane wyniki.

Położenie w scenie physXa musimy przenieść do naszej sceny macierze transformacji odpowiadające ich położeniu są pobierane w funkcji

Tworzenie aktora

Aktora tworzy się za pomocą metod klasy PxPhysics, jest ona dostępna u nas po pxScene.physics (pamiętaj, że jest to wskaźnik i trzeba używać strzałki zamiast kropki do wywołania metod).

Aby stworzyć aktora należy użyć metody createRigidStatic lub createRigidDynamic, które tworzą odpowiednio statycznego i dynamicznego aktora (o aktorze statycznym można pomyśleć jak o obiekcie z nieskończoną masą, na którego nie działają żadne siły). Funkcja przyjmuje argument transform, który jest początkową pozycją.

Następnie musimy określić kształt obiektu za pomocą za pomocą metody createShape ona z kolei przyjmuje 2 argumenty: geometrię i materiał. Geometria odpowiada za kształt obiektu (przykładowo PxPlaneGeometry() daje nam płaszczyznę a PxBoxGeometry(hx, hy, hz) daje prostopadłościan o wymiarach 2hx na 2hy na 2hz). Kształt dodaje się do aktora za pomocą metody attachShape. Dodany kształt należy usunąć używając jego metody release

Dodatkowo do aktora można dodać dodatkowe dane poprzez atrybut userData, który jest wskaźnikiem typu void*. Wykorzystywany jest by powiązać scenę silnika fizycznego z reprezentacją graficzną, która będzie na ekranie

Zadanie

Wykonaj zadania opisane w komentarzach pliku main_8_1 i main_8_2

 

Rejestrowanie zdarzeń

W tej części skupimy się na rejestrowaniu i obsłudze zderzeń pomiędzy obiektami. Jest to przydatna funkcjonalność przy tworzeniu gier lub ogólnie aplikacji wykorzystującej fizykę. Z ich pomocą można zaimplementować szereg mechanik, jak zadanie obrażeń w wyniku trafienia pociskiem/bronią białą, wywołanie animacji czy przytwierdzenie haka do ściany.

Implementacja wymaga najpierw zdefiniowania swojego filter shadera, w którym należy zdefiniować jak mają być obsłużone zdarzenia w scenie physx. W poniższej definicji definiujemy, że punkty zderzenia będą obsługiwane przez OnContact.

Samą obsługę zdarzeń definiujemy za pomocą wywołań zwrotnych - callbacków.

Wywołanie zwrotne można rozumieć jako odwrotność wywołania funkcji. Zwykle programista wykorzystuje biblioteki poprzez wywoływanie zawartych w niej funkcji. W tym przypadku jest odwrotnie: programista pisze funkcję i przekazuje ją bibliotece, która odpowiada za jej użycie w odpowiednim momencie.

Callback ustala się poprzez ustawienie odpowiedeniego atrybutu:

sceneDesc.simulationEventCallback = simulationEventCallback;

Klasa obiektu simulationEventCallback musi dziedziczyć po klasie PxSimulationEventCallback, która zawiera szereg metod będących różnymi callbackami odpowiadającymi za różne zdarzenia. Nas będzie interesować metoda onContact, która jest wywoływana dla każdego zetknięcia się dwóch obiektów w scenie.

Zadania

Wykonaj zadania opisane w main8_3.cpp.

Jak zrobisz raportowanie na konsoli zderzeń pomiędzy kulą a kostkami zmodyfikuj kod tak, żeby kostki, które zetkną się z kulą znikały