2010-07-24 11 views
6

Şu anda, bir fizik motoru ve bir grafik motoru olan here görüldüğü gibi bir varlık bileşeni sistemini bütünleştiriyorum. Bu, son zamanlarda fiziğin kendi iş parçasında koşması gerektiğine karar verene kadar iyiydi. (Teşekkürler Glenn Fiedler!) Şimdi ben sadece bileşenleri erişirken tüm alt sistemlerin tarafından paylaşılan bir nesnesini kilitlemeden am olduğu gibiBileşen varlık sistem dizilimimi nasıl güvenli hale getiririm?

. fizik döngüden

Pasajı: Grafik döngüden

lock_guard<mutex> lock(m_EntMutex); 
entitymap::iterator it; 
for (it = m_Ents.begin(); it != m_Ents.end(); ++it) 
{ 
    // Get physics component from entity 
    // This is guaranteed to work (component must exist for it to present in the map) 
    shared_ptr<comp_phys> phys(static_cast<comp_phys*>(it->second->getComponent(COMP_PHYS).lock().get())); 
    // Get resulting Box2D vector 
    b2Vec2 vec = phys->getBody()->GetPosition(); 

    // Get position component from entity 
    // Same as above, but this is the component shared with the graphics subsystem 
    shared_ptr<comp_pos> pos(static_cast<comp_pos*>(it->second->getComponent(COMP_POS).lock().get())); 
    // Update position component from Box2D vector 
    pos->setPosition(vec.x, vec.y, 0); 
} 

Pasajı:

lock_guard<mutex> lock(m_EntMutex); 
entitymap::iterator it; 
for (it = m_Ents.begin(); it != m_Ents.end(); ++it) 
{ 
    // Get position component from entity 
    // This is shared with the physics subsystem 
    shared_ptr<comp_pos> pos(static_cast<comp_pos*>(it->second->getComponent(COMP_POS).lock().get())); 
    // Get position from position component 
    doubleVec3 vec = p->getPosition(); 

    // Get graphics component from entity 
    shared_ptr<comp_gfx> gfx(static_cast<comp_gfx*>(it->second->getComponent(COMP_GFX).lock().get())); 
    // Update graphics component from position component 
    gfx->getObject()->getParentSceneNode()->setPosition(float(vec.x), float(vec.y), float(vec.z)); 
} 

Bu tabii ki bir çok naif uygulamasıdır, bu yüzden ayrı bileşenler kendi muteksleri sahip hale çalıştı. Mantıksal performans seçeneği görünüyordu, ama daha sonra fizik sonuçları (konum bileşeninden sorgulandığı gibi) her zaman tutarlı ve güvenilir olmazdı.

Ne pürüzsüz güncelleme işlemini gerçekleştirerek en verimli şekilde olurdu? Tüm dünyayı tek seferde güncellemeli mi yoksa daha fazla bir şey mi yapmalıyım?

Düzenleme: İşaretçi edinme düzeninin kusurlu olduğu dikkatimi çekti, ancak işaretçilerin geçerli olduğunu varsayalım.

cevap

2

o oyun motorlarında çalışan fizik motorları gelince seni pozisyonları üzerinden kopyalama nereye karede bir Syncpoint olduğunu önermiştir/size bileşen sistemine fizik sisteminden gerekebilir türlü bilgi. İsterseniz dubbel-buffering olarak adlandırın. Konumunuzun iç ve dış bir örneği (dünya matrisi/hızları vb.). fizik pozisyonlara bir çerçeve gecikmesi kadar

değil herhangi bir oyun göreceksiniz şeydir. Bir başka not

, ben oyun motoru geri kalanı tercihen şey yapmaz iken mümkün olduğunca çok sayıda konuları kullandığınız bir şekilde fizik motorları uygulanması tercih ediyoruz. Bullet ve Havok bu çözümle en iyi şekilde çalışıyor gibi görünüyor.

+0

Senkronizasyonları yaparken fizik motorunuzun bütünleşmesini durdurmak istediğinizi eklemeliyim. – Simon

+2

Katılıyorum. Çok sayıda senkromanın bulunması verimli görünebilir ancak sahneyi çizmeden önce, bileşen başına kilitlerin amacını ortadan kaldırarak bir engel oluşturmanız gerekecektir. Ayrıca, genellikle fiziğin grafiklerden farklı bir çerçeve üzerinde çalışmasına izin vermek istediğinizi unutmayın. Her bir fizik güncellemesi için bir kilit üzerinde odaklanmalı ve oyun motorunun her bir grafik çerçevesindeki son fizik verisinden aramasına izin verdim. –