Qual è il modo migliore per gestire le collisioni simultanee in un motore fisico?


13

Sto scrivendo un motore fisico 2D in javascript in modo da poter imparare di più sulla fisica nei videogiochi. Ho funzionato correttamente per collisioni di corpi rigidi, tranne se un corpo si scontra con due o più altri corpi contemporaneamente.

Attualmente per ogni coppia di corpi in collisione (A, B) modifico le loro velocità e velocità angolari in base all'impulso di collisione e li spingo l'uno dall'altro in modo che non penetrino. Ma poi il rilevamento delle collisioni e i calcoli degli impulsi per altre collisioni che coinvolgono A saranno errati.

Quali approcci posso esplorare per far funzionare il mio motore per 3+ oggetti in collisione?


2
Correlati: gamedev.stackexchange.com/questions/15836/… e gamedev.stackexchange.com/questions/26181/… e sono sicuro che ce ne sono altri, non riesco proprio a trovare il momento.
MichaelHouse

Risposte:


11

Uso il seguente approccio (simile all'algoritmo di divisione di massa di Tonge http://www.richardtonge.com/ ):

  • rileva tutte le coppie in collisione nella tua scena / contesto. Sia (A, B) una tale coppia. Applica un'idea di divisione fantasma / di massa: se A è in contatto con M corpi e B è in contatto con N altri corpi, imposta temporaneamente la massa di A su m_A/Me quella di B sum_B/N
  • calcolare i contributi della forza di reazione / restituzione per ciascuna coppia (A, B) e conservare questi contributi negli accumulatori propri di A e B
  • calcola le velocità di restituzione dagli impulsi (come hai affermato) e memorizzali nello stesso modo (dei residui di velocità deltaV nei loro accumulatori per ciascuna coppia (A, B))
  • calcolare gli spostamenti di penalità (di nuovo, accumulare spostamenti, non applicarli all'istante!)
    • resettare le masse di tutti i corpi precedentemente designati come parti in coppie di collisione ( m_A = m_A * Me m_B = m_B * N)

Questo approccio è simile al modo in cui l'algoritmo iterativo Jacobi funziona con sistemi di equazioni lineari simultanei. E non è garantito che converga, ma nel mio simulatore fa il lavoro abbastanza agevolmente .. in 3D (sì, una dimensione aggiuntiva aggiunge il doppio della difficoltà!).

Avvertenza : correggere posizioni e velocità solo al termine della fase di rilevamento / gestione delle collisioni! In questo modo aggiorni simultaneamente i tuoi attori in collisione. Inoltre, le forze di restituzione devono essere prese in considerazione la prossima volta quando si integrano posizioni e velocità.

EDIT: Beh, immagino che tu stia utilizzando il metodo di integrazione Verlet già abusato (questo è diventato un nome familiare tra gli appassionati di Gamedev). In questo spettro di gestione e integrazione delle collisioni, potresti dare un'occhiata qui .

AGGIORNAMENTO: Alcune delle informazioni su come affrontare la collisione (e l'auto-collisione per questo motivo) possono essere trovate in questi documenti:

L'approccio che ho proposto non è di gran lunga un contributo originale, molti giochi lo usano con risultati plausibili ed è stato impiegato al meglio da Jakobsen nel suo motore di gioco Hitman.

Da un'esperienza in qualche modo pratica, le forze di penalità (simili alle molle lineari o esponenziali che ottengono il loro input dalla distanza di penetrazione) non risolvono adeguatamente le penetrazioni quando altre forze dei corpi che si scontrano riescono ad essere più grandi di loro. Ecco perché ho scelto di combinare tre approcci (quasi ridondanti): forze di reazione newtoniane (spingi il muro, il muro spinge indietro), velocità derivate dagli impulsi (palle da biliardo che si scontrano) e un non naturale "allontanano geometricamente i corpi l'uno dall'altro "soluzione. Insieme sembrano fornire tutto: sbarazzarsi di piùbrutti artefatti di compenetrazione, corpi in collisione tendono ad interagire tra loro nel lungo periodo (a causa delle velocità e delle forze di restituzione - almeno le forze che tendevano a trascinare i corpi in uno scenario di collisione vengono cancellate e i corpi rimbalzano l'uno dall'altro) . Infine, per un'ulteriore comprensione di questi concetti semplici ma comuni, suggerisco di analizzare queste diapositive .

Il mio epiteto del "metodo abusato" che descrive i passaggi dell'integrazione di Verlet è mirato alla credenza della cultura popolare che questo è il Santo Graal dei metodi di integrazione. È solo leggermente migliore del suo cugino Symplectic Euler (chiamato anche da alcuni Euler semi-implicito). Esistono metodi di integrazione più complicati (e tutti hanno il nome implicito in essi). Potenti motori di gioco li usano, ma gli sviluppatori indipendenti non hanno il tempo di sperimentare quelli dal momento che Verlet, quando sintonizzato su uno scenario specifico, fa davvero meraviglie. Inoltre, non esiste assolutamente alcun metodo di integrazione in grado di gestire i vincoli rigidi senza essere coinvolto in un piccolo imbroglio (non è possibile trovare il collegamento, ma il documento a cui mi riferisco dovrebbe essere chiamato "X.Provot -" Vincoli di deformazione in una massa modello a molla per descrivere il comportamento del tessuto rigido "


Grazie (+1)! Cosa sono la "velocità di restituzione" e gli "spostamenti di penalità"? Inoltre, perché dici che l'integrazione del verlet è "abusata"? Pensi che sia un cattivo metodo da usare?
Cam

Le velocità di restituzione sono esattamente quelle velocità che si ottengono dagli impulsi, l'unica differenza è che le computo come residui (cioè memorizzo la differenza tra quella velocità basata su quell'impulso e la velocità corrente mantenendo intatta la velocità corrente per ulteriori calcoli). Gli spostamenti di penalità sono vettori con una lunghezza determinata da quanti due oggetti si compenetrano ed è il vettore di lunghezza minima che può tradurre un oggetto completamente al di fuori dell'altro. Di solito aggiungo un tale spostamento a ciascun oggetto dividendo la lunghezza per 2).
teodron,

1
Risposta brillante! Ho un'altra domanda. Supponiamo che accumuli le velocità di restituzione, non si sommeranno a un numero molto non realistico? Se tratto ogni collisione con l'oggetto A separatamente e sommo semplicemente gli effetti su ciascun oggetto, A non avrebbe il suo impulso distribuito tra gli oggetti? Invece a ciascuno di essi verrà applicato un pieno impulso che mi sembra intuitivamente sbagliato
Cam

Questa è un'ottima domanda .. da un punto di vista, sembra plausibile che gli impulsi contribuiscano in modo aggiuntivo alla velocità risultante. Ecco il mio ragionamento (forse difettoso!): Immagina che tre palle da biliardo / snooker si scontrino. Uno di loro dovrebbe ricevere contributi dagli altri due in questo modo additivo. Inizialmente, ho pensato di soppesare questi contributi e calcolare una media ponderata per la velocità finale, ma poiché volevo risultati rapidi, ho saltato questa idea. Tutto sommato, la palla in collisione deve ottenere contributi di velocità dai restanti due. Forse un libro di testo di scuola superiore può aiutare.
teodron,

3
Forse non capisco quello che hai spiegato, perché il seguente esempio mi riguarda ancora: considera un rettangolo lungo orizzontalmente che cade verso il basso e supponi che il pavimento sia frastagliato (quindi composto da più triangoli affiancati). Se ci sono n triangoli, usando il tuo metodo cumulativo, il rettangolo tornerà indietro a n volte la velocità che dovrebbe! Come si può risolvere quella situazione?
Cam

1

Suggerisco che, invece di cambiare velocità, cambi le forze che agiscono su un oggetto. Non "spingerli" piuttosto, piuttosto, farlo senza problemi e utilizzando il codice già esistente. In questo modo i corpi non cambieranno immediatamente (e rapidamente, suppongo) le loro velocità.

Dai un'occhiata a Box2DJS per un esempio: http://box2d-js.sourceforge.net/index2.html .


-1

Ho risolto analiticamente l'equazione degli impulsi per gruppi di corpi in collisione. L'unico problema che ho affrontato è stata la mancanza di variabili per trovare la forza di interazione relativa tra i contatti in un gruppo, che ho riempito con la profondità dell'intersezione dei corpi.

La soluzione per i contatti di gruppo non è molto più difficile del contatto singolo. Purtroppo ho perso un documento con i calcoli, quindi non sono riuscito a condividerlo qui.

Modifica: Probabilmente ho inventato qualcosa del genere /physics/296767/multiple-colliding-balls

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.