Tecniche di rilevamento delle collisioni del motore di fisica continua


10

Sto lavorando su un motore fisico puramente continuo e devo scegliere algoritmi per il rilevamento di collisioni in fase ampia e stretta. "Puramente continuo" significa che non eseguo mai test di intersezione, ma invece voglio trovare il modo di catturare ogni collisione prima che accada, e inserirle tutte nello stack "collisioni pianificate" che viene ordinato da TOI.

Fase larga L'unico metodo continuo a fase larga che mi viene in mente è quello di racchiudere ogni corpo in un cerchio e verificare se ogni cerchio si sovrapporrà mai a un altro. Questo sembra orribilmente inefficiente e manca di abbattimento.

Non ho idea di quali analoghi continui potrebbero esistere per i metodi di abbattimento delle collisioni discrete di oggi come i quad-alberi. Come potrei fare per prevenire test ampi inappropriati e inutili come fa un motore discreto? Vorrei anche essere in grado di vedere le collisioni più di 1 fotogramma avanti.

Narrow Phase
Sono riuscito ad adattare lo stretto SAT a un controllo continuo piuttosto che discreto, ma sono sicuro che ci sono altri algoritmi migliori là fuori in documenti o siti che potresti aver incontrato.
Quali vari algoritmi veloci o precisi mi consigliate di utilizzare e quali sono i vantaggi / gli svantaggi di ciascuno?

Nota finale:
dico tecniche e non algoritmi perché non ho ancora deciso in che modo memorizzare diversi poligoni che potrebbero essere concavi, convessi, rotondi o addirittura dotati di buchi. Ho intenzione di prendere una decisione in base a ciò che richiede l'algoritmo (ad esempio, se scelgo un algoritmo che suddivide un poligono in triangoli o forme convesse, memorizzerò semplicemente i dati del poligono in questo modulo).



Mi dispiace aggiungere, ma perché non usare Box2D? È stato portato in quasi tutte le lingue. Se non hai intenzione di usarlo, perché non navigare nella sua fonte in modo da poter vedere come gestisce la sua collosione?
Derek,

Risposte:


2

Sto davvero solo gettando idee qui. Supponendo di avere (almeno) la currentposizione e la nextposizione; per ogni fotogramma.

Avresti bisogno di due ampie fasi separate, seguite dalla tua fase stretta:

  • Uno che scopre che si verificherà una collisione.
  • Uno che capisce approssimativamente dove si verifica effettivamente la collisione (ad esempio una fase ampia / SAT impreciso)
  • Infine, la tua fase ristretta migliorerebbe il risultato della seconda fase ampia.

Fase ampia iniziale

Potresti esaminare l'hashing spaziale (usando la nextposizione, non current) per la fase ampia iniziale. Ciò dividerebbe bene lo spazio del problema in gruppi di candidati alla collisione.

Seconda fase ampia

Esegui un campione multiplo binario usando il metodo di intersezione del cerchio che hai descritto. In altre parole:

left = current
right = next
midpoint = (left + right) / 2
loop a desired amount of times tweaked to the accuracy you want:
  is a collision occuring at midpoint?
    right = midpoint
  else?
    left = midpoint
  midpoint = (left + right) / 2
pointOfCollision = midpoint

Quella correzione di precisione potrebbe anche prendere in considerazione la distanza - penso che l' uso del "quadrato al quadrato" di next - currentottenere un risultato perfetto per i pixel.

Fase stretta

Fai un multi-campione binario usando qualcosa come PMask - la logica sarà esattamente la stessa di cui sopra; semplicemente usando una diversa routine di collisione.

Finalmente

Sarai in grado di calcolare il tempo di intersezione da pointOfCollision, currente la tua corrente speede acceleration(supponendo che tu abbia un integratore ragionevole).


Quindi, per il rilevamento secondario della fase larga, stai suggerendo di ottenere il punto medio del percorso di spostamento del cerchio e testare se è all'interno del cerchio da testare? Stavo pensando di poter semplicemente creare un'equazione che dia i due cerchi distanza l'una dall'altra nel tempo, e vedendo se in qualsiasi momento la distanza è uguale a 0.
Griffin,

