Ich habe einen 2D-AABBvsAABB-Sweep-Cast in mein Spiel implementiert, habe jedoch Schwierigkeiten, die Treffer-Normalen des Sweep-Casts zu berechnen.
Ich habe die Sweep-Richtung, sowohl die a- als auch die b-AABB-Position und die xy-Min-Max-Werte, die ersten und letzten Trefferzeiten, aber nicht die Kollisionskante (n) oder die normale Richtung. Ich kann mir einfach keine effiziente Lösung für dieses spezielle Problem vorstellen. Irgendwelche Ideen? :) :)
*bearbeiten
Dies ist, was ich bisher habe - nur eine allgemeine Implementierung des AABB-Sweeps von Gomez und Christer Ericson . Es gibt keinen normalen Treffer, daher ist mir die normale Berechnung zwar ein Rätsel, aber ich kann keine Kollisionsantwort für meinen Charakter-Controller erzeugen.
bool SweepVelAABBvsAABB(AABB a, AABB b, Vector2 v, out Vector2 outVel, out Vector2 norm )
{
outVel = v; //Initialise out velocity
norm = Vector2.zero;
if( AABBvsAABB(a,b) ) return true; //return early if a,b overlap
v = -v;
float hitTime = 0.0f;
float outTime = 1.0f;
if(v.x < 0.0f) //sweep is going right
{
if(b.max.x < a.min.x) return false;
if(a.max.x < b.min.x) hitTime = Mathf.Max( (a.max.x - b.min.x) / v.x, hitTime );
if(b.max.x > a.min.x) outTime = Mathf.Min( (a.min.x - b.max.x) / v.x, outTime );
}
else if(v.x > 0.0f) //sweep is going left
{
if(b.min.x > a.max.x) return false;
if(b.max.x < a.min.x) hitTime = Mathf.Max( (a.min.x - b.max.x) / v.x, hitTime );
if(a.max.x > b.min.x) outTime = Mathf.Min( (a.max.x - b.min.x) / v.x, outTime );
}
if(hitTime > outTime) return false;
//=================================
if(v.y < 0.0f) //sweep is going up
{
if(b.max.y < a.min.y) return false;
if(a.max.y < b.min.y) hitTime = Mathf.Max( (a.max.y - b.min.y) / v.y, hitTime );
if(b.max.y > a.min.y) outTime = Mathf.Min( (a.min.y - b.max.y) / v.y, outTime );
}
else if(v.y > 0.0f) //sweep is going down
{
if(b.min.y > a.max.y) return false;
if(b.max.y < a.min.y) hitTime = Mathf.Max( (a.min.y - b.max.y) / v.y, hitTime );
if(a.max.y > b.min.y) outTime = Mathf.Min( (a.max.y - b.min.y) / v.y, outTime );
}
if(hitTime > outTime) return false;
outVel = -v * hitTime;
return true;
}