Bir fizik motorunda eş zamanlı çarpışmalarla başa çıkmanın en iyi yolu nedir?


13

Javascript'te bir 2d fizik motoru yazıyorum, böylece video oyunlarındaki fizik hakkında daha fazla bilgi edinebilirim. Herhangi bir cismin aynı anda iki veya daha fazla cisimle çarpışması dışında, katı cisim çarpışmaları için doğru çalışıyorum.

Şu anda her bir çarpışan cisim çifti (A, B) için çarpışma dürtüsüne bağlı olarak hızlarını ve açısal hızlarını değiştiriyorum ve nüfuz etmemeleri için birbirlerinden dürtüyorum. Ancak daha sonra A'yı içeren diğer çarpışmalar için çarpışma tespiti ve dürtü hesaplamaları yanlış olacaktır.

Motorumun birbiriyle çarpışan 3+ nesne için çalışmasını sağlamak için hangi yaklaşımları keşfedebilirim?


2
İlgili: gamedev.stackexchange.com/questions/15836/… ve gamedev.stackexchange.com/questions/26181/… ve eminim daha fazlası var, hemen şimdi bulamıyorum.
MichaelHouse

Yanıtlar:


11

Aşağıdaki yaklaşımı kullanıyorum (Tonge kütle bölme algoritmasına benzer : http://www.richardtonge.com/ ):

  • sahnenizdeki / bağlamınızdaki tüm çarpışan çiftleri algılar. (A, B) böyle bir çift olsun. Bir hayalet / kütle bölme fikri uygulayın: A, M gövdeleriyle temas halindeyse ve B, diğer N gövdesi ile temas halindeyse , A'nın kütlesini geçicim_A/M olarak B'ye vem_B/N
  • her bir çift (A, B) için reaksiyon / restitüsyon kuvveti katkılarını hesaplar ve bu katkıları A ve B'nin kendi akümülatörlerinde depolar
  • impulslardan restitüsyon hızlarını hesaplayın (belirttiğiniz gibi) ve aynı şekilde saklayın ( her bir (A, B) çifti için kendi akümülatörlerinde deltaV hız kalıntıları olarak)
  • ceza infazlarının hesaplanması (yine deplasmanları biriktirin, anında uygulamayın!)
    • daha önce çarpışma çiftlerinde ( m_A = m_A * Mve m_B = m_B * N) parti olarak belirlenmiş tüm organların kütlelerini sıfırlayın

Bu yaklaşım, Jacobi yinelemeli algoritmanın doğrusal eşzamanlı denklem sistemleriyle nasıl çalıştığına benzer. Ve birleşmesi garanti edilmez, ancak simülatörümde işi oldukça sorunsuz yapar .. 3D'de (evet, ekstra bir boyut iki kat zorluk ekler!).

Uyarı : pozisyonları ve hızları ancak çarpışma algılama / elleçleme aşaması bittikten sonra düzeltin! Bu şekilde, çarpışan aktörlerinizi aynı anda güncellersiniz. Ayrıca, konumlar ve hızlar için bir sonraki entegrasyonunuzda restitüsyon güçleri de dikkate alınmalıdır.

EDIT: Sanırım zaten suistimal edilmiş Verlet entegrasyon yöntemini kullanıyorsunuz (bu gamedev meraklıları içinde bir ev ismi haline geldi). Bu çarpışma yönetimi ve entegrasyon hayaletinde, buraya bir göz atmak isteyebilirsiniz .

GÜNCELLEME: Çarpışmaya nasıl yaklaşılacağı hakkında bazı bilgiler (ve bu konuda kendi kendine çarpışma) şu makalelerde bulunabilir:

Önerdiğim yaklaşım uzun zamandır orijinal bir katkı değil, birçok oyun bunu makul sonuçlarla kullanıyor ve Jakobsen tarafından Hitman oyun motorunda en iyi şekilde kullanılıyordu.

Biraz pratik bir deneyimden, ceza kuvvetleri (girişlerini penetrasyon mesafesinden alan doğrusal veya üstel yaylara benzer şekilde) çarpışan cisimlerden gelen diğer kuvvetler onlardan daha büyük olmayı başardığında nüfuzları düzgün bir şekilde çözmezler. Bu yüzden üç (neredeyse gereksiz) yaklaşımı birleştirmeyi seçtim: Newton reaksiyonu kuvvetleri (duvarı itiyorsunuz, duvar geri itiyor), dürtü kaynaklı hızlar (bilardo topları çarpışıyor) ve doğal olmayan bir "bedenleri geometrik olarak birbirinden uzaklaştırıyor " çözüm. Birlikte her şeyi sağlıyorlar: çoğu şeyden kurtulunçirkin iç içe geçme eserleri, çarpışan bedenler uzun vadede birbirleriyle etkileşime girme eğilimindedir (restitüsyon hızları ve kuvvetleri nedeniyle - en azından bir çarpışma senaryosunda bedenleri sürükleme eğilimi olan kuvvetler iptal edilir ve bedenler birbirinden uzaklaşır) . Son olarak, bu basit ama ortak kavramları daha iyi anlamak için, bu slaytları analiz etmenizi öneririm .

Verlet entegrasyon adımlarını açıklayan "istismar edilmiş yöntem" epithet'im, bunun entegrasyon yöntemlerinin Kutsal Kâsesi olduğuna dair popüler bir kültür inancını hedefliyor. Symplectic Euler (bazı yarı örtülü Euler olarak da bilinir) kuzeninden çok az daha iyidir. Çok daha karmaşık entegrasyon yöntemleri vardır (ve hepsinde örtük isim vardır). Güçlü oyun motorları bunları kullanır, ancak bağımsız geliştiricilerin Verlet'i belirli bir senaryoya ayarlandığında gerçekten harikalar yaptığı için deneyecek zamanları yoktur. Ayrıca, biraz hile yapmadan katı kısıtlamalarla başa çıkabilecek hiçbir entegrasyon yöntemi yoktur (bağlantıyı bulamıyorum, ancak bahsettiğim kağıda "X.Provot -" Bir Kitle'deki Deformasyon Kısıtlamaları denmelidir. Kumaş Davranışını Tanımlamak için Yayılma Modeli "


Teşekkürler (+1)! 'Ücret iadesi' ve 'cezaların yerinden edilmesi' nedir? Ayrıca, neden entegrasyon entegrasyonunun 'istismar edildiğini' söylüyorsunuz? Bunun kötü bir yöntem olduğunu düşünüyor musunuz?
Cam

Restitüsyon hızları tam olarak dürtülerden aldığınız hızlardır, tek fark onları kalıntı olarak hesaplamamdır (yani, dürtü temelli hız ve mevcut hız arasındaki farkı, mevcut hıza daha fazla hesaplama için dokunmadan saklıyorum). Penaltı yer değiştirmeleri, iki nesnenin ne kadar iç içe geçtiği ile belirlenen bir uzunluğa sahip vektörlerdir ve bir nesneyi tamamen diğerinin dışına çevirebilen minimum uzunluk vektörüdür. Genellikle uzunluğu 2'ye bölen her nesneye böyle bir yer değiştirme eklerim.
teodron

1
Mükemmel cevap! Yine de başka bir sorum var. Diyelim ki, iade hızlarını biriktiriyorum, çok gerçekçi olmayan bir sayı eklemeyecekler mi? Her çarpışmaya A nesnesiyle ayrı ayrı davranırsam ve her nesne üzerindeki efektleri toplarsam A'nın nesneler arasında dürtü yayılması olmaz mı? Bunun yerine sezgisel olarak bana yanlış gelen her birine tam dürtü uygulanacak
Cam

Bu çok iyi bir soru .. bir açıdan bakıldığında, dürtülerin ortaya çıkan hıza ilave olarak katkıda bulunması mantıklı görünüyor. İşte benim (belki de hatalı!) Akıl yürütme: Üç havuz / bilardo topunun çarpıştığını hayal edin. Bunlardan biri bu katkı maddesi tarzında diğer ikisinden katkı almalıdır. Başlangıçta, bu katkıları tartmayı düşündüm ve son hız için ağırlıklı bir ortalama hesapladım, ancak hızlı sonuçlar istediğimden bu fikri atladım. Sonuçta, çarpışan top diğer ikisinden hız katkıları almalıdır. Belki bir lise ders kitabı yardımcı olabilir.
teodron

3
Belki de ne anlattığınızı anlamıyorum, çünkü aşağıdaki örnek hala beni ilgilendiriyor: Yatay olarak uzun bir dikdörtgenin aşağıya doğru düştüğünü düşünün ve zeminin pürüzlü olduğunu varsayalım (bu yüzden yan yana birden fazla üçgenden oluşur). Biriktirme yönteminizi kullanarak n üçgen varsa, dikdörtgen olması gereken hızın n hızında geri döner! Bu durum nasıl düzeltilebilir?
Cam

1

Hızları değiştirmek yerine, bir nesneye etki eden kuvvetleri değiştirmenizi öneririm . Onları "dürtmeyin", daha doğrusu ve zaten var olan kodu kullanarak yapın. Bunu yaparak bedenler hemen alışkanlık kazanmayacak (ve hızla, sanırım) hızlarını değiştirecekler.

Bir örnek için Box2DJS'ye bakın: http://box2d-js.sourceforge.net/index2.html .


-1

Çarpışan cisim grupları için dürtü denklemini analitik olarak çözdüm. Karşılaştığım tek sorun, bir gruptaki kişiler arasındaki göreceli etkileşim gücünü bulmak için değişken eksikliğiydi, ki bu da vücutların kesiştiği derinlikle doldurdum.

Grup temasları için çözüm tek temastan çok daha zor değildir. Ne yazık ki hesaplamalarla bir makale kaybettim, bu yüzden burada paylaşamıyorum.

Düzenleme: Muhtemelen böyle bir şey buldum /physics/296767/multiple-colliding-balls

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.