Có một vài lời cảnh báo cho câu trả lời của tôi, rằng tôi sẽ tránh đường trước: Nó chỉ liên quan đến các hộp giới hạn không quay. Nó giả định rằng bạn đang cố gắng giải quyết các vấn đề đường hầm , tức là các vấn đề gây ra bởi các vật thể di chuyển ở tốc độ cao.
Khi bạn đã xác định được MTV, bạn biết cạnh / bề mặt bình thường bạn cần kiểm tra lại. Bạn cũng biết vectơ vận tốc tuyến tính của đối tượng xen kẽ.
Khi bạn đã thiết lập rằng tại một số điểm trong khung hình, một giao lộ đã xảy ra, sau đó bạn có thể thực hiện các thao tác nửa bước nhị phân, dựa trên các điểm bắt đầu sau: Xác định đỉnh xâm nhập đầu tiên trong khung:
vec3 vertex;
float mindot = FLT_MAX;
for ( vert : vertices )
{
if (dot(vert, MTV) < mindot)
{
mindot = dot(vert, MTV);
vertex = vert;
}
}
Khi bạn đã xác định được đỉnh, nửa bước nhị phân trở nên rẻ hơn rất nhiều:
//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;
Điều này là chính xác hợp lý, nhưng sẽ chỉ cung cấp một điểm va chạm duy nhất, trong một trường hợp duy nhất.
Vấn đề là, thường có thể nói trước liệu một vật thể sẽ di chuyển đủ nhanh trên mỗi khung hình để có thể chui như thế này, vì vậy lời khuyên tốt nhất là xác định các đỉnh dẫn dọc theo vận tốc và thực hiện kiểm tra tia dọc theo vectơ vận tốc. Trong trường hợp các đối tượng quay, bạn sẽ phải thực hiện một số loại trượt nửa bước nhị phân để xác nhận điểm tiếp xúc chính xác.
Tuy nhiên, trong hầu hết các trường hợp, có thể giả định một cách an toàn rằng hầu hết các đối tượng trong cảnh của bạn sẽ không di chuyển đủ nhanh để xâm nhập đến mức đó trong một khung hình duy nhất, do đó không cần phải thực hiện nửa bước và phát hiện va chạm rời rạc. Các vật thể tốc độ cao như đạn, di chuyển quá nhanh để nhìn thấy, có thể được chiếu tia cho các điểm tiếp xúc.
Thật thú vị, phương pháp nửa bước này cũng có thể cung cấp cho bạn thời gian (gần như) chính xác mà đối tượng xảy ra trong khung:
float collisionTime = frametimeSeconds * halfstep;
Nếu bạn đang thực hiện một số loại giải quyết va chạm vật lý, thì bạn có thể sửa vị trí của A bằng cách:
v - (v*halfstep)
sau đó bạn có thể làm vật lý của bạn bình thường từ đó. Nhược điểm là nếu đối tượng di chuyển hợp lý nhanh, bạn sẽ thấy nó dịch chuyển tức thời dọc theo vectơ vận tốc của nó.