Dengan hanya 30 objek maks, Anda tidak perlu banyak optimasi sama sekali selain untuk tidak memeriksa dua pasangan yang sama satu sama lain lebih dari sekali per frame. Yang akan dicakup contoh kode di bawah ini. Tetapi jika Anda menarik dalam berbagai optimisasi yang akan digunakan mesin fisika, lanjutkan membaca sisa posting ini.
Yang Anda perlukan adalah implementasi partisi spasial , seperti Octree (untuk game 3D) atau Quadtree (untuk game 2D). Ini mempartisi dunia menjadi sub-bagian, dan kemudian masing-masing sub-bagian dipartisi lebih lanjut dalam manor yang sama, sampai mereka dibagi menjadi ukuran minimum. Ini memungkinkan Anda untuk dengan cepat memeriksa objek mana yang berada di wilayah yang sama dengan yang lain di dunia, yang membatasi jumlah tabrakan yang harus Anda periksa.
Selain partisi spasial saya akan merekomendasikan membuat AABB ( Axis-aligned box ) untuk masing-masing objek fisika Anda. Ini memungkinkan Anda untuk memeriksa AABB dari satu objek terhadap yang lain, yang jauh lebih cepat daripada cek per-poli rinci antara objek.
Ini dapat diambil selangkah lebih jauh untuk objek fisika yang rumit atau besar, di mana Anda dapat membagi mesh fisika itu sendiri, memberikan masing-masing sub-bentuk AABB sendiri yang dapat Anda periksa hanya jika AABB dua objek saling tumpang tindih.
Sebagian besar mesin fisika akan menonaktifkan simulasi fisika aktif pada tubuh fisika begitu mereka beristirahat. Ketika sebuah tubuh fisika dinonaktifkan, ia hanya perlu memeriksa tabrakan terhadap AABB setiap frame, dan jika ada sesuatu yang bertabrakan dengan AABB maka ia akan mengaktifkan kembali dan melakukan pemeriksaan tabrakan yang lebih granular. Ini menjaga waktu simulasi turun.
Juga, banyak mesin fisika menggunakan 'pulau simulasi', yang merupakan tempat sekelompok badan fisika yang berdekatan dikelompokkan bersama. Jika semua yang ada di pulau simulasi diam maka pulau simulasi itu sendiri akan dinonaktifkan. Manfaat dari pulau simulasi adalah bahwa semua benda di dalamnya dapat berhenti memeriksa tabrakan begitu pulau tidak aktif, dan satu-satunya memeriksa setiap frame adalah untuk melihat apakah ada sesuatu yang memasuki AABB pulau. Hanya sekali sesuatu memasuki AABB pulau maka masing-masing badan di dalam pulau perlu memeriksa tabrakan. Pulau simulasi juga mengaktifkan kembali jika benda di dalamnya mulai bergerak sendiri. Jika suatu benda bergerak cukup jauh dari pusat kelompok, ia dikeluarkan dari pulau.
Pada akhirnya Anda dibiarkan dengan sesuatu seperti ini (dalam pseudo-code):
// Go through each leaf node in the octree. This could be more efficient
// by keeping a list of leaf nodes with objects in it.
for ( node in octreeLeafNodes )
{
// We only need to check for collision if more than one object
// or island is in the bounds of this octree node.
if ( node.numAABBsInBounds > 1)
{
for ( int i = 0; i < AABBNodes.size(); ++i )
{
// Using i+1 here allows us to skip duplicate checks between AABBS
// e.g (If there are 5 bodies, and i = 0, we only check i against
// indexes 1,2,3,4. Once i = 1, we only check i against indexes
// 2,3,4)
for ( int j = i + 1; j < AABBNodes.size(); ++j )
{
if ( AABBOverlaps( AABBNodes[i], AABBNodes[j] ) )
{
// If the AABB we checked against was a simulation island
// then we now check against the nodes in the simulation island
// Once you find overlaps between two actual object AABBs
// you can now check sub-nodes with each object, if you went
// that far in optimizing physics meshes.
{
}
}
}
}
Saya juga akan merekomendasikan tidak memiliki begitu banyak loop dalam loop seperti ini, sampel di atas hanya jadi Anda punya ide, saya akan memecahnya menjadi beberapa fungsi yang memberi Anda fungsi yang sama seperti sesuatu seperti yang ditunjukkan di atas.
Juga, pastikan untuk tidak mengubah wadah AABBNodes saat mengulanginya, karena itu bisa berarti cek tabrakan yang terlewat. Ini mungkin terdengar seperti akal sehat, tetapi Anda akan terkejut betapa mudahnya untuk bereaksi terhadap benturan menyebabkan perubahan yang tidak Anda harapkan. Misalnya jika tabrakan menyebabkan salah satu objek bertabrakan untuk mengubah posisi cukup untuk menghapusnya dari AABB dari node Octree yang Anda periksa maka itu dapat mengubah wadah itu. Untuk mengatasi ini, saya sarankan menyimpan daftar semua peristiwa tabrakan yang terjadi selama pemeriksaan, dan kemudian setelah semua pemeriksaan selesai dijalankan melalui daftar dan mengirimkan semua peristiwa tabrakan.