Three.js · Motor · Çarpışma
Çarpışma mantığı: etkileşimin kuralları
Fizik motorunda «çarpışma» yalnızca iki nesnenin birbirine değmesi değildir; önce adayları daraltan, sonra kesin teması üreten bir süzgeç hattı, ardından şekil ve filtre sözleşmeleri ve olay sinyalleri vardır. Bu sayfa bu hattı kütüphane bağımsız bir ortak dil olarak özetler.
Görsel–fizik ayrımı ve tel vizör için Fizik debug; kesişim testinin hiyerarşik okuması için Intersection test sayfalarına başvurabilirsiniz — burada aynı hikâyeyi tekrar etmek yerine motor içi çarpışma boru hattını sabitliyoruz.
İki fazlı süzgeç: geniş ve dar faz
Çarpışma maliyeti, sahnedeki olası çift sayısıyla kabaca ölçeklenir. Bu yüzden motorlar neredeyse daima önce ucuz elen, sonra pahalı doğrula modeline oturur: geniş fazda «belki» kümesini küçültür, dar fazda «kesinlikle» cevabını üretir. Bu ayrım, işlemciyi (CPU) boşuna poligon poligon test etmekten kurtarır.
A. Geniş faz (broad-phase)
Motor, uzak duran çiftleri hızlıca eler. Yaygın taşıyıcı, eksenlere hizalı sınırlayıcı kutu (AABB)dır: her gövde için «minimum hacimde ama konservatif» bir kutu tutulur; kutular kesişmiyorsa, alt seviye geometrinin çarpışma ihtimali yoktur denilebilir (tersi her zaman doğru değildir; bu yüzde narrow vardır).
Geniş faz bazen yalnızca kutu–kutu testi değil; uzamsal indeks, süpürme–ayıklama (sweep and prune) veya hiyerarşik hacim ağaçları ile aday çift listesi üretimini de kapsar. Amaç bellidir: milyonlarca pahalı test yerine, çoğu zaman birkaç tamsayı karşılaştırması veya düşük dereceli geometri ile saniyeler kazanmak.
B. Dar faz (narrow-phase)
Geniş faz «yakınlar» dediğinde devreye dar faz girer: küre–kutu, kutu–kutu, kapsül–üçgen gibi kapalı formlar için kesin testler çalışır. Çıktı artık yalnızca evet/hayır değildir; çözücünün ihtiyaç duyduğu contact manifold verisi üretilir.
Bu verinin çekirdeği üçlüdür: temas noktası (nerede değdi), normal vektör (hangi yönde itilecekler) ve penetrasyon derinliği (ne kadar iç içe kaldılar). Dar fazın görevi «görsel olarak doğru» değil, sayısal olarak tutarlı temas üretmektir; görünürlük için tel katman Debug · temas noktaları ile üst üste okunur.
Çarpışma şekilleri (collision shapes)
Görsel modeliniz milyonlarca üçgenden oluşabilir; simülasyon ise çoğu zaman basit geometri ile yaşar. Şekil seçimi, doğruluk ile maliyet arasında yapılan ticarettir; «her yüzey aynı ayrıntıda olsun» beklentisi üretimde genelde tuzaktır — gerekçe için Entegrasyon · her yüzeye tam fizik mi? başlığına bakın.
Sphere (küre)
En ucuz temsildir: merkez + yarıçap ile mesafe karşılaştırması yeterlidir. Toplar, pickup parçacıkları ve «yaklaşık küremsi» objeler için sık seçilir; fakat düz zeminde yuvarlanan kutuyu küreyle temsil etmek görsel ile fizik arasında kasıtlı bir yalan olur — oyun tasarımı bunu tolere eder veya kapsüle geçilir.
Box (kutu)
Altı yüzeyli standart prizma; duvar, basamak, kutu envanter gibi dünya blokları için doğal seçimdir. OBB (ekene göre dönük kutu) ile AABB ayrımı geniş fazdaki taşıyıcıdan bağımsızdır; gövde şekli olarak OBB dar fazda biraz daha pahalıdır fakat dönmüş duvarlarda hacim şişmesini azaltır.
Silindir ve kapsül (cylinder / capsule)
İnsan ve hayvan silueti için kapsül, köşeli kutuya göre merdiven ve küçük çıkıntılarda daha az «takılır»: alt yarısı sürekli eğri olduğu için, zeminle temas geçişi daha yumuşak bir profil çizer. Karakter kontrolcüsü ile fizik gövdesinin aynı hizada pivotlanması burada kritiktir.
Convex hull (dışbükey zar)
Karmaşık silueti, dışbükey bir «gergin balon» ile sarar; concave oyukları tek başına modelleyemez, fakat çoğu dinamik nesne için trimesh’e göre hâlâ ucuzdur. Aşırı detaylı kabuk, yine de dar fazı şişirir; bu yüzden «kabuk sadeleştirme» ayrı bir üretim adımıdır.
Trimesh (üçgen ağ)
Statik dünya geometrisi için kullanılır: merdiven yüzeyi, organik zemin, level ağı. Dinamik gövdeye doğrudan bağlamak genelde pahalı ve stabilite açısından risklidir; dinamik taraf hâlâ kutu/kapsül, statik taraf ağ şeklinde kalır. Üçgen sayısı arttıkça broad-phase’in kazandığı zaman dar fazda eriyebilir.
Filtreleme: kim kime çarpar?
Her çiftin test edilmesi gerekmez. Karakterin kendi silahıyla sürtünmesini istemezsiniz; mermi düşmana giderken oyuncuya çarpmamalıdır. Bunu yönetmek için motorlar grup ve maske (veya katman + maske) sözleşmeleri sunar — isimler değişir, fikir aynıdır: çarpışma, izin verilen kategori çarpımında oluşur.
Çarpışma grupları (collision groups)
Her gövde bir veya birkaç kategoriye aittir: zemin, oyuncu, düşman, mermi, tetik alanı… Gruplar, tasarım dilinizi kod tarafına taşır; iyi isimlendirme, hata ayıklamada hayalet çarpışma avında size yol gösterir.
Maskeler (collision masks)
Maske, «bu gövde hangi gruplarla etkileşime girebilir?» sorusunun cevabıdır; çoğu uygulamada bit alanlarıyla ifade edilir. Örnek: mermi yalnızca «düşman» ve «zemin» maskelerine açıkken, «oyuncu» maskesini kapalı tutar — böylece ateş edenle çarpışıp anında sönmez; zeminle çarpışınca delil veya patlama olayı tetiklenir.
Raycaster katman filtrelemesi ile karıştırmamak gerekir: seçim ışını ile fizik filtresi aynı bitleri paylaşabilir, fakat farklı alt sistemlerdir; aynı sabiti iki yerde kullanırken dokümantasyonunuzu net tutun.
Çarpışma olayları (collision events)
Temas üretildiğinde yalnızca sekme/durma görselleşmez; oyun mantığı için sinyal gerekir. Motorlar genelde üç zaman dilimini ayırır; API adları değişse de anlam şöyledir:
Temas başlangıcı (on collide start)
İki gövde ilk kez anlamlı temas kurduğunda tetiklenir: tek seferlik ses, can düşüşü, parçacık patlaması gibi «ilk dokunuş» işleri buraya yazılır. Aynı temas kareler boyunca sürecekse burada ağır iş yüklemekten kaçının; yoksa her karede maliyet taşar.
Süren temas (on collide active)
Gövdeler hâlâ değiyorken periyodik olarak gelir: lav zeminde sürekli hasar, sürtünme sesi eğrisi gibi «devam eden» etkiler burada modellenir. Frekans motor ve adım politikasına bağlıdır; oyun tasarımında biriktirme (accumulate damage per second) gibi örneklerle maliyet kontrol edilir.
Temas bitişi (on collide end)
Ayırma anında çalışır: zıplama sayacını sıfırlama, platformdan inince animasyon kesme, birleşik cisimleri ayırma gibi temizlik işleri buraya yakışır. «Başlatıldı ama bitmedi» durumları, genelde bu olayın kaçırılmasından doğar.
Tetikleyici mantığı (trigger / sensor)
Bazı gövdeler «hayalet» gibi davranır: itme üretmezler, fakat örtüşme raporlarlar. Kapı önü bölgesi, bölge müziği değiştiren hacim veya gizli geçit algısı bu sınıftadır. Fizik motorunda bu, genelde sensör bayrağı veya özel malzeme sınıfı ile ayrılır.
Tetikleyici, hayalet çarpışma hatasıyla karıştırılmamalıdır: orada istenmeyen katı gövde vardır; burada ise kasıtlı olarak katı tepki yoktur, yalnızca olay üretilir. Oyuncu tetik alanından çıkınca bitiş sinyaliyle müzik veya UI durumu geri alınır.
Holodepth teknik notu
Aynı sahne için hem «katı dünya» hem «tetik hacimleri» tanımlarken, filtre maskelerini ve olay dinleyicilerini bir tabloda dokümante edin; aksi halde bir sonraki geliştirici hangi çarpışmanın impulse ürettiğini hangisinin yalnızca sinyal verdiğini kaybeder.