Autor Wątek: Odpowiedź kolizji ciał sztywnych  (Przeczytany 819 razy)

Offline taki_tam

  • Użytkownik

# Marzec 30, 2012, 17:14:31
Siema!
Długoo nie pisałem nic, co nie znaczy, że nie śledzę forum.
Na początku chciałbym wyrazić zadowolenie z nowego warsztatu 3.0, jak dla mnie świetny (poza paroma błędami, 1 ważny zamieściłem w bug-truckerze).

A teraz do rzeczy.

Ostatnio zacząłem pisać od nowa mój silnik fizyczny, tym razem prawdziwe ciała sztywne.
Poprzedni symulował ciała (nie tylko sztywne) typu "Verlet-based rigid body".
Zdecydowałem się na napisanie wszystkiego od nowa, tym razem wg. dokumentu Pana Chrisa Heckera, ponieważ pojawiły się problemy ze stabilnością i wydajnością przy ogromnej liczbie przeróżnych ciał(mimo podziału przestrzeni - tutaj jednak znaczenie na wydajność miał mój zabytkowy komputer na który jestem jeszcze skazany, podział przestrzeni działał sprawnie). Jednakże Verletowskie ciała sztywne/miękkie wymagają nieco więcej od procesora, a w zasadzie miękkie nie są mi do niczego potrzebne.

Odpowiedź kolizji na prędkość liniową wyglądają bez zarzutu, jednak z prędkością kątową są już jaja.
Na początek przedstawię mini schemat działania silnika:
1: sprawdzanie kolizji metodą SAT
- jeśli jest odsuwam ciała o MTD(jest znormalizowany więc mnożę go przez głębokość)
- liczę odpowiedź kolizji
2: liczenie prędkości
3: liczenie pozycji
4: pętla
5: render

Dla kolizji liczę dwa punkty kontaktu jeśli to możliwe(obliczenia działają bez zarzutu)

Teraz przedstawię równania, które biorą udział w odpowiedzi kolizji.

R1, R2 - wektor od punktu kontaktu do środka masy
VA, VB - wektor prędkości w punkcie kontaktu
VAB - Prędkość względna w punkcie kontaktu
N - wektor normalny kolizji
e - współczynnik restytucji <0, 1>
J - impuls

Teraz tak
R1 = contact.pos - bodyA.pos
R2 = contact.pos - bodyB.pos
VA = bodyA.vel + Cross(R1, bodyA.AngVel)
VB = bodyB.vel + Cross(R2, bodyB.AngVel)
VAB = VB - VA
VN = Dot(VAB, N)
J = (-(1.0 - e) * VN) / (Dot(N, N) * (bodyA.InvMass + bodyB.InvMass) + (Sqr(Dot(R1, N)) * bodyA.InvI) + (Sqr(Dot(R2, N)) * bodyB.InvI))

Nowe prędkości:
bodyA.vel = bodyA.vel + N * J / bodyA.InvMass
bodyA.AngVel = bodyA.AngVel + Dot(R1, N*J) / bodyA.InvI

bodyB.vel = bodyB.vel - N * J / bodyB.InvMass
bodyB.AngVel = bodyB.AngVel - Dot(R2, N*J) / bodyB.InvI

Objawy: Tak jak napisałem na początku, obliczenia dla prędkości liniowej wyglądają w porządku, jednak dla prędkości kątowej wygląda to tak, że ciało przewraca się cały czas z jednego boku na drugi i z powrotem.

Osobiści przez 2 noce przeglądałem źródła, czytałem dokument Heckera ale bez skutku decydując się na prośbę o pomoc na forum.

Edit: Oo, żeby nie lamić, zapomniałem pytania :P Co robię źle, czy moje obliczenia są poprawne?
Jeśli to konieczne mogę dodać RAR'a z demkiem.

Pozdrawiam! ;)

taki_tam
« Ostatnia zmiana: Marzec 30, 2012, 17:56:35 wysłana przez taki_tam »

Offline Mr. Spam

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