Silnik fizyki

Z EGA Wiki

Spis treści

Co to jest?

Silnik fizyki jest to zbiór mechanizmów, który wykonuje obliczenia odpowiedzialne za odwzorowanie praw fizyki z pomocą zmiennych, takich jak masa, prędkość, tarcie itp.

Rola

Pozwala realistycznie (lub też nie) symulować i przewidywać skutki w różnych warunkach. Czyli co się będzie dziać w życiu czy w świecie wirtualnym.

Wykorzystanie

  • Do gier:

-Ważniejsza szybkośc niż dokladność -czas rzeczywisty

  • Naukowe:

-Ważniejsza dokładność niż szybkość

Na przykład: - Pogoda - testy samochodów

Wygląd obiektów

  • Grafika
  • Fizyka

Podstawowe zadania

  • wykrywanie kolizji
  • symulacja ruchu

czyli obliczanie macierzy transformacjii

Przykłady Enginów

  • Havok
  • Bullet
  • PhysX

PhysX hierarchia klas

Plik:klas_diag.png

Aktorzy

Wszystkie obiekty znajdujace się na scenie

  • Statyczne -np. skrzynki, beczki, wszystko na co ma działać fizyka
  • Dynamiczne - np. grunt, budynek

macierz transformacji

  • Fizyka NxMat34
  • Grafika float glmat[16]

Przejscie z jednego typu do drugiego uzskujemy za pomocą getColumnMajor44(glmat); w kazdym aktorze

Obiekty PhysX-owe

Singleton

   NxPhysicsSDK*	gPhysicsSDK = NULL;
   NxScene*		gScene = NULL;
   
   gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
   if (!gPhysicsSDK)  return;

Scena

   NxSceneDesc SceneDesc;
   
   sceneDesc.gravity = NxVec3(0.0f,-9.8f,0.0f); //grawitacja
   gScene=gPhysicsSDK->createScene(sceneDesc); 

Materiały

   NxMaterialDesc materialDesc;
   
   materialDesc.restitution = 0.7f;
   materialDesc.staticFriction = 0.5f;
   materialDesc.dynamicFriction = 0.5f; 
   
   NxMaterial *newMaterial=gScene->createMaterial(materialDesc);

Proste kształty

   NxActorDesc actorDesc;
   NxBodyDesc bodyDesc;
   NxBoxShapeDesc boxDesc;
   
   boxDesc.materialIndex= newMaterial->getMaterialIndex();
   boxDesc.dimensions.set(0.5,0.5,0.5);
   actorDesc.shapes.pushBack(&boxDesc);
   actorDesc.body	= &bodyDesc;
   actorDesc.density 	= 10.0f;
   actorDesc.globalPose.t	= NxVec3(0,4,0);
   
   NxActor *pActor = gScene->createActor(actorDesc);

Złożone kształty

   NxActorDesc actorDesc;
   NxBodyDesc  bodyDesc;	
   	
   //sześcian
   
   NxBoxShapeDesc boxShape;
   boxShape.dimensions		= NxVec3(1.0f, 1.0f, 1.0f);
   boxShape.localPose.t	= NxVec3(1.5f, 0.0f, 0.0f);
   actorDesc.shapes.pushBack(&boxShape);
   
   //kapsułka	
   
   NxCapsuleShapeDesc capsuleDesc; //Capsule Shape
   capsuleDesc.radius		= 0.8f;
   capsuleDesc.height		= 1.0f;
   capsuleDesc.localPose.t = NxVec3(0.0f, 0.0f, 0.0f);
   
   //obrot jej o 90 stopni
   
   NxQuat quat(90.0f, NxVec3(0, 0, 1));
   NxMat33 m;
   m.id();
   m.fromQuat(quat);
   capsuleDesc.localPose.M = m;
   
   actorDesc.shapes.pushBack(&capsuleDesc);
   
   
   //Sfera
   
   NxSphereShapeDesc sphereDesc;
   sphereDesc.radius		= 1.0f;
   sphereDesc.localPose.t	= NxVec3(-1.5f, 0.0f, 0.0f);
   
   actorDesc.shapes.pushBack(&sphereDesc);
   
   actorDesc.body			= &bodyDesc;
   actorDesc.density		= 10.0f;
   actorDesc.globalPose.t	= NxVec3(5.0f, 0.0f, 0.0f);
   
   NxActor *pActor = gScene->createActor(actorDesc);

Joint-y

Tkaniny

Ciała miękkie

Jak odpalić to cudo na Linuksie

Disclaimer

Nikogo nie namawiam do działania wbrew prawu i pisania na Linuksie, pisze to po to gdyby ktoś potrzebował lub miał życzenie :-)

Download

Dla Linuksa nVidia udostępnia tylko 32bitowe (dla PhysX SDK 3.0 ponoć będą już 64bit) bilbioteki PhysXa w wersji rpm lub deb - ściągamy interesującą nas wersję:

   PhysX_2.8.1_SDK_CoreLinux_rpm.tar.gz
   PhysX_2.8.1_SDK_CoreLinux_deb.tar.gz

Instalacja

