Dalam mesin fisika 2D, bagaimana saya menghindari resolusi tabrakan yang tidak berguna ketika benda-benda beristirahat?

9

Dalam mesin fisika yang saya kembangkan (untuk belajar) menggunakan love-2d , saya menerapkan resolusi tabrakan dengan cara ini:

FixedUpdate(dt)  // I use fixed timestep
 foreach collide c1 in allNotStaticColliders
   c1.integartePhysic // i.e. apply gravitational force..
   foreach collider c2 "near" c1 // "near"= I use spatial hashing 
      if collide(c1,c2)
        resolve collision (c1,c2)  // the heavy operation
        collison callbacks c1
        collison callbacks c2
        ...

animasi benda yang jatuh dan berhenti

Seperti yang dapat Anda lihat di akhir animasi gif, ada pembusukan FPS ketika semua colliders hampir di-ground-kan pada objek statis.

keadaan statis terakhir, dengan 2 FPS

Ini karena jumlah resolusi tabrakan tumbuh sebagai objek menghabiskan lebih banyak waktu menyentuh saat mereka menyelesaikan. Namun, banyak perhitungan yang "tidak berguna" karena benda-benda telah menetap di posisi yang stabil terhadap satu sama lain.

Apa praktik terbaik (mudah-mudahan tidak memerlukan gelar fisika) untuk menghindari deteksi tabrakan "tidak berguna" ini?

Edit: petunjuk DMG yang diterima dan sampai pada hasil ini (belum optimal)

masukkan deskripsi gambar di sini

(Merah = statis, Biru = aktif, Hijau = tidur)

dnk drone.vs.drones
sumber
1
Pendekatan yang biasa adalah "tidur" objek yang datang untuk beristirahat, dan tidak mempertimbangkan interaksi antara objek tidur / statis (tetapi objek tidur masih dapat dibangunkan oleh interaksi dari objek dinamis yang masih terjaga & bergerak). Sayangnya ini hanya membantu sekali suatu objek sepenuhnya diam. Jika saya membaca contoh Anda dengan benar, sepertinya masalah kinerja Anda mulai ketika objek masih menetap dan bergerak sedikit. Yang bisa saya pikirkan untuk dilakukan di sini adalah menambahkan lebih banyak gesekan / redaman ke sistem (mungkin dengan ambang batas kecepatan) sehingga gerakan kecil membusuk agar istirahat benar lebih cepat.
DMGregory
@DMGregory Kedengarannya seperti jawaban yang bagus. Tambahkan itu?
Anko

Jawaban:

9

Saya menduga OP sudah tahu pendekatan ini, jadi saya sebutkan di komentar sebagai titik awal, tapi saya akan mencoba menyempurnakannya ...

Sebagian besar mesin fisika membagi benda dinamis menjadi dua kelompok, " terjaga ," dan " tidur ."

Objek tidur ketika mereka duduk diam, dan bangun ketika digerakkan atau dipercepat oleh pengaruh luar.

Sebuah tidur objek berperilaku seperti objek statis dalam banyak hal - gerakannya tidak terintegrasi dari waktu ke waktu (karena saat istirahat, sehingga tidak memiliki gerakan) dan pengabaian mesin tabrakan antara benda-benda yang tidur atau statis.

Objek tidur yang duduk di lantai statis tidak jatuh melewatinya, meskipun tidak ada respons tabrakan, karena semua integrasi gerakan dilewati untuk objek tidur, termasuk gravitasi.

Jadi, hanya tabrakan yang melibatkan setidaknya satu objek dinamis yang terjaga yang perlu diperiksa:

Collisions    Static          Sleeping           Awake
          ------------------------------------------------
Awake     |    Check        Check & Wake         Check
Sleeping  |     No               No
Static    |     No

Ini secara dramatis dapat mengurangi jumlah objek yang memerlukan simulasi aktif, terutama dalam tumpukan yang seperti diilustrasikan dalam pertanyaan memiliki banyak benturan timbal balik untuk memeriksa sedikit atau tidak ada pergerakan net.

Tidur hanya membantu setelah benda benar-benar mencapai istirahat, yang mungkin memakan waktu cukup lama.

Beberapa hal yang dapat Anda lakukan untuk mencapai istirahat lebih cepat:

  • Miliki kecepatan atau momentum minimum nol, dan jepit apa pun yang jatuh di bawahnya ke nol. (Ini pada dasarnya adalah epsilon, yang biasa digunakan dalam membandingkan pelampung)

  • Gunakan gesekan, redaman, dan tumbukan tidak elastis untuk menyerap energi dari sistem dan membantunya mencapai istirahat lebih cepat secara keseluruhan.

  • Tingkatkan gesekan / redaman / inelastisitas secara selektif untuk objek yang bergerak lambat untuk memberi mereka dorongan terakhir untuk beristirahat, tanpa memengaruhi perilaku tubuh yang lebih berenergi.

DMGregory
sumber
Jawaban yang bagus. Anda menunjukkan ide-ide bagus. Untuk pemeriksaan tidur / bangun saya melihat 2 poin lemah: 1) jika objek tidur o1 di bawah objek tidur o2 bangun menjauh dari o2, ia tidak bangun o2; 2) jika saya menghapus platform statis di bawah objek tidur, objek itu tidak bangun (di bawah gaya gravitasi)
dnk drone.vs.drones
1
@ dnkdrone.vs.drones Pengamatan yang baik. Tidak pernah menulis mesin fisika sendiri, saya tidak yakin bagaimana ini biasanya ditangani. Satu kemungkinan adalah, ketika mengatur objek untuk tidur, kami menyimpan daftar objek yang disentuhnya (atau menambahkannya ke sekelompok objek lokal). Ketika kita membangunkan objek yang tertidur, kita juga membangunkan segala yang ada dalam daftar / klusternya. Mungkin ada opsi yang lebih elegan, seperti memeriksa kontak terdekat pada saat bangun (sebelum dipindahkan).
DMGregory