최대 30 개의 객체 만 있으면 프레임 당 한 번 이상 동일한 두 쌍을 서로 비교하지 않는 것 외에는 최적화가 많이 필요하지 않습니다. 아래 코드 샘플 중 어느 것을 다룰 것인가? 그러나 물리 엔진이 사용할 다른 최적화에 관심이 있다면이 게시물의 나머지 부분을 계속 읽으십시오.
필요한 것은 Octree (3D 게임의 경우) 또는 Quadtree (2D 게임의 경우) 와 같은 공간 분할 구현 입니다. 이들은 세계를 하위 섹션으로 분할 한 다음 각 하위 섹션은 최소 크기로 세분 될 때까지 동일한 저택에서 추가로 분할됩니다. 이를 통해 다른 객체와 동일한 지역에있는 다른 객체를 매우 빠르게 확인할 수 있으므로 확인해야하는 충돌의 양이 제한됩니다.
공간 분할 외에도 각 물리 객체에 대해 AABB ( 축 정렬 경계 상자 )를 만드는 것이 좋습니다 . 이를 통해 한 객체의 AABB를 다른 객체와 비교할 수 있습니다. 이는 객체 간의 폴리 당 세부 검사보다 훨씬 빠릅니다.
이것은 복잡하거나 큰 물리 객체에 대해 한 단계 더 나아가 물리 메쉬 자체를 세분화하여 각 서브 셰이프에 자체 AABB를 제공하여 두 객체의 AABB가 겹치는 경우에만 확인할 수 있습니다.
대부분의 물리 엔진은 일단 물리 바디가 휴식을 취하면 물리 바디에서 활성 물리 시뮬레이션을 비활성화합니다. 피직스 바디가 비활성화되면 각 프레임마다 AABB와의 충돌 만 검사하면됩니다. AABB와 충돌하는 경우 다시 활성화되고보다 세밀한 충돌 검사가 수행됩니다. 시뮬레이션 시간이 줄어 듭니다.
또한 많은 물리 엔진은 '시뮬레이션 아일랜드 (simulation islands)'를 사용하는데, 여기에는 서로 가까운 물리 그룹이 함께 그룹화됩니다. 시뮬레이션 섬의 모든 것이 정지 상태이면 시뮬레이션 섬 자체가 비활성화됩니다. 시뮬레이션 섬의 장점은 섬이 비활성화되면 내부의 모든 몸체가 충돌 검사를 중지 할 수 있으며, 각 프레임에서 유일한 점검 사항은 섬의 AABB에 진입했는지 확인하는 것입니다. 일단 섬의 AABB에 무언가가 들어가면 섬 내의 각 몸체가 충돌을 확인해야합니다. 내부에있는 몸체가 스스로 다시 움직이기 시작하면 시뮬레이션 섬도 다시 활성화됩니다. 시체가 그룹의 중심에서 충분히 멀리 이동하면 섬에서 제거됩니다.
결국 당신은 (의사 코드로) 다음과 같은 것을 남깁니다.
// Go through each leaf node in the octree. This could be more efficient
// by keeping a list of leaf nodes with objects in it.
for ( node in octreeLeafNodes )
{
// We only need to check for collision if more than one object
// or island is in the bounds of this octree node.
if ( node.numAABBsInBounds > 1)
{
for ( int i = 0; i < AABBNodes.size(); ++i )
{
// Using i+1 here allows us to skip duplicate checks between AABBS
// e.g (If there are 5 bodies, and i = 0, we only check i against
// indexes 1,2,3,4. Once i = 1, we only check i against indexes
// 2,3,4)
for ( int j = i + 1; j < AABBNodes.size(); ++j )
{
if ( AABBOverlaps( AABBNodes[i], AABBNodes[j] ) )
{
// If the AABB we checked against was a simulation island
// then we now check against the nodes in the simulation island
// Once you find overlaps between two actual object AABBs
// you can now check sub-nodes with each object, if you went
// that far in optimizing physics meshes.
{
}
}
}
}
또한 이와 같은 루프 내에 너무 많은 루프를 두지 않는 것이 좋습니다. 위의 샘플은 아이디어를 얻었으므로 위의 것과 같은 기능을 제공하는 여러 함수로 나누었습니다.
또한 AABBNodes 컨테이너를 반복하는 동안 충돌 검사를 놓칠 수 있으므로 AABBNodes 컨테이너를 변경하지 마십시오. 이것은 상식처럼 들릴지 모르지만 충돌에 반응하는 것이 예상치 못한 변화를 일으키는 것이 얼마나 쉬운 지 놀랄 것입니다. 예를 들어 충돌로 인해 충돌하는 객체 중 하나가 Octree 노드의 AABB에서 객체를 제거하기에 충분한 위치로 변경되면 해당 컨테이너가 변경 될 수 있습니다. 이 문제를 해결하려면 검사 중에 발생하는 모든 충돌 이벤트 목록을 유지 한 다음 모든 검사가 완료된 후 목록을 통해 실행하고 충돌 이벤트를 전송하는 것이 좋습니다.