Bir çarpışma motoru ile bir fizik motoru arasında büyük bir fark var. Fizik motoru genellikle bir çarpışma motoruna dayanmasına rağmen, aynı şeyi yapmazlar.
Çarpışma motoru daha sonra iki bölüme ayrılır: çarpışma tespiti ve çarpışma tepkisi. Sonuncusu genellikle fizik motorunun bir parçasıdır. Bu nedenle çarpışma motorları ve fizik motorları genellikle aynı kütüphaneye taşınır.
Çarpışma tespiti, ayrık ve sürekli olmak üzere iki şekilde gelir. Gelişmiş motorlar, farklı özelliklere sahip oldukları için her ikisini de destekler. Genel olarak, sürekli çarpışma tespiti çok pahalıdır ve sadece gerçekten ihtiyaç duyulan yerlerde kullanılır. Çarpışma ve fiziğin çoğunluğu ayrık yöntemler kullanılarak ele alınmaktadır. Kesikli yöntemlerde nesneler birbirine nüfuz eder ve fizik motoru daha sonra onları birbirinden uzaklaştırmaya çalışır. Böylece motor bir oyuncunun kısmen bir duvardan veya zeminden yürümesini durdurmaz, oyuncunun kısmen duvar / yerde olduğunu tespit ettikten sonra sabitler. Burada ayrık çarpışma algılamaya odaklanacağım, çünkü sıfırdan uygulamada en çok deneyime sahip olduğum şey bu.
Çarpışma algılama
Çarpışma tespiti nispeten kolaydır. Her nesnenin bir dönüşümü ve bir şekli vardır (muhtemelen çoklu şekiller). Naif yaklaşımlar, çarpışma motorunun tüm nesne çifti boyunca bir O (n ^ 2) döngü yapmasını ve çiftler arasında çakışma olup olmadığını test etmesini sağlar. Daha akıllı yaklaşımlarda, birden fazla uzamsal veri yapısı (örneğin, statik ve dinamik nesneler için), her nesne için bir sınırlama şekli ve her nesne için çok parçalı dışbükey alt şekiller bulunur.
Mekansal veri yapıları, KD-Ağaçları, Dinamik AABB ağaçları, Octrees / Quadtrees, Binary Space Partitioning trees ve benzerlerini içerir. Her birinin avantajları ve dezavantajları vardır, bu yüzden bazı yüksek uçlu motorlar birden fazla kullanmaktadır. Örneğin Dinamik AABB ağaçları gerçekten çok hızlı ve çok sayıda hareketli nesneyi işlemek için iyidir; KD-Ağacı ise nesnelerin çarpıştığı statik seviye geometrisi için daha uygun olabilir. Başka seçenekler de var.
Geniş faz, uzamsal veri yapılarını ve her nesne için soyut bir sınırlayıcı hacmi kullanır. Sınırlayıcı bir hacim, tüm nesneyi saran basit bir şekildir, genellikle çarpışma testlerini yapmak için ucuza kalırken, mümkün olduğu kadar "sıkıca" tutma amacı ile. En yaygın sınırlama şekilleri, Eksen Hizalanmış Sınırlama Kutuları, Nesne Hizalanmış Sınırlama Kutuları, Küreler ve Kapsüller'dir. AABB'ler genellikle en hızlı ve en kolay olanı olarak kabul edilir (Bazı durumlarda küreler daha kolay ve daha hızlıdır, ancak bu uzamsal veri yapılarının birçoğu, kürenin yine de bir AABB'ye dönüştürülmesini gerektirecektir), ama aynı zamanda pek çok nesneye de zayıf bir şekilde sığma eğilimindedir. Kapsüller, karakter seviyesi çarpışmalarının üstesinden gelmek için 3D motorlarda popülerdir. Bazı motorlar iki sınırlama şekli kullanır,
Çarpışma tespitinin son aşaması, geometrinin kesiştiği yeri tam olarak tespit etmektir. Bu genellikle, her zaman olmasa da, bir ağın (ya da 2B'de çokgen) kullanılması anlamına gelir. Bu aşamanın amacı, nesnelerin gerçekten çarpışıp çarpışmadığını, ince bir ayrıntı seviyesinin gerekli olup olmadığını bulmaktır (örneğin, bir vurucuda mermi çarpışması, ancak zorlukla kaçıran çekimleri görmezden gelmek isteyebilirsiniz) ve Ayrıca nesnelerin tam olarak nerede çarpıştığını bulmak için, bu nesnelerin nasıl tepki vereceğini etkileyecektir. Örneğin, bir masanın kenarında oturan bir kutu varsa, motor masanın hangi noktalara karşı bastırdığını bilmelidir; Kutunun ne kadar asılı kaldığına bağlı olarak, kutu yana yatmaya ve düşmeye başlayabilir.
Manifold Üretimi
Burada kullanılan algoritmalar, popüler GJK ve Minkowski Portal İyileştirme algoritmalarını ve Ayırıcı Eksen testini içerir. Popüler algoritmalar genellikle yalnızca dışbükey şekiller için çalıştığından, birçok karmaşık nesneyi dışbükey alt nesnelere ayırmak ve her biri için ayrı ayrı çarpışma testleri yapmak gerekir. Bu, basitleştirilmiş kafeslerin sıklıkla çarpışma için kullanılmasının nedenlerinden biri ve ayrıca daha az üçgen kullanmak için işlem süresindeki azalmanın bir nedenidir.
Bu algoritmaların bazıları size yalnızca nesnelerin kesin olarak çarpıştığını değil, aynı zamanda nerede çarpıştığını da söyler - birbirlerinden ne kadar içeri girdiklerini ve “temas noktalarının” ne olduğunu. Algoritmaların bazıları, bu bilgiyi elde etmek için çokgen kırpma gibi ek adımlar gerektirir.
Fiziksel Tepki
Bu noktada, bir temas keşfedildi ve fizik motorunun kontağı işlemesi için yeterli bilgi var. Fizik kullanımı çok karmaşık olabilir. Basit algoritmalar bazı oyunlar için işe yarar, ancak bir kutu yığını sabit tutmak kadar basit görünen bir şey bile oldukça zordur ve çok fazla çalışma ve açık olmayan kesimler gerektirir.
En temel seviyede, fizik motoru bunun gibi bir şey yapacak: çarpışan nesneleri ve onların temas manifoldunu alacak ve çarpışan nesneleri ayırmak için gereken yeni konumları hesaplayacaktır. Nesneleri bu yeni pozisyonlara taşıyacaktır. Ayrıca bu itmeden kaynaklanan hız değişimini, restitüsyon (sıçrama) ve sürtünme değerleri ile birlikte hesaplayacaktır. Fizik motoru aynı zamanda nesnelerin yeni hızlarını hesaplamak için yerçekimi gibi nesnelere etki eden diğer kuvvetleri de uygulayacak ve daha sonra yeni konumlarını hesaplayacaktır.
Daha ileri fizik tepkisi hızla karmaşıklaşıyor. Yukarıdaki yaklaşım, diğerlerinin üzerinde oturan bir nesne dahil olmak üzere birçok durumda yıkılacaktır. Her bir çift ile başa çıkmak "titremeye" neden olur ve nesneler çok fazla zıplar. En temel teknik, çarpışan nesne çiftleri üzerinde bir dizi hız-düzeltme yinelemesi yapmaktır. Örneğin, "B" ve "C" diğer iki kutunun üstüne oturmuş bir "A" kutusuyla, önce AB çarpışması gerçekleştirilir, bu da A kutusunun C kutusuna daha fazla eğilmesine neden olur. Sonra AC çarpışması gerçekleştirilir. kutuları biraz dışarı çıkartın, ancak A'yı aşağı ve B'ye doğru çekin. Daha sonra başka bir yineleme yapılır, böylece AC düzeltmesinin neden olduğu AB hatası, AC yanıtında biraz daha fazla hata yaratarak hafifçe giderilir. AC tekrar işlendiğinde ele alınır. Yapılan yineleme sayısı sabit değildir ve “mükemmel” olduğu bir nokta yoktur, ancak ne kadar sayıda yineleme anlamlı sonuç verirse durursa dursun. 10 yineleme tipik bir ilk denemedir, ancak belirli bir motor ve belirli bir oyunun ihtiyaçları için en iyi rakamı bulmak için ince ayar yapılması gerekir.
Önbelleğe Alma
Birçok oyun türüyle uğraşırken gerçekten kullanışlı (ya da daha az gerekli) olduğu ortaya çıkan başka numaralar da vardır. Kontakt önbellekleme daha faydalı olanlardan biridir. Bir kişi önbelleğiyle, her bir çarpışan nesne kümesi arama tablosuna kaydedilir. Bir çarpışma algılandığında, her kare, nesnelerin daha önce temas halinde olup olmadığını görmek için bu önbellek sorgulanır. Nesneler daha önce temas halinde değilse, "yeni bir çarpışma" olayı oluşturulabilir. Nesneler daha önce temas halindeyse, bilgi daha istikrarlı bir yanıt sağlamak için kullanılabilir. Kişi önbelleğindeki bir çerçevede güncellenmeyen tüm girişler, birbirinden ayrılan iki nesneyi gösterir ve "ayırma nesnesi" olayı oluşturulabilir. Oyun mantığı genellikle bu olaylar için kullanır.
Oyun mantığının yeni çarpışma olaylarına cevap vermesi ve bunları göz ardı edilmiş olarak işaretlemesi de mümkündür. Bu, platformlarda sıkça karşılaşabileceğiniz, ancak üzerine çıkabileceğiniz platformlar gibi bazı özellikleri uygulamak için gerçekten yararlıdır. Naif uygulamalar, aşağı doğru platform-> karakter çarpışması normal olan çarpışmaları görmezden gelebilir (oyuncunun başının platformun dibine vurduğunu gösterir), ancak temas önbelleğe alma olmadan, oyuncunun kafası platformun içinden yükselir ve sonra başlarsa kırılır düşmek. Bu noktada normal temas, yukarı bakacak ve oyuncunun yapmaması gerektiğinde platformdan çıkmasına neden olabilir. Temas önbelleğe alma ile motor, ilk çarpışmaya normal şekilde güvenilir şekilde bakabilir ve platform ile oynatıcı tekrar ayrılana kadar tüm diğer temas olaylarını görmezden gelebilir.
Uyuyor
Çok kullanışlı bir teknik de, nesneleri etkileşime girmedikleri takdirde "uykuda" olarak işaretlemektir. Uyuyan nesneler fizik güncellemesi almazlar, diğer uyuyan nesnelerle çarpışmazlar ve temel olarak sadece uykuda olmayan başka bir nesne onlarla çarpışana kadar zaman içerisinde donmuş olarak otururlar.
Bunun etkisi, orada oturan hiçbir şey yapmayan çarpışan nesnelerin çiftlerinin hiçbir işlem zaman almamasıdır. Ayrıca, sabit miktarda küçük fizik düzeltmesi olmadığı için, yığınlar sabit kalacaktır.
Bir nesne, tek bir kareden daha fazlası için sıfıra yakın bir hıza sahip olduğunda uyumak için adaydır. Bu sıfıra yakın hızı test etmek için kullandığınız epsilonun, yığılmış nesnelerle bir miktar titremeyi beklemeniz gerektiğinden, normal kayan nokta karşılaştırma epsilonundan biraz daha yüksek olacağını ve eğer varsa tüm nesnelerin uykuya dalmasını istediğinizi unutmayın. İstikrar için "yeterince yakın" kalıyorsun Eşik elbette ince ayar ve deneme gerektirecektir.
Kısıtlamalar
Birçok fizik motorunun son büyük kısmı kısıtlayıcı çözücüdür. Böyle bir sistemin amacı, yaylar, motorlar, tekerlek ekseni, simüle edilmiş yumuşak gövdeler, kumaşlar, halatlar ve zincirler ve bazen de sıvı gibi şeylerin uygulanmasını kolaylaştırmaktır (akışkan, genellikle tamamen farklı bir sistem olarak uygulanır).
Kısıtlama çözümünün temelleri bile çok matematik yoğunlaşabilir ve bu konudaki uzmanlığımın ötesine geçebilir. Konunun daha ayrıntılı bir açıklaması için Randy Gaul'un fizikle ilgili mükemmel yazı dizisini incelemenizi öneririm .