Autor Wątek: Silnik fizyczny szukam podstaw.  (Przeczytany 2424 razy)

Offline prociomen007

  • Użytkownik

# Kwiecień 05, 2012, 22:48:01
No i przyszedł czas na zabawę z silnikiem fizycznym. Nie ukrywam że będzie to dojść trudne poniewarz pierwszy raz mam napisać to całkiem sam ;-). Jako że piszę na androida nie mam możliwości skorzystania z czegoś takiego jak chodźmy osławiony phisX. Aktualnie szukam pomocy oraz stron wyjaśniających jak sprawdzać czy obiekty ze sobą kolidują. Interesują mnie jakieś proste kształty typu szejścian, prostokąt, kostka. Załorzenia na wstęp mam proste:

Każdy obiekt posiada pozycję (tutaj pełna macierz obroty, przesunięcie ), prędkość oraz przyspieszenie. Globalnie definiujemy w którą stronę ma działać przyciąganie  i z tych danych obliczamy zaminy w pozycji obiektów.

Problem pojawia się teraz kiedy obiekty mają ze sobą wchodzić w interakcję. Jak można matematycznie sprawdzić czy ich wierzchołki ze sobą kolidują? Oraz jak można sprawdzić jak zmienia się "siła" oddziałująca na dany obiekt aby po uderzeniu zmieniał się kierunek przemieszania.

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline mihu

  • Użytkownik
    • mihu

# Kwiecień 05, 2012, 22:52:39
Jeśli chciałbyś użyć gotowego silnika to zobacz bullet. Widziałem przynajmniej jeden przypadek skutecznego użycia go na Androidzie.

Na początek polecam książkę Game Physics Engine Development Iana Millingtona. Dobrze i powoli wprowadza w podstawy.

Offline prociomen007

  • Użytkownik

# Kwiecień 06, 2012, 16:29:28
Dzięki to była porada w dziesiątkę z tym bullet. A sam wolał bym się nie zabierać aktualnie za pisanie silnika fizycznego bo jest to zapewne przedsięwzięcie nie mniej pracochłonne jak pisanie silnika graficznego ;-) Udało mi się skonfigurować bulleta z androidem i z eclipse oraz załadować do programu biblioteki. Jeśli ktoś miał do czynienia z tym engnem to szukam porad jak najprościej zintegrować to z OpenGL. Udało mi się na chwilę obecną załadować scenę fizyczną tworząc "podłogę" i jeden obiekt jako kostka. Szukam sposobu połączenia tego z openGL. Scena jest tworzona tak:

/* Tworzenie świata fizycznego ;-) */
CollisionConfiguration collisionConfiguration = new DefaultCollisionConfiguration();
CollisionDispatcher dispatcher = new CollisionDispatcher(collisionConfiguration);

Vector3f worldAabbMin = new Vector3f(-10000,-10000,-10000);
Vector3f worldAabbMax = new Vector3f(10000,10000,10000);
AxisSweep3 overlappingPairCache = new AxisSweep3(worldAabbMin, worldAabbMax);
SequentialImpulseConstraintSolver solver = new SequentialImpulseConstraintSolver();

dynamicWorld = new DiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
dynamicWorld.setGravity(new Vector3f(0,-10,0));
dynamicWorld.getDispatchInfo().allowedCcdPenetration = 0f;

               /* Tworzenie standardowej podłogi */

CollisionShape groundShape = new BoxShape(new Vector3f(100.f, 50.f, 100.f));
Transform groundTransform = new Transform();
groundTransform.setIdentity();
groundTransform.origin.set(new Vector3f(0.f, -56.f, 0.f));
float mass = 0f;
Vector3f localInertia = new Vector3f(0, 0, 0);
    DefaultMotionState myMotionState = new DefaultMotionState(groundTransform);
RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, groundShape, localInertia);
RigidBody body = new RigidBody(rbInfo);
dynamicWorld.addRigidBody(body);

dynamicWorld.clearForces();

                /* Utworzenie obiektu fizycznego (kostka) */

Transform transform;
BoxShape shape = new BoxShape(new Vector3f(2,2,2));
float mass2 = 2;
Vector3f localInertia1 = new Vector3f(0,0,0);
shape.calculateLocalInertia(mass2, localInertia1);
 
RigidBodyConstructionInfo rbInfo1;
RigidBody body1;

transform = new Transform();
transform.setIdentity();
transform.origin.set(0, 5,10);

DefaultMotionState polorzenie = new DefaultMotionState(transform);
   
rbInfo1 = new RigidBodyConstructionInfo(mass2, polorzenie, shape, localInertia);
body1 = new RigidBody(rbInfo1);
body1.setRestitution(0.1f);
body1.setFriction(0.50f);
body1.setDamping(0f, 0f);
   
dynamicWorld.addRigidBody(body1);
 

Teraz podczas renderu sceny wołam co klatkę

float ms = clock.getTimeMicroseconds();
  clock.reset();
  dynamicWorld.stepSimulation(ms / 1000000f);

Co pewnie (bo nie mam jak podejrzeć) uaktualnia mi scenę fizyczną. Pytanie jak teraz dostać z tego wszystkiego macierz transformacji dla opengl dla danego obiektu?

Offline quaikohc

  • Użytkownik

# Kwiecień 06, 2012, 16:58:50
Jako że piszę na androida nie mam możliwości skorzystania z czegoś takiego jak chodźmy osławiony phisX.

od wersji 3.1 physxa dostępne jest (darmowe ofc) sdk do androida, więc możesz z niego skorzystać

Offline Avaj

  • Użytkownik

# Kwiecień 06, 2012, 17:08:11
motion_state.m_worldTransform.getOpenGLMatrix(m)

Offline prociomen007

  • Użytkownik

# Kwiecień 06, 2012, 20:21:25
Ok dzięki wszystkim jednak można to zrobić na tym bulled. Z wydajnością nawet nie jest jakoś tragicznie.
http://warsztat.gd/video/1141 efekty pod linkiem dostępne.

Offline lukasyno

  • Użytkownik

# Kwiecień 06, 2012, 21:14:08
@prociomen007 w czym zrobiles sterowanie? mam na mysli te dwa "joystick" po bokach? jakis lib? kontrolki z androida natywne?

Offline prociomen007

  • Użytkownik

# Kwiecień 06, 2012, 21:31:48
Całkowicie mój pomysł do tych kontrolek ;-). To są dwa obrazki dodane do głównej warstwy obrazu na których obsługuję multitouch. Jeśli chodzi o samą detekcję ruchu to wykombinowałem prosty algorytm który mi to sprawdza i podejmuje konkretne działania.

Offline lukasyno

  • Użytkownik

# Kwiecień 07, 2012, 16:25:32
A jesze jak bys mogl powiedziec jakiej wersji bulleta uzywałes? np tej http://apistudios.com/hosted/marzec/badlogic/wordpress/?p=248 poprzez NDK czy jakies natywnie pisanej w JAVIE?
pzdr


Offline MrKaktus

  • Użytkownik

# Kwiecień 07, 2012, 16:39:06
kolejne 2 (pozostale 2 sa wieksze niz 5mb kazdy a niechce mi sie bawic w megauploady i inne, na razie powinno starczyc :)

Offline prociomen007

  • Użytkownik

# Kwiecień 07, 2012, 20:10:10
He he z bulletem jest niespodzianka mała. Nie działa ten najnowszy na andku. Są jakieś problemy z zarządzaniem pamięcią. Udało mi się załadować "jbullet-20080303" + biblioteki kilka bibliotek.