PDA

View Full Version : [C# XNA C++ ..]Collisioni e BoundingSphere


WILEz
01-06-2008, 13:46
Aiuto..sto impazzendo.
Dovrei impostare la Y di un oggetto in base alla collisione con delle BoundingSphere..
Mi spiego:

Ho il mio terreno che, su ogni vertice ha una BoundingSphere.
Il mio personaggio (che è una navetta..) prosegue fino ad incontrare una salita e dunque, dovrebbe salire.

http://www.wilez.it/bs1.jpg

Ora, se faccio così:
IF (collide con la BoundingSphere[i]) {Y.personaggio = Y. BoundingSphere} funziona, cioè il personaggio sale ma il movimento risulta ovviamente a "scalini" perchè il terreno non ha un vertice ogni pixel e dunque sale di un "tot" in base alla Y della BoundingSphere incontrata. Dovrei calcolare la Y del personaggio in base alla BoundingSphere attualmente in collisione e la BoundingSphere in collisione in precedenza...


http://www.wilez.it/bs2.jpg

Conoscendo le posizioni XYZ di A , di B e di P, rilevando la collisione con le BoundingSphere (cerchi gialli), come posso dire che la Y di P deve essere quella, in base alla distanza di P con A e B?



Anche così:
if (Posizione_nave1.Y <= bs_vertex[i].Center.Y) {
Posizione_nave1.Y+=Velocità;
}
if (Posizione_nave1.Y >bs_vertex[i].Center.Y)
{
Posizione_nave1.Y -= Velocità;
}

la cosa migliora un po' ma sempre a scalini si muove..

P.S. Si tratta di C#/XNA ma la teoria è la stessa a prescindere dal linguaggio..

_Xel_^^
01-06-2008, 14:39
Scusa ma la bouning sphere solitamente è usata per contenere oggetti... secondo me sbagli a voler usare una sfera per ogni vertice del terreno!
A meno che non vuoi fare qualcosa di particolare che allora non ho capito :D

Comunque dovresti fare una b-sphere per la navetta e rilevare le collisioni tra questa e i poligoni del terreno, magari dividendolo in aree in modo che il test alla fine lo fai tra pochi poligoni escludendo a priori quelli più distanti.

Però se il tuo terreno non è una mesh complessa ma una semplice griglia (come mi pare dall'immagine) ti basta prendere il punto dove si trova la navetta, trovi subito il poligono sottostante, interpoli tra le altezze dei vertici del triangolo in cui si trova e hai subito l'altezza giusta per la navetta che così seguirà fluidamente il terreno e non a scatti :)

Ciau!

WILEz
01-06-2008, 18:10
Posso anche non usare le Bsphere ma il problema rimane.

Però se il tuo terreno non è una mesh complessa ma una semplice griglia (come mi pare dall'immagine) ti basta prendere il punto dove si trova la navetta, trovi subito il poligono sottostante, interpoli tra le altezze dei vertici del triangolo in cui si trova e hai subito l'altezza giusta per la navetta che così seguirà fluidamente il terreno e non a scatti

Non mica capito.. La mesh è una griglia di cui io conosco la posizione dei vertici.. come faccio a "trovare" il poligono sottostante? Posso trovare il vertice sottostante ma il poligono..come? Per "interpoli" intendi dire fare una media delle altezze dei tre vertici? Se è così alla fine scatta lo stesso no? Ogni poligono un punto solo di posizione per la navetta no?

WILEz
01-06-2008, 19:09
Ok, ho eliminato le BSphere.. Ora la collisione viene rilevata dalla distanza tra la nevetta e i singoli vertici della griglia.. Il problema resta. Cosa vuol dire interpolare? Non credo che sia la stessa interpolazione che fa il 3DS o Flash che crea il movimento tra due fotogrammi.. C'è attinenza?

_Xel_^^
01-06-2008, 20:05
Allora... tu sai la dimensione della tua griglia, ad esempio 100x100 vertici memorizzata in una variabile, ad esempio una matrice che contiene le altezze di tutti questi vertici.
Nello spazio questi vertici li posizioni alla distanza che vuoi, ad esempio uno ogni 10 unità e hai quindi una griglia dove ogni 10 unità c'è un vertice. Hai così 99 poligoni per lato.
Se ad esempio metti la navetta alla posizione (235,512) sapendo che ogni vertice dista 10 unità dall'altro hai già le posizioni dei vertici del poligono in cui si trova.
I vertici del poligono avranno quindi le coordinate (230,510) (240,510) (240,520) (230,520). Come vedi la navetta sta in mezzo a queste coordinate!
Se poi dividi per 10 trovi gli indici della matrice dove trovi anche le altezze!

Ora come avrai visto un "poligono quadrato" è formato da due triangoli e puoi trovare facilmente in quale dei due sei capitato.
Fatto questo ti rimangono solo TRE vertici con cui fare i conti di cui conosci tutte le coordinate. Questi sono per forza di cose sullo stesso piano e quello che si vuole ottenere è che la navetta scivoli su questo piano, che è ben differente dal fare la media delle altezze! ;)
In pratica è tutta matematica/geometria analitica e qua lo trovi spiegato molto meglio di come farei io :D http://www.toymaker.info/Games/html/terrain_follow.html


Ciau!
PS. spero si sia capito qualcosa perchè faccio schifo a spiegare :asd:
PPS. come vedi vettori, matrici, piani, interpolazioni, normali, prodotti vettoriali saranno all'ordine del giorno nella grafica 3D :D cerca di farti qualche base leggendo qualcosa in giro ;)

WILEz
04-06-2008, 16:21
Grazie per la risposta, vedrò di smanettare su quanto mi hai detto.
A dire il vero la mia griglia non ha i vertici posizionati in modo così sistematico, si tratta di un file .x che creo con 3dsMax ma alla fine si tratta comunque di una griglia che posso anche creare con poligoni quadrati di dimensioni constanti.
Poi, grazie ad uno script che mi sono scritto appositamente, riesco a salvare le coordinate di tutti i vertici su un file di testo seguendo una formattazione che ho impostato io ( 512_324_432; 432_432_411; ....) così, al caricamento del livello mi carico le posizioni dei vertici in un array, le splitto e ottengo le mie coordinate, xyz di ogni vertice. Le coordinate della navetta le conosco sempre ma dicendogli che "se le coordinate XZ della navetta sono uguali alle XY del vertice, allora la coordinata Y della navetta deve essere uguale alla coordinata Y del vertice", funziona ma scatta.

Ora, da quanto ho capito dovrò calcolare la posizione della navetta non in base hai vertici ma in base al "quadrato" su cui si trova e poi interpolare i vertici di quel "quadratao" per calcolare l'altezza del "pixel" su cui si trova la nave.. credo.:muro:

_Xel_^^
04-06-2008, 20:40
Esatto :)
Però se la tua mesh del terreno non la generi in modo regolare hai in più il problema di trovare il poligono su cui ti trovi... e qui torna in gioco la b-sphere!
Tieni poi conto che se il terreno è grande non ha senso cercare la collisione tra tutti i poligoni... ci sono vari metodi che consistono nel suddividere il terreno in gruppi di più poligoni per potere fare confronti del tipo: "sono in questa zona del terreno, dentro questa zona sono in quest'altra zona più piccola, ok mi rimangono pochi poligoni vediamo su quale collido".
Questo è anche utile per effettuare frustum-culling per le aree del terreno che non sono visibili.

