\\ Home : Articoli : Stampa
IntersectMesh
Di RobyDx (del 25/07/2007 @ 16:43:42, in DirectX9, linkato 1849 volte)

Una delle funzioni che non può mancare in un programma CAD è la possibilità di spostare un oggetto con il mouse. La cosa è tutt'altro che semplice perchè richiede numerosi conti e soprattutto un buon sistema di collisioni. DirectX ci viene incontro offrendoci una istruzione chiamata IntersectMesh che ci permette di ottenere facilmente il rayCollision, ossia la collisione di una semiretta con una mesh in modo da ottenere qualsiasi dato sull'impatto. La cosa può risultare peraltro utile per calcolare le collisioni di spari (che sono essenzialmente immediati ed in linea retta) ed in definitiva in molte situazioni di calcolo di collisioni. Ad esempio possiamo verificare se una linea che va da noi ad un nemico è interposta da un muro e quindi regolarci di conseguenza.

L'istruzione è un metodo della mesh:

m.intersectMesh(

dove m è un oggetto di tipo mesh (o progressive mesh).

L'istruzione ha 4 forme ma in tutte richiede come primo parametro un vettore che contiene il punto da cui parte il raggio e come secondo un altro vettore che contiene la direzione (si calcola come vettore contenente la posizione finale meno il vettore contenente la posizione iniziale). Il metodo restituisce un booleano che indica l'avvenuta collisione o meno. Gli altri parametri per le altre forme sono una variabile o un array di

IntersectInformation

questa variabile contiene le informazioni sul punto di impatto più vicino (se gli viene passata variabile), o su tutti gli impatti se gli viene passato un array. I parametri sono:

dist: distanza dall'origine del raggio all'intersezione

u,v: coordinate del baricentro

faceIndex: numero della faccia colpita dal raggio

Per ottenere l'intersezione con un punto 2D sullo schermo (esempio le coordinate del mouse) occorre fare l'unproject del vettore (conversione dallo spazio dello schermo allo spazio 3D). La funzione è questa

Function intersectM(ByVal X As Single, ByVal Y As Single, ByVal m As Mesh, ByVal matW As Matrix, ByRef numF As Long) As Boolean
Dim vista As Viewport
Dim punto As Vector3
Dim frontV As Vector3
Dim backV As Vector3
Dim DirectionV As Vector3
'ottiene la vista
vista = device.Viewport
punto.X = X : punto.Y = Y
'trasforma il punto dato in coordinate DirectX nel piano con z=-100
punto.Z = -100
frontV = Vector3.Unproject(punto, vista, device.Transform.Projection, device.Transform.View, matW)
'trasforma il punto dato in coordinate DirectX nel piano con z=100
punto.Z = 100
backV = Vector3.Unproject(punto, vista, device.Transform.Projection, device.Transform.View, matW)
'crea il vettore direzione
DirectionV = Vector3.Subtract(frontV, backV)
Dim b As Boolean
Dim interInfo As IntersectInformation
b = m.Intersect(frontV, DirectionV, interInfo)
If b Then
numF = interInfo.FaceIndex
End If
Return b
End Function

Restituisce un booleano che indica il contatto e nell'ultimo parametro mette il numero della faccia toccata. Chiede la matrice World. Il motivo principale è che l'intersect mesh viene calcolato in posizione neutra (matrice identità). Quindi non possiamo trasformare la mesh ma dobbiamo trasformare in inversione i punti di contatto. Fate attenzione a questo perchè vi complicherà i conti durante intersezioni complesse.

Esiste anche

IntersectSubset

Questa vi permette di calcolare l'intersezione su una sola subset (quelle usate in rendering).

Vi lascio all'esempio.

Esempio VB.Net