Cevabımdan önce yoldan çıkacağım için birkaç uyarı var: Sadece dönmeyen sınırlama kutuları ile ilgileniyor. Tünel açma sorunlarını, yani yüksek hızda hareket eden nesnelerin neden olduğu sorunları ele almaya çalıştığınızı varsayar .
MTV'yi belirledikten sonra, test etmeniz gereken kenar / yüzey normalini bilirsiniz. Ayrıca, iç içe geçen nesnenin doğrusal hız vektörünü de bilirsiniz.
En tespit sonra bir noktada dilimi içinde, bir kesişme oluştu, daha sonra takip eden başlangıç noktaları göre, ikili yarım adım işlemleri gerçekleştirebilir: çerçeve sırasında birinci nüfuz tepe belirlenmesi:
vec3 vertex;
float mindot = FLT_MAX;
for ( vert : vertices )
{
if (dot(vert, MTV) < mindot)
{
mindot = dot(vert, MTV);
vertex = vert;
}
}
Tepe noktası belirlendikten sonra, ikili yarım adım çok daha ucuz hale gelir:
//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;
Bu oldukça doğrudur, ancak tek bir durumda yalnızca tek bir çarpışma noktası sağlayacaktır.
Mesele şu ki, bir nesnenin böyle tünelleme yapabilmek için kare başına yeterince hızlı hareket edip etmeyeceğini önceden söylemek mümkündür, bu nedenle en iyi tavsiye hız boyunca önde gelen köşeleri tanımlamak ve hız vektörü boyunca bir ışın testi yapmaktır. Dönen nesneler söz konusu olduğunda, doğru temas noktasını belirlemek için bir çeşit ikili yarım adımlı slerp yapmanız gerekir.
Bununla birlikte, çoğu durumda, sahnenizdeki çoğu nesnenin tek bir karede o kadar nüfuz edecek kadar hızlı hareket edemeyeceği, bu nedenle yarım adım gerekmeyeceği ve ayrık çarpışma tespitinin yeterli olacağı güvenli bir şekilde kabul edilebilir. Görmek için çok hızlı hareket eden mermiler gibi yüksek hızlı nesneler, temas noktaları için ışınlanabilir.
İlginç bir şekilde, bu yarım adım yöntemi, nesnenin çerçeve sırasında meydana geldiği (neredeyse) kesin zamanı da verebilir:
float collisionTime = frametimeSeconds * halfstep;
Bir tür fizik çarpışma çözünürlüğü yapıyorsanız, A'nın konumunu şu şekilde düzeltebilirsiniz:
v - (v*halfstep)
o zaman fiziğinizi normal olarak oradan yapabilirsiniz. Dezavantajı, eğer nesne oldukça hızlı hareket ederse, hız vektörü boyunca geri ışınlandığını göreceksiniz.