Ada beberapa peringatan untuk jawaban saya, bahwa saya akan keluar dari jalan pertama: Ini hanya berurusan dengan kotak berlari yang tidak berputar. Diasumsikan bahwa Anda mencoba menangani masalah tunneling , yaitu masalah yang disebabkan oleh objek yang bergerak dengan kecepatan tinggi.
Setelah Anda mengidentifikasi MTV, Anda tahu tepi / permukaan normal yang perlu Anda uji. Anda juga tahu vektor kecepatan linier dari objek yang saling menembus.
Setelah Anda menetapkan bahwa di beberapa titik selama bingkai, terjadi persimpangan, Anda kemudian dapat melakukan operasi setengah langkah biner, berdasarkan titik awal berikut: Identifikasi titik yang pertama kali menembus selama bingkai:
vec3 vertex;
float mindot = FLT_MAX;
for ( vert : vertices )
{
if (dot(vert, MTV) < mindot)
{
mindot = dot(vert, MTV);
vertex = vert;
}
}
Setelah Anda memiliki simpul diidentifikasi, setengah langkah biner menjadi jauh lebih murah:
//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;
Ini cukup akurat, tetapi hanya akan memberikan satu titik tumbukan, dalam satu kasus.
Masalahnya adalah, biasanya mungkin untuk mengetahui terlebih dahulu apakah suatu objek akan bergerak cukup cepat per frame untuk dapat terowongan seperti ini, jadi saran terbaik adalah mengidentifikasi simpul terkemuka sepanjang kecepatan dan melakukan tes sinar sepanjang vektor kecepatan. Dalam hal objek berputar, Anda harus melakukan semacam biner halfstep slerp untuk memastikan titik kontak yang benar.
Dalam kebanyakan kasus, meskipun demikian, dapat diasumsikan dengan aman bahwa sebagian besar objek dalam adegan Anda tidak akan bergerak cukup cepat untuk menembus sejauh itu dalam satu frame tunggal, sehingga tidak diperlukan setengah langkah, dan deteksi tabrakan diskrit akan cukup. Objek berkecepatan tinggi seperti peluru, yang bergerak terlalu cepat untuk dilihat, dapat ditelusuri untuk titik kontak.
Menariknya, metode setengah-setengah ini juga dapat memberi Anda (hampir) waktu yang tepat ketika objek terjadi selama bingkai:
float collisionTime = frametimeSeconds * halfstep;
Jika Anda melakukan semacam resolusi tabrakan fisika, Anda kemudian dapat memperbaiki posisi A dengan:
v - (v*halfstep)
maka Anda dapat melakukan fisika Anda secara normal dari sana. Kelemahannya adalah jika objek bergerak cukup cepat, Anda akan melihatnya bergerak kembali bersama vektor kecepatannya.