내 대답에는 몇 가지주의 사항이 있습니다. 터널링 문제, 즉 고속으로 움직이는 물체로 인한 문제 를 처리하려고한다고 가정합니다 .
MTV를 식별하면 테스트해야 할 가장자리 / 표면 법선을 알 수 있습니다. 또한 상호 침투 물체의 선형 속도 벡터도 알고 있습니다.
당신에게 있음을 설립 한 후 어느 시점 프레임 동안, 교차로가 발생하면 다음 시작 포인트를 기준으로, 진 반 단계의 작업을 수행 할 수 있습니다 : 프레임 중 첫번째 관통하는 정점을 확인합니다 :
vec3 vertex;
float mindot = FLT_MAX;
for ( vert : vertices )
{
if (dot(vert, MTV) < mindot)
{
mindot = dot(vert, MTV);
vertex = vert;
}
}
정점이 식별되면 이진 반 단계는 훨씬 저렴합니다.
//mindistance is the where the reference edge/plane intersects it's own normal.
//The max dot product of all vertices in B along the MTV will get you this value.
halfstep = 1.0f;
vec3 cp = vertex;
vec3 v = A.velocity*framedurationSeconds;
float errorThreshold = 0.01f; //choose meaningful value here
//alternatively, set the while condition to be while halfstep > some minimum value
while (abs(dot(cp,normal)) > errorThreshold)
{
halfstep*=0.5f;
if (dot(cp,normal) < mindistance) //cp is inside the object, move backward
{
cp += v*(-1*halfstep);
}
else if ( dot(cp,normal) > mindistance) //cp is outside, move it forward
{
cp += v*(halfstep);
}
}
return cp;
이것은 상당히 정확하지만, 단일 경우에는 단일 충돌 지점 만 제공합니다.
문제는 일반적으로 프레임 당 객체가 이와 같이 터널링 할 수있을만큼 충분히 빠르게 움직 일지 미리 알 수 있으므로 속도를 따라 주요 정점을 식별하고 속도 벡터를 따라 광선 테스트를 수행하는 것이 가장 좋습니다. 회전하는 물체의 경우 올바른 접점을 확보하기 위해 일종의 이진 반 단계 슬리핑을 수행해야합니다.
그러나 대부분의 경우 장면의 대부분의 객체가 단일 프레임에서 멀리까지 충분히 빠르게 이동하지 않기 때문에 하프 스테핑이 필요하지 않으며 불연속 충돌 감지로 충분합니다. 너무 빨리 이동하는 탄환과 같은 고속 물체는 접점에 대해 광선 추적 될 수 있습니다.
흥미롭게도,이 반 단계 방법은 프레임 동안 오브젝트가 발생한 (거의) 정확한 시간을 제공 할 수도 있습니다.
float collisionTime = frametimeSeconds * halfstep;
어떤 종류의 물리 충돌 해결을 수행하는 경우 다음을 통해 A의 위치를 수정할 수 있습니다.
v - (v*halfstep)
거기서 물리학을 정상적으로 할 수 있습니다. 단점은 물체가 합리적으로 빠르게 움직이면 속도 벡터를 따라 순간 이동하는 것을 볼 수 있다는 것입니다.