2010-07-24 4 views
6

현재 물리 엔진과 그래픽 엔진을 사용하여 here처럼 엔터티 구성 요소 시스템을 통합하고 있습니다. 최근까지 물리학이 자체 스레드에서 실행되어야한다고 결정할 때까지는 괜찮 았습니다. (Thanks Glenn Fiedler!)구성 요소 엔티티 시스템 스레드를 안전하게 보호하려면 어떻게해야합니까?

지금은 구성 요소에 액세스 할 때 모든 하위 시스템에서 공유하는 뮤텍스를 잠그는 중입니다. 물리학 루프에서

발췌문 : 그래픽 루프에서

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); 
} 

니펫 :

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)); 
} 

이것은 분명히 매우 순진한 구현, 그래서 개별 구성 요소가 자신의 뮤텍스를 만드는 시도했다. 논리적 인 성능 선택 인 것처럼 보였지만, 물리학 결과 (위치 구성 요소를 통해 쿼리 됨)가 항상 일관성 있고 신뢰할만한 것은 아닙니다.

원활한 업데이트 프로세스를 수행하는 가장 효율적인 방법은 무엇입니까? 한 번에 전 세계를 업데이트하거나 더 많은 것을 증분해야합니까?

편집 : 포인터 획득 스키마에는 결함이 있지만 포인터가 유효하다고 가정 해 보겠습니다.

답변

2

게임 엔진에서 실행되는 물리 엔진에 관해서는 물리 시스템에서 구성 요소 시스템으로 필요할 수있는 위치/모든 정보를 복사 할 프레임 당 한 번 싱크 포인트가 있어야합니다. 원한다면 더 블링 버퍼링이라고 부르세요. 자신의 위치에 대한 내부 및 외부 인스턴스 (월드 매트릭스/속도 등).

physics-positions에서 한 프레임 지연까지는 게이머가 알아 차릴 수있는 것이 아닙니다.

또 다른 참고 사항으로, 가능한 한 많은 스레드를 사용하는 방식으로 물리 엔진을 구현하는 것을 선호하지만 나머지 게임 엔진은 바람직하지 않습니다. Bullet과 Havok은이 솔루션으로 가장 잘 작동하는 것 같습니다.

+0

동기 점을 수행 할 때 물리 엔진이 통합되지 않도록 추가해야한다고 덧붙여 야합니다. – Simon

+2

동의합니다. 여러 개의 싱크 포인트가 효율적으로 보이지만 장면을 그리기 전에 장벽을 만들어 구성 요소 잠금의 목적을 무효화해야합니다. 물리와 그래픽이 그래픽이 아닌 다른 프레임으로 실행되도록하고 싶을 수도 있습니다. 물리 업데이트 당 하나의 잠금에 초점을두고 게임 엔진이 각 그래픽 프레임의 최근 물리 데이터를 보간하도록합니다. –

관련 문제