Sto usando Bullet e sto tentando di creare un algoritmo di collisione che genera punti di contatto al di fuori di un terreno basato su cubi insieme alla risposta di collisione appropriata. Ho anche intenzione di estenderlo per includere anche le forme non-box, tuttavia non è vitale al momento. Ho scoperto che l'uso di una mesh triangolare è troppo di un maiale RAM per le mappe di grandi dimensioni.
Ho provato la procedura descritta da Byte56 qui , tuttavia, ho una serie di domande relative all'implementazione di questo con Bullet:
- Come si genera una forma di collisione per il mondo? Usi una forma personalizzata? Che cosa hai intenzione
m_shapeType
di essere su di esso? - O usi ancora una scatola dalle dimensioni del mondo?
- Come garantire che i punti di contatto vengano liberati?
- Come si modifica esattamente
processCollision
?
Quello che ho fatto:
- Ho creato un terrainShape
that extends
btBoxShape, the only difference being that
m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE`, per consentirmi di registrare un nuovo algoritmo di collisione con il dispatcher per oggetti con solo questa forma. - Ho esteso la
btRigidBody
classe in un modo simile a Byte56 nella sua domanda (vedi il link nel 2 ° paragrafo), tuttaviacheckCollisionWith(CollisionObject * co)
restituisce vero se qualsiasi voxel nell'ABDco
non è aereo. Ho esteso la
btCollisionAlgorithm
classe, in un modo simile abtCompoundCollisionAlgorithm
,processCollision
facendo quanto segue:- Controlla gli oggetti in collisione passati come argomenti e determina quale è il terreno e quale è l'entità.
- Cancella le molteplici eventuali algoritmi figlio.
- Chiamata
resultOut->setPersistantManifold(resultOut)
- Genera nuove forme e trasformazioni di casella nell'ABD occupato dall'entità in collisione, quindi chiama
m_dispatcher->findAlgorithm
. Memorizza la forma, trasforma e trova l'algoritmo in una struttura Algorithm figlio per ogni voxel all'interno dell'AABB. - Scorrere su tutti gli algoritmi figlio, chiamando
proccessCollision
. - Scorrere su tutti gli algoritmi figlio, rimuovendo qualsiasi ora al di fuori dell'AABB dell'entità in collisione. (chiamando
~btCollisionAlgorithm()
quindim_dispatcher->freeCollisionAlgorithm()
) - Chiama
resultOut->refreshContactPoints()
.
Cosa funziona: processCollision
viene chiamato ogni volta che l'AABB del giocatore si interseca con voxel non aerei.
Cosa no: la risposta alla collisione è semplicemente strana ... L'entità giocatore inizia a levitare verso l'alto. Se entra in qualcosa, rimbalza violentemente. A volte, non è possibile continuare a muoversi su un asse dopo essere entrati in qualcosa. Ciò che sospetto stia accadendo è che i punti di contatto non vengano rilasciati dopo la risposta alla collisione, probabilmente a causa dell'entità giocatore che si trova sempre nell'ABS dell'oggetto mondiale. Sono curioso di vedere se sto abbaiando l'albero giusto rispetto a processCollision
?