J'utilise Bullet et j'essaie de créer un algorithme de collision qui génère des points de contact hors d'un terrain basé sur un cube avec la réponse de collision appropriée. Je prévois également d'étendre cela pour inclure également les formes non-boîte, mais ce n'est pas vital pour le moment. J'ai trouvé que l'utilisation d'un maillage triangle est trop de porc RAM pour les grandes cartes.
J'ai essayé la procédure décrite par Byte56 ici , cependant, j'ai un certain nombre de questions concernant la mise en œuvre de cela avec Bullet:
- Comment générer une forme de collision pour le monde? Utilisez-vous une forme personnalisée? Que comptez-vous
m_shapeType
y faire? - Ou utilisez-vous toujours une boîte de la taille du monde?
- Comment assurez-vous que les points de contact sont libérés?
- Comment modifiez-vous exactement
processCollision
?
Ce que j'ai fait:
- J'ai créé un terrainShape
that extends
btBoxShape, the only difference being that
m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE`, afin que je puisse enregistrer un nouvel algorithme de collision avec le répartiteur pour les objets ayant uniquement cette forme. - J'ai étendu la
btRigidBody
classe d'une manière similaire à Byte56 dans sa question (voir le lien dans le 2ème paragraphe), maischeckCollisionWith(CollisionObject * co)
renvoie vrai si aucun voxel dans l'AABBco
n'est pas aérien. J'ai étendu la
btCollisionAlgorithm
classe, d'une manière similaire àbtCompoundCollisionAlgorithm
, enprocessCollision
procédant comme suit:- Vérifiez les objets en collision passés comme arguments et déterminez quel est le terrain et quelle est l'entité.
- Effacez les multiples algorithmes enfants.
- Appel
resultOut->setPersistantManifold(resultOut)
- Générez de nouvelles formes de boîte et transforme dans l'AABB occupé par l'entité en collision, puis appelez
m_dispatcher->findAlgorithm
. Stockez la forme, la transformation et l'algorithme trouvé dans une structure d'algorithme enfant pour chaque voxel dans l'AABB. - Itérer sur tous les algorithmes enfants, appelant
proccessCollision
. - Itérer sur tous les algorithmes enfants, en supprimant ceux qui se trouvent maintenant en dehors de l'AABB de l'entité en collision. (appelant
~btCollisionAlgorithm()
alorsm_dispatcher->freeCollisionAlgorithm()
) - Appelle
resultOut->refreshContactPoints()
.
Ce qui fonctionne: processCollision
est appelé chaque fois que l'AABB du joueur croise des voxels non aériens.
Ce qui ne fonctionne pas: la réponse à la collision est tout simplement bizarre ... L'entité joueur commence à léviter vers le haut. S'il entre dans quelque chose, il rebondit violemment. Parfois, il est incapable de continuer à se déplacer sur un axe après être entré dans quelque chose. Ce que je soupçonne, c'est que les points de contact ne sont pas libérés après la réponse à la collision, peut-être parce que l'entité du joueur est toujours dans l'AABB de l'objet mondial. Je suis curieux de voir si j'aboie le bon arbre par rapport à processCollision
?
la source
Réponses:
Malheureusement, je n'ai pas pu obtenir de résultats fiables à partir de la méthode décrite dans la réponse à laquelle vous faites référence . Comme pour vous, j'obtiendrais des événements flottants étranges, ou des situations où la suppression d'un voxel ferait en sorte que des objets flottant au-dessus d'eux restent flottants dans l'air, ou feraient tomber une étrange plume oscillante au sol. J'ai abandonné cette stratégie pour une nouvelle stratégie.
J'ai commencé à créer des maillages de collision personnalisés pour chaque morceau de terrain voxel. Je fais ça avec le
BvhTriangleMeshShape
. Cela fonctionne plutôt bien:Il y a plus de détails sur l'implémentation des maillages de collision personnalisés ici .
la source