2D 물리 엔진에서 물체가 휴식을 취할 때 쓸모없는 충돌 해결을 어떻게 피할 수 있습니까?


9

love-2d를 사용하여 (학습을 위해) 물리 엔진 에서 다음과 같이 충돌 해결을 구현했습니다.

FixedUpdate(dt)  // I use fixed timestep
 foreach collide c1 in allNotStaticColliders
   c1.integartePhysic // i.e. apply gravitational force..
   foreach collider c2 "near" c1 // "near"= I use spatial hashing 
      if collide(c1,c2)
        resolve collision (c1,c2)  // the heavy operation
        collison callbacks c1
        collison callbacks c2
        ...

정지하고 정지하는 객체의 애니메이션

gif 애니메이션의 끝에서 볼 수 있듯이 모든 충돌체가 정적 객체 위에 거의 접지되면 FPS 붕괴가 발생합니다.

2 FPS의 최종 정적 상태

이것은 충돌 할 때 물체가 만지면 더 많은 시간을 보내면서 충돌 해결 수가 증가하기 때문입니다. 그러나 객체가 이미 서로에 대해 안정적인 위치에 정착했기 때문에 많은 계산이 "무용지물"입니다.

이러한 "불필요한"충돌 탐지를 피하기위한 최선의 방법 (물리학 학위가 필요하지 않음)은 무엇입니까?

편집 : DMGregory 힌트를 수락 하고이 결과를 얻습니다 (아직 최적은 아님)

여기에 이미지 설명을 입력하십시오

(적색 = 정적, 청색 = 활성, 녹색 = 수면)


1
일반적인 방법은 잠들게되는 객체를 "잠자기"하는 것입니다. 잠자기 / 정적 객체 간의 상호 작용을 고려하지는 않습니다 (그러나 잠자기 개체는 여전히 깨어 있고 움직이는 동적 객체와의 상호 작용에 의해 깨어날 수 있습니다). 불행히도 이것은 물체가 완전히 정지 된 후에 만 ​​도움이됩니다. 예제를 올바르게 읽으면 객체가 여전히 정착하고 약간 움직일 때 성능 문제가 시작되는 것처럼 보입니다. 여기서 생각할 수있는 것은 시스템에 마찰 / 댐핑을 더 추가하여 (속도 임계 값으로) 작은 움직임이 실제 휴식으로 더 빨리 붕괴되도록하는 것입니다.
DMGregory

@DMGregory 좋은 답변 인 것 같습니다. 추가 하시겠습니까?
Anko

답변:


9

OP가 이미이 접근법을 알고 있다고 생각했기 때문에 의견에서 시작점으로 언급했지만 조금 더 살려 보려고합니다 ...

대부분의 물리 엔진은 동적 객체를 " 깨어 라 "와 " 자고 " 라는 두 그룹으로 나눕니다 .

물체는 휴식을 취하면 잠을 자고 외부 영향을 받아 움직이거나 가속하면 깨어납니다.

수면 (이 정지 때문에이 더 움직임이 없다, 그래서)의 움직임이 시간이 지남에 통합되지 않고 자고있는 객체 또는 정적 사이의 엔진 무시 충돌 - 대부분의 측면에서 정적 객체와 같은 객체 동작합니다.

중력을 포함하여 수면 물체에 대한 모든 움직임 통합이 생략되므로 충돌 응답이 없어도 정적 바닥에 수면 물체가 떨어지지 않습니다.

따라서 하나 이상의 깨우기 동적 객체와 관련된 충돌 만 확인하면됩니다.

Collisions    Static          Sleeping           Awake
          ------------------------------------------------
Awake     |    Check        Check & Wake         Check
Sleeping  |     No               No
Static    |     No

이를 통해 능동 시뮬레이션이 필요한 객체의 수를 극적으로 줄일 수 있습니다. 특히 문제에서 설명 된 것처럼 상호 충돌이 많고 순 움직임이 거의 없는지 확인하는 파일에서 더욱 그렇습니다.

잠자는 것은 물체가 실제로 휴식에 도달 한 후에 만 ​​도움이 되며 시간이 걸릴 수 있습니다.

더 빨리 휴식을 취하기 위해 할 수있는 일 :

  • 최소 속도 또는 운동량이 0이 아니고 그 이하로 떨어지는 것은 제로로 고정하십시오. (이것은 기본적으로 엡실론이며, 수레를 비교하는 데 일반적으로 사용됩니다)

  • 마찰, 댐핑 및 비탄성 충돌을 사용하여 시스템에서 에너지를 흡수하고 전체적으로 더 빨리 휴식을 취하도록 돕습니다.

  • 움직임이 느린 물체의 경우 마찰 / 댐핑 / 불완전 성을 선택적으로 높이면 보다 에너지가 많은 물체의 동작에 영향을주지 않으면 서 최종 너지 (nudge)를 멈출 수 있습니다.


좋은 대답입니다. 수면 / 깨우기 점검의 경우 2 가지 약점이 있습니다. 1) 수면 물체 o2 아래에있는 수면 물체 o1이 o2에서 멀어지면 깨어나지 않습니다. o2를 깨우지 않습니다. 2) 나는 개체) 중력의 힘에 따라 (안 깨어 않는다는 것을, 잠자는 개체 아래 정적 플랫폼을 제거하는 경우
DNK가 drone.vs.drones

1
@ dnkdrone.vs.drones 좋은 관찰. 물리 엔진을 직접 작성한 적이 없어서 이것이 어떻게 정상적으로 처리되는지 잘 모르겠습니다. 한 가지 가능성은 객체를 잠자기 상태로 설정할 때 접촉하는 객체 목록을 저장하거나 로컬 객체 클러스터에 추가하는 것입니다. 잠든 물체를 깨우면 목록 / 클러스터의 모든 것을 깨 웁니다. 깨어나는 순간 (이동하기 전에) 근처의 연락처를 확인하는 것과 같이 더 우아한 옵션이있을 수 있습니다.
DMGregory
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.