Po rozpakowaniu mamy 6 paczek deb lub rpm i jeżeli mamy dystrybucję, która je obsługuje to nie ma problemu - w przeciwnym wypadku instalujemy ręcznie. W tym celu:

   disturb $ tar xf ../PhysX_2.8.1_SDK_CoreLinux_rpm.tar.gz 
   libphysx-2.8.1-2.8.1-5.i386.rpm
   libphysx-common-2.8.1-5.i386.rpm
   libphysx-dev-2.8.1-2.8.1-5.i386.rpm
   libphysx-doc-2.8.1-2.8.1-5.i386.rpm
   libphysx-extras-2.8.1-2.8.1-5.i386.rpm
   libphysx-samples-2.8.1-2.8.1-5.i386.rpm

Do rozpakownia rpmów można użyć aliena, rpm2cpio lub najłatwiej rpm2targz:

   disturb $ for i in *.rpm; do rpm2targz $i; done
   disturb $ rm *.rpm
   disturb $ ls
   libphysx-2.8.1-2.8.1-5.i386.tar.gz
   libphysx-common-2.8.1-5.i386.tar.gz
   libphysx-dev-2.8.1-2.8.1-5.i386.tar.gz
   libphysx-doc-2.8.1-2.8.1-5.i386.tar.gz
   libphysx-extras-2.8.1-2.8.1-5.i386.tar.gz
   libphysx-samples-2.8.1-2.8.1-5.i386.tar.gz
   disturb $ for i in libphysx-*.tar.gz; do tar xf $i; done
   disturb # cp etc/PhysX.conf /etc/
   disturb # cp -r usr/* /usr/

Dowiązania

Includy:

   disturb # ln -s /usr/include/PhysX/v2.8.1/SDKs/Cooking/include /usr/include/NxCooking
   disturb # ln -s /usr/include/PhysX/v2.8.1/SDKs/Foundation/include /usr/include/NxFoundation
   disturb # ln -s /usr/include/PhysX/v2.8.1/SDKs/NxCharacter/include /usr/include/NxCharacter
   disturb # ln -s /usr/include/PhysX/v2.8.1/SDKs/Physics/include /usr/include/NxPhysics
   disturb # ln -s /usr/include/PhysX/v2.8.1/SDKs/PhysXLoader/include /usr/include/PhysXLoader

Bilbioteki:

   disturb # ln -s /usr/lib/libPhysXLoader.so.1 /usr/lib/libPhysXLoader.so
   disturb # ln -s /usr/lib/PhysX/v2.8.1/libNxCharacter.so.1 /usr/lib/libNxCharacter.so{,.1}
   disturb # ln -s /usr/lib/PhysX/v2.8.1/libNxCooking.so.1 /usr/lib/libNxCooking.so{,.1}
   disturb # ln -s /usr/lib/PhysX/v2.8.1/libPhysXCore.so.1 /usr/lib/libPhysXCore.so{,.1}

Jak niemożliwe jest z jakiegoś powodu dowiązywanie w /usr/lib, można skopiować PhysX do /usr/local/lib (albo w inne miejsce):

   disturb $ export PHYSX_LIB_PATH="/usr/local/lib/"
   disturb $ cp -a /usr/lib/PhysX ${PHYSX_LIB_PATH}/PhysX/v2.8.1/
   disturb $ cp usr/lib/libPhysXLoader.so.1 ${PHYSX_LIB_PATH}/PhysX/v2.8.1/
   disturb $ ln -s ${PHYSX_LIB_PATH}/PhysX/v2.8.1/libNxCharacter.so.1 ${PHYSX_LIB_PATH}//PhysX/v2.8.1/libNxCharacter.so
   disturb $ ln -s ${PHYSX_LIB_PATH}/PhysX/v2.8.1/libNxCooking.so.1 ${PHYSX_LIB_PATH}//PhysX/v2.8.1/libNxCooking.so
   disturb $ ln -s ${PHYSX_LIB_PATH}/PhysX/v2.8.1/libPhysXCore.so.1 ${PHYSX_LIB_PATH}//PhysX/v2.8.1/libPhysXCore.so
   disturb $ ln -s ${PHYSX_LIB_PATH}/PhysX/v2.8.1/libPhysXLoader.so.1 ${PHYSX_LIB_PATH}//PhysX/v2.8.1/libPhysXLoader.so
   disturb # echo "${PHYSX_LIB_PATH}/PhysX/v2.8.1/" >> /etc/ld.so.conf
   disturb # ldconfig 

Teraz możemy includować:

   #include <NxPhysics/NxPhysics.h>

Do linkowania prostego programu potrzebujemy:

   -DNX_DISABLE_FLUIDS -DNX32 -m32 -DLINUX -lpthread -ldl -lPhysXLoader -lPhysXCore -lNxCooking

Test

Jak już zainstalowane to można sprawdzić, czy działa:

   disturb $ svn co http://th.if.uj.edu.pl/disturb_svn/branches/D3 D3
   disturb $ cd D3/tests
   disturb $ cmake .
   disturb $ make
   disturb $ ./physx_test
   OK

CUDA i OpenCL

Dobrym pomysłem jest instalacja sterowników nVidia obsługujących CUDA i OpenCL i prawdopodobnie najlepszym wyborem do tego celu zdaje się być:

   cudadriver_3.0-beta1_linux_64_195.17-beta.run
   cudadriver_3.0-beta1_linux_32_195.17-beta.run