공간 해시 및 쿼드 트리에 대한 2D 공간 파티셔닝 대안


11

내 게임에서 공간 분할 알고리즘을 구현하려고 시도했지만 공간 해시와 쿼드 트리가 모두 내가 원하는 것이 아닙니다.

내 레벨 크기에는 제한이 없어야합니다 (Int32 제한 만). "Level Width"와 "Level Height"가 필요없는 공간 분할 알고리즘이 필요합니다.

움직이는 물리적 물체가 많이 있습니다. 500 개 이상의 객체를 지원할만큼 빠른 알고리즘이 필요합니다.

대안이 있습니까?

답변:


13

다이나믹 트리

Box2D숙련 된 물리 / 게임 프로그래머가 설계 한 최적화 된 엔진입니다 . 원래 Box2D는 고정 높이와 너비가 필요한 해시 그리드를 사용했습니다.

Erin이 더 나은 광대역 알고리즘으로 업그레이드했을 때 그는 Nathanael Presson의 btDbvt와 함께 갔다. 이것은 Bullet Physics에서 사용하는 광범위한 단계입니다. Erin은 2d에 대한 알고리즘을 수정하고 최적화했습니다.

Box2D 매뉴얼 (§4.11) 에서 초고 수준 개요를 읽 거나 Dynamic Tree를 검색 할 수 있습니다.

다음은 코드 설명서 의 예외입니다 (공개 API의 일부가 아닌 것을 고려하면 매우 좋습니다).

Nathanael Presson의 btDbvt에서 영감을 얻은 다이나믹 AABB 트리의 넓은 단계. 동적 트리는 데이터를 이진 트리로 정렬하여 볼륨 쿼리 및 레이 캐스트와 같은 쿼리를 가속화합니다. 리프는 AABB를 사용하는 프록시입니다. 트리에서 프록시 AABB가 클라이언트 오브젝트보다 더 크도록 b2_fatAABBFactor에 의해 프록시 AABB를 확장합니다. 이를 통해 트리 업데이트를 트리거하지 않고 클라이언트 개체를 소량 이동할 수 있습니다.

노드는 풀링 및 재배치 가능하므로 포인터가 아닌 노드 인덱스를 사용합니다.

Dynamic Tree의 알고리즘에 대한 나의 이해는 이것입니다. 동적 트리는 클래식 avl 이진 트리 와 쿼드 트리 사이의 교차 입니다. 최종 효과는 각 노드를 절반으로 만 분할하는 쿼드 트리이며 분할 선은 고정되어 있지 않습니다 (두 개의 반은 쿼드 트리와 크기가 같지 않습니다). 동적 스플릿이있는 쿼드는 본질적으로 목록 (O (n) 조회 속도)으로 저하 될 수 있기 때문에 AVL이 제공됩니다. AVL은 하위 트리를 재조정하여 Olg (N) 조회 속도를 보장하는 데 사용됩니다.

모든 코드 중 최고는 MIT이므로 복사 / 파생 / 뻔뻔한 도용 등을 자유롭게 복사하십시오.


복잡해 보인다! 그래도 살펴 보겠습니다. 누군가가 "스윕 및 프룬"또는 "정렬 및 스윕"기술을 사용하도록 제안했지만 C # 또는 .NET 구현에 대해서는 아무것도 찾을 수 없습니다. C ++ 예제를 찾았지만 혼란스럽고 작동하지 않았습니다 (어쨌든 구현하려고했습니다). SAP를 구현하기가 더 쉬울 것이라고 생각하십니까? .NET 구현이 있습니까?
Vittorio Romeo

8

이것은 Gamedev에서 묻는 비슷한 질문에 매우 가깝지만 파일 저장 공간이 아닌 성능과 관련하여 볼 때 아마도 내 대답 이 더 유용 할 것입니다. 여기에 완성도를 높이기 위해 여기에 대량을 포함시킬 것입니다. 그러나 원래 답변은 자세히 살펴보고 싶을 때 깊이를 제공합니다.

비슷한 문제가 발생하여 데이터를 처리하는 자체 구조를 만들기로 결정했습니다. 쿼드 트리를 느슨하게 기반으로하지만 모든 방향에서 무한대 (적어도 Int만큼) 확장 성이 있습니다. 현재 Minecraft와 마찬가지로 중앙 지점에서 확장 된 그리드 기반 데이터를 처리하도록 설계되었습니다. 메모리에서 공간 효율적이며 매우 빠릅니다.

내 코드는 여기 에서 찾을 수 있습니다 . 코드는 완전하고 테스트 (단위 및로드 테스트)되며 최적화되어 있습니다. 내부 작업은 아직 잘 문서화되어 있지 않지만 모든 공개 방법이 사용 가능해야합니다. 누군가 시도해보기로 결정한 경우 질문이나 의견이 있으면 언제든지 저에게 연락하십시오.


1

상대적으로 적은 수의 (<수천) 작은 물체를 처리 할 때 (대부분의 물체는 다른 물체와 충돌 할 수있을만큼 크지 않습니다) 축 정렬 된 경계 상자 (AABB)의 간단한 x 순서 목록이 작동한다는 것을 알았습니다 꽤 잘합니다. 방금 객체를 목록에 넣은 다음 객체를 이동 한 후 각 프레임을 x 값으로 목록을 빠르게 정렬 한 다음 AABB 근접성을 검사하는 목록을 한 번 통과시킵니다. 각 객체에 대해 목록의 끝에 도달하거나 x 범위를 벗어난 객체에 도달 할 때까지 목록의 객체보다 먼저 확인합니다. 즉, 왼쪽 가장자리의 x 값은 테스트중인 개체의 오른쪽 가장자리> x 값입니다. 기본적으로 공간을 겹치는 AABB x x 너비 크기 슬라이스로 동적으로 공간을 나눕니다. 그것'


0

아마도 r-tree 알고리즘 이 당신이 찾고있는 것일 것 입니다.

정적 지오메트리는 실제로 잘 작동하지만 새 위치에서 객체를 제거하고 추가하여 객체를 이동하는 데 사용할 수도 있습니다.


C # 구현을 시도했는데 "새 위치에서 개체를 제거하고 추가 할 때"성능이 너무 나빴습니다.
Vittorio Romeo

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.