Se invece vuoi partire da qualcosa di semplice posso consigliarti di generare il terreno da un'immagine a scala di grigi (heightmap)!
esempio: http://www.hypeskeptic.com/mattias/Landscaper/Images/Islands.jpg
A ogni colore corrisponde un'altezza (che poi potrai moltiplicare per un fattore che vuoi tu per rendere più o meno alto il dislivello), nero = 0 bianco = 255, la disegni come vuoi, la salvi in raw con un programma di fotoritocco e otterrai un file dove ogni byte corrisponde a un vertice quindi con un'immagine di 101x101 pixel potrai costruire un terreno di 100x100 poligoni!
Così trovi anche tanti esempi da caricare in giro e puoi farci cose molto carine ;)

Ciau!

WILEz
05-06-2008, 08:18
Grazie ancora delle risposte, farò altre prove..
Le HeigthMap le ho provate, all'inizio l'idea era quella di mettere sotto al livello una HMap invisibile che rilevasse le collisioni e sopra il livello vero che veniva renderizzato così da sfruttare i dettagli della mesh creata con 3DS e rilevare le collisioni in modo più semplice, ma le differenze tra le HMap e la mesh erano troppe e non mi permettevano di fare cose tipo "sopraelevate"(una strada che passa sopra l'altra con le HMap non si può ovviamente fare)..

Continuo a provare e vediamo che riesco a tirare fuori:stordita:
Ciao e grazie!