Inoltre, cosa fa esattamente Pmask? il sito non spiega davvero = /.
Griffin,

@Griffin il tuo primo commento potrebbe funzionare - vedi se riesci a capire. Fondamentalmente sto facendo una ricerca binaria su uno spazio di collisione ... PMask è piuttosto intelligente. Vedi un 64-int senza segno come una griglia di pixel 8x8 (acceso / spento) - un semplice AND (binario) determina se si sta verificando una collisione (diversa da zero); devi prima fare un po 'di bit shifting intelligente, ma questa è l'idea. Leggi la fonte per maggiori informazioni; è difficile da spiegare qui (o meglio, la mia spiegazione farebbe schifo) - devi davvero fare riferimento alla fonte.
Jonathan Dickinson,

1

Bene, ho visto che hai aggiornato la tua domanda in modo da essere più specifico. Proverò ad aiutarti ancora.

Per il tuo primo controllo a fase larga, consiglio vivamente l'hash spaziale .

In sostanza, dividi lo schermo in griglie di dimensioni uguali. Quindi, se un oggetto si trova all'interno di una griglia, lo si aggiunge a un "bucket" in una tabella hash 1D.

Questo è il tuo primo controllo fatto. Se gli oggetti non si trovano nello stesso bucket, sarebbe impossibile per loro incrociarsi.

Continuando con quello, ora hai un elenco di secchi con oggetti (potenzialmente) in essi. Puoi fare un altro controllo in fase larga qui:

A.) Dividere questo bucket in altri 4 bucket e controllare la tabella di hash 1D risultante. Se non sono nello stesso secchio, nessuna collisione.

O:

B.) Fare un semplice controllo della distanza e tenere a mente la larghezza e / o l'altezza dell'oggetto per garantire la precisione.

Ma che dire di quando potenzialmente hai una collisione?

Poi mi sento di raccomandare qualcosa sulla falsariga di questo . È essenzialmente una sorta di mix tra collisione poligonale (per forme complesse) o rettangolo / cerchio per forme meno complesse.

Inoltre, se vuoi davvero "catturare le collisioni prima che si verifichino e archiviarle", puoi sempre fare qualcosa del genere:

Se due oggetti si trovano nello stesso bucket, potrebbero scontrarsi.

Inoltre, gli oggetti sono abbastanza vicini da potersi scontrare presto? (Tenendo conto della velocità, della dimensione e della distanza dell'oggetto)

Se la risposta ad entrambi è sì, vai avanti e memorizzalo per fare un test di intersezione in un secondo momento.


" Vecchia risposta

Bene, sfortunatamente ho perso la traccia del mio manuale "Tutti i tipi di collisione e per cosa vengono utilizzati". :)

Tuttavia, anche se questa è una missione estremamente ampia, ti inizierò.

C'è una buona (risposta) domanda relativa a qualcosa di simile qui .

Oltre a un articolo delle persone che hanno realizzato N e N + qui .

Per non parlare del fatto che hai ottenuto il buon vecchio fallback Per-pixel Collision .

Dubito sinceramente che qualcuno avrà un elenco a portata di mano per ogni tipo di collisione, ma questo dovrebbe aiutarti a iniziare.

Tuttavia, dovrei menzionare che il tipo di collisione di cui hai bisogno (e che finirai per usare) dipende in gran parte dal tipo di gioco che stai creando. Ecco perché trovi tutorial: la maggior parte delle persone presume che tu abbia un'idea di ciò che desideri, quindi ti aiutano in quella specifica area. Mi rendo conto che la maggior parte dei miei link sono tutorial su un argomento specifico, ma penso che un tutorial onestamente ti aiuterà di più. Una lista è una cosa, ma se leggi tu stesso ogni punto elenco, puoi arrivare a una decisione più istruita che probabilmente soddisferà le tue esigenze in modo più specifico.


Ho dimenticato di aggiungere il metodo su cui ho basato la mia collisione (Per-Pixel usando uno scafo design) Perdonate l'archivio, il sito originale è andato nel paradiso del sito web. web.archive.org/web/20090126230334/http://www.ziggyware.com/…
electroflame
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.