전통문화대전망 - 전통 미덕 - 3D 게임은 어떻게 충돌을 탐지합니까?

3D 게임은 어떻게 충돌을 탐지합니까?

먼저 충돌 탐지와 관련된 기하학과 수학에 대한 기본적인 이해가 있다고 가정해 봅시다. 문장 마지막에, 나는 네가 그것들에 대해 좀 낯설지 않도록 이 방면의 참고 자료를 제공할 것이다. 또한 Jeff Lander 의 그래픽 열에서 충돌 탐지에 대한 문장 ("새해를 맞췄습니다."; "두 마음이 충돌할 때"; 그리고 "충돌 응답: 신축성, 재미, 재미,"). 먼저 대략적인 설명을 한 다음 핵심 내용으로 빠르게 들어가 이 두 단계를 통해 위에서 아래로 충돌 감지까지 파고들겠습니다. (데이비드 아셀, Northern Exposure (미국 TV 드라마), 스포츠명언) 두 가지 유형의 그래픽 엔진 (포털 기반 및 BSP 기반) 에서 충돌 감지에 대해 설명하겠습니다. 각 엔진의 다각형 구성은 다르므로 세계-물체 충돌 탐지에 큰 차이가 있습니다. 물체-물체 충돌 탐지는 위의 두 엔진 중 대부분 모두 동일합니다. 주로 당신이 어떻게 실현하느냐에 따라 다릅니다. 우리가 폴리곤의 충돌 탐지를 접할 때, 우리는 또한 우리가 배운 볼록 물체까지 어떻게 확장할 수 있는지를 실험할 것이다.

이상적인 충돌 감지 프로그램을 만들려면 해당 프레임워크를 계획하고 만드는 동시에 게임에 대한 그래픽 파이프를 개발해야 합니다. 프로젝트 끝에 간섭 테스트를 추가하는 것은 상당히 어렵습니다. 개발 주기가 끝날 때 빠른 충돌 탐지를 만들려고 하면 효율적으로 실행할 수 없기 때문에 전체 게임이 손상될 수 있습니다. 좋은 게임 엔진에서 충돌 탐지는 정확하고 효과적이며 매우 빨라야 합니다. 이러한 요구 사항은 충돌 탐지가 장면의 다각형 관리 파이프와 밀접하게 관련되어 있음을 의미합니다. 이것은 또한 가난법이 통하지 않는다는 것을 의미한다. 오늘날의 3D 게임에서 프레임당 처리되는 데이터의 양은 메시가 끊길 수 있습니다. 한 오브젝트의 각 다각형이 장면의 다른 다각형과 충돌하는지 여부를 감지할 때 시간이 지났습니다.

먼저 기본 게임 엔진 루프 (목록 1) 를 말씀드리겠습니다. 이러한 코드를 빠르게 탐색하여 간섭 테스트에 대한 전략을 얻습니다. 우리는 충돌이 발생하지 않았다고 가정하고 물체의 위치를 업데이트한다. 충돌이 발견되면, 우리는 물체를 원래의 위치로 옮겨 국경을 넘지 못하게 합니다 (또는 물체를 파괴하거나 예방 조치를 취하는 것). 그러나 이 가설은 너무 간단하다. 왜냐하면 우리는 물체의 원래 위치가 여전히 유효한지 알 수 없기 때문이다. 이 상황에 대한 계획을 세워야 합니다. (그렇지 않으면 앞의 예와 같이 붕괴나 총알에 맞은 느낌을 경험할 수 있습니다.) 만약 당신이 열정적인 선수라면, 일부 게임에서는 벽에 접근하여 통과하려고 할 때 카메라가 흔들리기 시작한다는 것을 이미 알아차렸을 것이다. 네가 겪고 있는 것은 주인공을 원래 위치로 옮기는 상황이다. 진동은 더 큰 시간 조각을 가져 와서 발생합니다.

목록 1. 매우 단순화된 게임 주기

While( 1){

Process_input () 을 참조하십시오.

Update _ objects ();

Render _ world ();

}

