Jaki jest najlepszy sposób radzenia sobie z jednoczesnymi zderzeniami w silniku fizyki?

13

Piszę silnik fizyki 2d w javascript, abym mógł dowiedzieć się więcej o fizyce w grach wideo. Mam to działa poprawnie dla sztywnych zderzeń ciała, z wyjątkiem przypadków, gdy którekolwiek ciało koliduje z dwoma lub więcej innymi ciałami jednocześnie.

Obecnie dla każdej pary zderzających się ciał (A, B) modyfikuję ich prędkości i prędkości kątowe na podstawie impulsu zderzenia i odsuwam je od siebie, aby się nie przenikały. Ale wtedy wykrywanie kolizji i obliczanie impulsów dla innych kolizji z udziałem A będzie błędne.

Jakie podejścia mogę zbadać, aby mój silnik działał dla ponad 3 obiektów kolidujących ze sobą?

Krzywka
źródło
2
Powiązane: gamedev.stackexchange.com/questions/15836/... i gamedev.stackexchange.com/questions/26181/... i jestem pewien, że jest więcej, po prostu nie mogę teraz znaleźć właściwego.
MichaelHouse

Odpowiedzi:

11

Używam następującego podejścia (podobnego do algorytmu podziału masy w Tonge http://www.richardtonge.com/ ):

  • wykryj wszystkie kolidujące pary w twojej scenie / kontekście. Niech (A, B) będzie taką parą. Zastosuj ideę podziału ducha / masy: jeśli A ma kontakt z ciałami M, a B ma kontakt z N innymi ciałami, wówczas tymczasowo ustaw masę A na m_A/Mi masę B nam_B/N
  • obliczyć wkład siły reakcji / restytucji dla każdej pary (A, B) i przechowywać te wkłady we własnych akumulatorach A i B.
  • obliczyć prędkości restytucji z impulsów (jak powiedziałeś) i przechowywać je w ten sam sposób (jako reszty prędkości deltaV we własnych akumulatorach dla każdej pary (A, B))
  • obliczać przemieszczenia karne (ponownie, akumuluj przemieszczenia, nie stosuj ich natychmiast!)
    • zresetuj masy wszystkich organów wcześniej wyznaczonych jako strony w parach kolizyjnych ( m_A = m_A * Mi m_B = m_B * N)

Podejście to jest podobne do działania algorytmu iteracyjnego Jacobiego z liniowymi równoczesnymi układami równań. I nie ma gwarancji, że się zbiegnie, ale w moim symulatorze robi to dość płynnie ... w 3D (tak, dodatkowy wymiar zwiększa dwukrotnie trudność!).

Uwaga : popraw pozycje i prędkości dopiero po zakończeniu fazy wykrywania / obsługi kolizji! W ten sposób jednocześnie aktualizujesz zderzających się aktorów. Również siły restytucji muszą być wzięte pod uwagę następnym razem, gdy integrujesz się dla pozycji i prędkości.

EDYCJA: Cóż, myślę, że używasz już nadużywanej metody integracji Verleta (ta stała się popularną marką wśród entuzjastów gamedev). W tym spektrum obsługi kolizji i integracji możesz zajrzeć tutaj .

AKTUALIZACJA: Niektóre informacje o tym, jak podejść do kolizji (i sam kolizji w tym przypadku) można znaleźć w tych dokumentach:

Podejście, które zaproponowałem, nie jest od dawna oryginalnym wkładem, wiele gier używa go z wiarygodnymi wynikami i najlepiej je zastosował Jakobsen w swoim silniku gry Hitman.

Z nieco praktycznego doświadczenia, siły karne (podobne do sprężyn liniowych lub wykładniczych uzyskujących wkład z odległości penetracji) nie rozwiązują poprawnie penetracji, gdy inne siły z ciał, które zderzają się, są większe od nich. Właśnie dlatego zdecydowałem się połączyć trzy (prawie zbędne) podejścia: siły reakcji Newtona (popychasz ścianę, ściana odpycha się), prędkości wynikające z impulsu (zderzanie się piłek bilardowych) i nienaturalne „odsuwanie ciał od siebie geometrycznie " rozwiązanie. Razem wydają się zapewniać wszystko: pozbyć się większościbrzydkie artefakty wzajemnego przenikania się, zderzające się ciała mają tendencję do wzajemnego oddziaływania na dłuższą metę (z powodu prędkości restytucji i sił - przynajmniej siły, które miały tendencję do przeciągania ciał w scenariuszu kolizji, są anulowane, a ciała odbijają się od siebie) . Na koniec, dla lepszego zrozumienia tych prostych, ale powszechnych pojęć, proponuję przeanalizować te slajdy .

Mój epitet „nadużywanej metody” opisujący kroki integracji Verleta jest ukierunkowany na przekonanie kultury popularnej, że jest to Święty Graal metod integracji. Jest tylko nieznacznie lepszy niż jego Symplectic Euler (nazywany również przez pół-niejawnego Eulera) kuzynem. Istnieją znacznie bardziej skomplikowane metody integracji (wszystkie mają w sobie niejawną nazwę). Wykorzystują je potężne silniki gier, ale twórcy niezależni nie mają czasu na eksperymentowanie z nimi, ponieważ Verlet, dostosowany do konkretnego scenariusza, naprawdę robi cuda. Ponadto, nie ma absolutnie żadnej metody integracji, która poradziłaby sobie ze sztywnymi ograniczeniami bez małego oszustwa (nie można znaleźć linku, ale artykuł, o którym mówię, powinien mieć nazwę „X.Provot -” Ograniczenia deformacji w mszy -springowy model opisujący zachowanie sztywnego materiału ”

teodron
źródło
Dzięki (+1)! Co to jest „prędkość restytucji” i „przemieszczenie kary”? Ponadto, dlaczego mówicie, że integracja Verlet jest „nadużywana”? Czy uważasz, że jest to zła metoda użycia?
Cam
Prędkości restytucji są dokładnie tymi prędkościami, które otrzymujesz z impulsów, jedyną różnicą jest to, że obliczam je jako reszty (tzn. Przechowuję różnicę między tą prędkością opartą na impulsie a prędkością prądu, zachowując prędkość prądu nietkniętą do dalszych obliczeń). Przemieszczenia karne to wektory o długości określonej przez to, jak bardzo dwa obiekty przenikają się wzajemnie, i to wektor minimalnej długości może tłumaczyć jeden obiekt całkowicie poza drugi. Zwykle dodajemy takie przesunięcie do każdego obiektu dzieląc długość przez 2).
teodron
1
Genialna odpowiedź! Mam jednak inne pytanie. Powiedzmy, że akumuluję prędkości restytucji, czy nie sumują się one do bardzo nierealistycznych liczb? Jeśli traktuję każdą kolizję z obiektem A osobno i po prostu sumuję efekty na każdym obiekcie, to czy A nie będzie miał impulsu rozłożonego między obiektami? Zamiast tego zostanie zastosowany pełny impuls dla każdego, co wydaje mi się błędne intuicyjnie
Cam
To bardzo dobre pytanie ... z jednego punktu widzenia wydaje się prawdopodobne, że impulsy przyczyniają się dodatkowo do powstałej prędkości. Oto moje (być może błędne!) Uzasadnienie: wyobraź sobie, że zderzają się trzy kule bilardowe / bilardowe. Jeden z nich powinien otrzymywać wkłady od dwóch pozostałych w ten sposób addytywny. Początkowo zastanawiałem się nad ważeniem tych wkładów i obliczeniem średniej ważonej prędkości końcowej, ale ponieważ chciałem szybkich rezultatów, pominąłem ten pomysł. Podsumowując, zderzająca się kula musi uzyskać wkład prędkości od pozostałych dwóch. Być może podręcznik z liceum może pomóc.
teodron
3
Być może nie rozumiem tego, co wytłumaczyłeś, ponieważ poniższy przykład wciąż mnie dotyczy: Rozważ prostopadły prostokąt spadający prosto w dół i załóżmy, że podłoga jest postrzępiona (składa się z wielu trójkątów obok siebie). Jeśli jest n trójkątów, używając metody akumulacji, prostokąt odbije się z powrotem n razy szybciej niż powinien! Jak można naprawić tę sytuację?
Cam
1

Sugeruję, aby zamiast zmieniać prędkości, zmieniać siły działające na przedmiot. Nie „wypychaj” ich, raczej zrób to płynnie i wykorzystując już istniejący kod. Robiąc to, ciała nie będą natychmiast (i przypuszczam, że gwałtownie) zmieniać prędkości.

Sprawdź Box2DJS jako przykład: http://box2d-js.sourceforge.net/index2.html .

jcora
źródło
-1

Analitycznie rozwiązałem równanie impulsowe dla grup zderzających się ciał. Jedynym problemem, z jakim się spotkałem, był brak zmiennych do znalezienia względnej siły interakcji między kontaktami w grupie, którą wypełniłem głębokością przecięcia ciał.

Rozwiązanie dla kontaktów grupowych nie jest trudniejsze niż pojedynczy kontakt. Niestety zgubiłem artykuł z obliczeniami, dlatego nie mogę go tutaj udostępnić.

Edytuj: Prawdopodobnie wpadłem na coś takiego /physics/296767/multiple-colliding-balls

George Vinokhodov
źródło