Saya menggunakan Bullet, dan saya berusaha membuat algoritma tabrakan yang menghasilkan titik kontak dari medan berbasis kubus bersama dengan respons tabrakan yang sesuai. Saya juga berencana untuk memperluas ini untuk memasukkan bentuk non-kotak juga, namun itu tidak penting saat ini. Saya telah menemukan bahwa menggunakan mesh segitiga adalah terlalu banyak babi RAM untuk peta besar.
Saya telah mencoba prosedur yang diuraikan oleh Byte56 di sini , namun, saya memiliki sejumlah pertanyaan mengenai penerapan ini dengan Bullet:
- Bagaimana Anda menghasilkan bentuk tabrakan untuk dunia? Apakah Anda menggunakan bentuk khusus? Apa yang Anda tentukan
m_shapeType
? - Atau apakah Anda masih menggunakan bentuk kotak seukuran dunia?
- Bagaimana Anda memastikan bahwa titik kontak dibebaskan?
- Bagaimana tepatnya Anda memodifikasi
processCollision
?
Apa yang telah kulakukan:
- Saya telah membuat terrainShape
that extends
btBoxShape, the only difference being that
m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE`, agar saya dapat mendaftarkan algoritme tabrakan baru dengan dispatcher untuk objek hanya dengan bentuk ini. - Saya telah memperluas
btRigidBody
kelas dengan cara yang mirip dengan Byte56 dalam pertanyaannya (lihat tautan di paragraf ke-2), namuncheckCollisionWith(CollisionObject * co)
mengembalikan true jika ada voxel di AABB ofco
bukan udara. Saya telah memperluas
btCollisionAlgorithm
kelas, dengan cara yang mirip denganbtCompoundCollisionAlgorithm
, denganprocessCollision
melakukan hal berikut:- Periksa objek bertabrakan yang dilewatkan sebagai argumen, dan tentukan yang merupakan medan, dan yang merupakan entitas.
- Kosongkan bermacam-macam algoritma anak.
- Panggilan
resultOut->setPersistantManifold(resultOut)
- Hasilkan bentuk dan transformasi kotak baru di AABB yang ditempati oleh entitas yang bertabrakan, lalu panggil
m_dispatcher->findAlgorithm
. Simpan bentuk, transformasi, dan algoritme yang ditemukan dalam struct Algoritma Anak untuk setiap voxel dalam AABB. - Iterate atas semua algoritma anak, memanggil
proccessCollision
. - Ulangi semua algoritme anak, hapus semua yang ada di luar AABB dari entitas yang bertabrakan. (menelepon
~btCollisionAlgorithm()
kemudianm_dispatcher->freeCollisionAlgorithm()
) - Panggil
resultOut->refreshContactPoints()
.
Yang berfungsi: processCollision
disebut setiap kali AABB pemain bersinggungan dengan non-air voxels.
Apa yang tidak: respons tabrakan benar-benar aneh ... Entitas pemain mulai melayang ke atas. Jika itu masuk ke sesuatu, itu memantul dengan keras. Terkadang, ia tidak dapat terus bergerak pada satu poros setelah berjalan ke sesuatu. Yang saya duga sedang terjadi adalah bahwa titik kontak tidak dilepaskan setelah respons tabrakan, mungkin karena entitas pemain selalu berada di AABB objek dunia. Saya ingin tahu apakah saya menggonggong pohon yang tepat sehubungan dengan processCollision
?
sumber
Jawaban:
Sayangnya saya tidak bisa mendapatkan hasil yang andal dari metode yang dijelaskan dalam jawaban yang Anda referensikan . Mirip dengan Anda, saya akan mendapatkan peristiwa mengambang aneh, atau situasi di mana mengeluarkan voxel akan menyebabkan benda-benda yang mengambang di atasnya tetap mengambang di udara, atau melakukan bulu berosilasi aneh jatuh ke tanah. Saya meninggalkan strategi itu untuk strategi baru.
Saya mulai membuat jerat tabrakan khusus untuk setiap bagian dari medan voxel. Saya melakukannya dengan
BvhTriangleMeshShape
. Ini bekerja dengan cukup baik:Ada detail lebih lanjut tentang implementasi jerat tabrakan khusus di sini .
sumber