Update_objects(){

에 대해 (객체당)

Save_old_position () 을 참조하십시오.

새 객체 위치 계산

{속도 가속도를 기준으로 합니다. 등등. }

If (collide_with_other_objects ())

New_object_position = 기존 _ position ();

{또는 손상된 오브젝트가 제거되면 등등. }

그림 1. 시간 기울기 및 충돌 테스트

그러나 우리의 방법은 결함이 있다. 우리는 등식에 시간을 추가하는 것을 잊었다. 그림 1 시간이 너무 중요해서 잊을 수 없다고 말해 주세요. 물체가 t 1 또는 T2 에서 충돌하지 않더라도 T (t 1) 에서 경계를 넘을 수 있습니다

우리는 시간을 4 차원으로 보고 4 차원 공간에서 모든 작업을 할 수 있다. 그러나 이로 인해 조작이 복잡해질 수 있으므로 우리는 이를 피할 것이다. 또한 t 1 및 T2 의 개체부터 시작하여 벽과 테스트할 수 있습니다 (그림 2 참조).

한 가지 쉬운 방법은 서로 다른 시간에 두 객체를 덮는 볼록 가방을 만드는 것입니다. 이런 방법의 비효율은 너의 게임 속도를 현저히 낮출 수 있다. 볼록 선체를 만들려면 솔리드 주위에 경계 상자를 만드는 것이 좋습니다. 우리는 다른 기술을 배운 후에 다시 돌아와서 이 문제를 토론할 것이다.

더 쉽게 구현할 수 있지만 정확하지 않은 또 다른 방법은 지정된 기간을 두 부분으로 나누고 시점 간의 교차 관계를 테스트하는 것입니다. 각 세그먼트의 시간 중간점을 차례로 재귀적으로 결정할 수도 있습니다. 이 방법은 이전 방법보다 훨씬 빠르지만 모든 충돌이 캡처될 수 있다는 보장은 없습니다.

또 다른 숨겨진 문제는 한 오브젝트가 장면의 다른 오브젝트와 교차하는지 여부를 결정하는 collide_with_other_objects () 메서드의 구현입니다. 장면에 많은 오브젝트가 있는 경우 이 방법은 매우 비쌀 수 있습니다. 장면의 각 오브젝트가 다른 오브젝트와 교차하는지 확인하려면 두 번 정도 비교해야 합니다. 그래서 비교 횟수는 N 의 제곱일까요? 또는 O(N2) 로 표시됩니다. 그러나 우리는 여러 가지 방법으로 O(N2) 쌍을 비교하지 않을 수 있다. 예를 들어 장면의 오브젝트를 정적 (충돌 오브젝트) 과 동적 (충돌 오브젝트 속도가 0 인 경우에도) 으로 나눌 수 있습니다. 마치 방 안의 벽이 부딪힌 것처럼 벽에 던져진 작은 공이 부딪혔다. 두 개의 개별 나무 (각 오브젝트 유형당 하나) 를 만든 다음 오브젝트가 충돌할 수 있는 나무를 테스트할 수 있습니다. 우리는 심지어 일부 충돌한 물체가 충돌하지 않도록 환경에 합의할 수도 있다. 예를 들어, 우리는 두 총알 사이에서 판단할 필요가 없다. 이제 우리가 계속하기 전에, 우리는 이 과정이 더 명확해졌다고 말할 수 있다. 장면에서 한 쌍의 비교를 줄이는 또 다른 방법은 8 진 트리를 만드는 것입니다. 이것은이 기사의 범위를 벗어납니다. 공간 데이터 구조: 쿼드 트리, 8 진 트리 및 기타 계층 방법의 추가 정보 섹션에서 8 진 트리에 대한 자세한 정보를 읽을 수 있습니다. 이제 포털 기반 엔진을 살펴 보겠습니다. 이 엔진에서 충돌 감지를 언급하는 것이 왜 그렇게 고통스러운지 살펴보겠습니다.

포털 엔진 및 오브젝트-오브젝트 충돌

포털 기반 엔진은 장면이나 표준을 더 작은 볼록 사각형 영역으로 나눕니다. 볼록한 사각형 영역은 다시 그려지지 않도록 하므로 그래픽 파이프에 적합합니다. 불행히도, 충돌 탐지를 위해 볼록 사각형 영역은 우리에게 약간의 어려움을 가져다 줄 것이다. 나의 최근 테스트 중 한 대의 엔진은 평균 400 ~ 500 개의 볼록한 사각형 영역을 가지고 있다. 물론 이 숫자는 엔진마다 다를 수 있습니다. 엔진마다 다른 다각형 기술을 사용하기 때문입니다. 다각형의 수는 장면의 크기에 따라 달라집니다.

오브젝트의 다각형이 장면의 다각형을 통과하는지 여부를 판단하면 계산량이 커질 수 있습니다. 가장 간단한 충돌 탐지 방법 중 하나는 구체를 사용하여 물체 또는 물체의 일부를 대략적으로 표시한 다음 주변 구가 교차하는지 여부를 판단하는 것입니다. 이렇게 하려면 두 구의 중심 사이의 거리가 반지름 (즉, 충돌) 보다 작은지 테스트하기만 하면 됩니다. 중심점 거리의 제곱과 반지름의 제곱을 비교하는 것이 더 좋으므로 거리를 계산할 때 제곱근 연산 차이를 제외할 수 있습니다. 그러나 간단한 작업으로 인해 정확도가 떨어질 수도 있습니다 (그림 3 참조).

그림 3. 구가 구와 교차하는 경우 루틴에서 실제로 발생하지 않고 충돌이 발생했다고 보고할 수 있습니다.

그러나 우리는 단지 이 부정확한 방법을 우리의 첫 걸음으로 삼을 뿐이다. 우리는 하나의 큰 구를 사용하여 전체 물체를 표시한 다음 그것이 다른 구와 교차하는지 확인합니다. 충돌이 감지되면 정확도를 더욱 높여야 합니다. 큰 구를 일련의 작은 구로 나누어 각 작은 구에 충돌이 있는지 확인할 수 있습니다. 우리는 만족스러운 근사치를 얻을 때까지 끊임없이 나누고 검사한다. 계층화와 분할의 기본 사상은 자신의 요구에 맞는 이상적인 상황을 달성하기 위해 최선을 다해야 한다는 것이다.

그림 4. 구 세분화.

하나의 구를 사용하여 하나의 물체를 대략적으로 표현하는데, 필요한 계산량은 매우 작지만, 게임에 있는 대부분의 물체는 정사각형이므로, 우리는 네모난 상자로 물체를 표현해야 한다. 개발자는 줄곧 포위상자와 이런 재귀의 빠른 방법을 사용하여 광선 추적 알고리즘을 가속화하고 있다. -응? 학원? 뭐 하는 거야? 잠시 동안 ABB (축 정렬 경계 상자) 가 나타납니다. 그림 5 는 AABB 와 해당 개체를 보여 줍니다. 그림 5. 객체와 해당 AABB 입니다.

축 정렬은 상자가 표준 축에 평행할 뿐만 아니라 상자의 각 면이 축에 수직임을 의미합니다. 이러한 기본 정보는 상자를 바꿀 때 작업 횟수를 줄일 수 있다. AABBs 는 오늘날 많은 게임에 응용되어 있으며, 개발자들은 종종 그것을 모델의 포위 상자로 사용한다. 다시 한 번, 정밀도를 높이면 속도가 느려질 수 있다는 점을 지적한다. AABBs 는 항상 좌표 사고에 평행하기 때문에 개체를 회전할 때 단순히 aabbs 를 회전할 수 없습니다. 모든 프레임을 다시 계산해야 합니다. 각 개체의 내용을 알고 있다면, 이 계산은 어렵지 않으며, 게임을 늦추지도 않을 것이다. 그러나, 우리는 여전히 정확성의 문제에 직면해 있다. 우리가 3 차원 날씬한 강성 직선봉을 가지고 있다고 가정해 봅시다. 애니메이션의 모든 프레임에서 AABB 를 다시 만들고 싶습니다. (존 F. 케네디, Northern Exposure (미국 TV 드라마), 애니메이션명언) 각 프레임의 경계 상자가 다르고 정밀도도 그에 따라 변하는 것을 볼 수 있습니다.