물리 엔진에서 동시 충돌을 처리하는 가장 좋은 방법은 무엇입니까?


13

비디오 게임의 물리학에 대해 자세히 배울 수 있도록 2D 물리 엔진을 자바 스크립트로 작성하고 있습니다. 바디가 동시에 두 개 이상의 다른 바디와 충돌하는 경우를 제외하고는 딱딱한 바디 충돌에 대해 올바르게 작동합니다.

현재 충돌체 (A, B)의 각 쌍에 대해 충돌 임펄스에 따라 속도와 각속도를 수정하고 관통하지 않도록 서로 밀어냅니다. 그러나 A와 관련된 다른 충돌에 대한 충돌 감지 및 임펄스 계산은 잘못됩니다.

3 개 이상의 객체가 서로 충돌하도록 엔진을 작동시키기 위해 어떤 접근법을 탐색 할 수 있습니까?


2
관련 : gamedev.stackexchange.com/questions/15836/…gamedev.stackexchange.com/questions/26181/… 그리고 더 많은 것이 있다고 확신합니다. 지금은 찾을 수 없습니다.
MichaelHouse

답변:


11

다음과 같은 접근 방식을 사용합니다 (Tonge http://www.richardtonge.com/ 의 질량 분할 알고리즘과 유사 ).

  • 장면 / 컨텍스트에서 충돌하는 모든 쌍을 감지합니다. (A, B)를 그런 쌍으로 만드십시오. 고스트 / 질량 분할 아이디어 적용 : A가 M 바디와 접촉하고 B가 다른 N 바디와 접촉하는 경우 A 의 질량 을 B로 일시적으로 설정합니다.m_A/Mm_B/N
  • 각 쌍 (A, B)에 대한 반력 / 반발력 기여를 계산하고 이러한 기여를 A와 B의 자체 누적기에 저장
  • 임펄스에서 복원 속도를 계산하고 (설명한대로) 동일한 방식으로 저장합니다 ( 각 (A, B) 쌍에 대해 자체 누적 기의 deltaV 속도 잔류 물로 )
  • 페널티 변위 계산 (다시, 변위 축적, 즉시 적용하지 마십시오!)
    • 충돌 쌍으로 이전에 당사자로 지정된 모든 바디의 질량을 재설정 ( m_A = m_A * Mm_B = m_B * N)

이 방법은 Jacobi 반복 알고리즘이 선형 연립 방정식 시스템에서 작동하는 방식과 유사합니다. 그리고 수렴이 보장되지는 않지만 시뮬레이터에서 3D로 작업이 매끄럽게 수행됩니다 (예, 추가 치수는 두 배의 어려움을 더합니다!)

경고 : 충돌 감지 / 처리 단계가 끝난 후에 만 ​​정확한 위치와 속도를 확인하십시오! 그렇게하면 충돌하는 액터를 동시에 업데이트 할 수 있습니다. 또한 다음에 위치와 속도를 통합 할 때 복원력을 고려해야합니다.

편집 : 글쎄, 당신은 이미 남용 된 Verlet 통합 방법을 사용하고 있다고 생각합니다 (이 방법은 gamedev 애호가들 사이에서 세대 이름이되었습니다). 이 충돌 처리 및 통합 스펙터에서 여기를 살펴볼 수 있습니다 .

업데이트 : 충돌에 접근하는 방법에 대한 일부 정보 (및 사실에 대한 자체 충돌)는 다음 백서에서 찾을 수 있습니다.

내가 제안한 접근법은 오래 전부터 독창적 인 기여를하는 것이 아니며, 많은 게임들이 그 결과를 그럴듯한 결과로 사용하며 Jakobsen은 그의 Hitman 게임 엔진에서 가장 잘 활용했습니다.

다소 실제적인 경험으로 볼 때 충돌하는 몸체의 다른 힘이 그보다 큰 경우 페널티 힘 (관통 거리에서 입력을받는 선형 또는 지수 스프링과 유사)이 침투를 제대로 해결하지 못합니다. 그렇기 때문에 나는 뉴턴의 반력 (벽을 밀고 벽을 뒤로 밀고), 유도 된 속도 (스누커 공 충돌)와 자연스럽지 않은 신체를 기하학적으로 서로 멀어지게하는 세 가지 (거의 중복 된) 접근법을 결합하기로 결정했습니다. " 해결책. 함께 그들은 모든 것을 제공하는 것처럼 보입니다 : 대부분을 제거하십시오추악한 상호 침투 아티팩트, 충돌 바디는 장기적으로 서로 상호 작용하는 경향이 있습니다 (복원 속도와 힘으로 인해 충돌 시나리오에서 바디를 드래그하는 경향이 사라지고 바디는 서로 튀어 나옵니다) . 마지막으로 이러한 단순하지만 일반적인 개념에 대한 이해를 돕기 위해이 슬라이드를 분석 하는 것이 좋습니다 .

Verlet 통합 단계를 설명하는 나의 "가혹한 방법"은이 통합 방법의 성배라는 대중 문화의 신념을 대상으로합니다. 그것은 Symplectic Euler (일부 반 암시 적 Euler라고도 함) 사촌보다 조금 더 낫습니다. 더 복잡한 통합 방법이 존재합니다 (그리고 모두 암시 적 이름을 가짐). 강력한 게임 엔진이이를 활용하지만 인디 개발자는 특정 시나리오에 맞춰 Verlet이 실제로 실험 한 이후로 이러한 기능을 실험 할 시간이 없습니다. 또한, 약간의 부정 행위가 발생하지 않고 뻣뻣한 구속 조건을 처리 할 수있는 통합 방법이 전혀 없습니다 (링크를 찾을 수는 없지만 제가 언급 한 논문은 "X.Provot-"질량의 변형 구속 조건 "이라고합니다) 헝겊 동작을 설명하는 봄 모델 "


감사합니다 (+1)! '배상 속도'와 '벌칙 변위'란 무엇입니까? 또한 왜 버렛 통합이 '거품'이라고 말합니까? 사용하기에 나쁜 방법이라고 생각하십니까?
Cam

복원 속도는 임펄스에서 얻을 수있는 속도입니다. 단, 차이점은 잔차로 계산한다는 것입니다 (즉, 추가 계산을 위해 전류 속도를 그대로 유지하면서 임펄스 기반 속도와 현재 속도의 차이를 저장합니다). 페널티 변위는 두 물체가 얼마나 많은 양을 관통하는지에 의해 결정되는 길이를 가진 벡터이며, 하나의 물체를 다른 물체 밖으로 완전히 번역 할 수있는 최소 길이의 벡터입니다. 나는 보통 길이를 2로 나눈 각 객체에 그러한 변위를 추가합니다.
teodron

1
훌륭한 답변! 그래도 다른 질문이 있습니다. 회복 속도를 누적한다고하더라도 매우 비현실적인 숫자가되지 않습니까? 객체 A와의 충돌을 개별적으로 처리하고 각 객체에 대한 효과를 추가하면 A가 객체 사이에 임펄스가 퍼지지 않습니까? 대신 전체적으로 충동이 나에게 직관적으로 잘못 보이는 각각에 적용될 것입니다
Cam

아주 좋은 질문입니다. 한 관점에서 볼 때 충동이 결과적으로 속도에 부가 적으로 기여하는 것은 그럴듯 해 보입니다. 여기에 내 (아마도 잘못된!) 추론이 있습니다 : 3 개의 수영장 / 스누커 공이 충돌한다고 상상해보십시오. 그들 중 하나는이 부가적인 방식으로 다른 두 가지로부터 기여를 받아야합니다. 처음에는 이러한 기여도를 측정하고 최종 속도에 대한 가중 평균을 계산한다고 생각했지만 빠른 결과를 원했기 때문에이 아이디어를 건너 뛰었습니다. 대체로 충돌하는 볼은 나머지 두 개에서 속도 기여를 가져와야합니다. 고등학교 교과서가 도움이 될 수 있습니다.
teodron

3
아마도 나는 다음 예제가 여전히 우려하기 때문에 당신이 설명 한 것을 이해하지 못할 것입니다 : 가로로 긴 사각형이 똑바로 떨어지는 것을 고려하고 바닥이 들쭉날쭉하다고 가정하십시오 (여러 개의 삼각형으로 구성되어 있음). 누적 방법을 사용하여 n 개의 삼각형이있는 경우 사각형은 필요한 속도의 n 배로 튀어 오릅니다! 그 상황은 어떻게 고칠 수 있습니까?
Cam

1

속도를 바꾸는 대신 물체에 작용 하는 을 바꾸는 것이 좋습니다 . 그것들을 "nudge"하지 말고, 기존 코드를 부드럽게 사용하십시오. 이렇게함으로써 신체는 그들의 속도를 즉시 (그리고 신속하게) 바꾸지 않을 것입니다.

: 예는 Box2DJS을 확인 http://box2d-js.sourceforge.net/index2.html .


-1

충돌체 그룹에 대한 임펄스 방정식을 분석적으로 해결했습니다. 내가 직면 한 유일한 문제는 그룹의 접촉 사이에서 상대 상호 작용 강도를 찾는 변수가 부족하여 신체 깊이 교차로 채워져 있다는 것입니다.

그룹 컨택에 대한 솔루션은 단일 컨택보다 그리 어렵지 않습니다. 불행히도 나는 계산으로 종이를 잃어 버렸으므로 여기서 공유 할 수 없었습니다.

편집 : 아마도이 /physics/296767/multiple-colliding-balls 와 같은 것을 생각해 냈습니다.

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