2D AABBvsAABBスイープキャストをゲームに実装しましたが、スイープキャストのヒットノーマルを計算するのが困難です。
AとBの両方のAABB位置とxy min-maxのスイープ方向があり、動作する最初と最後のヒット時間はありますが、衝突エッジまたは法線方向はありません。この特定の問題に対する効率的な解決策を概念化することはできません。何か案は?:)
*編集
これは私がこれまで持ってきたものです- ゴメスとクリスター・エリクソンの AABBスイープの単なる一般的な実装です。通常のヒットはないので、通常の計算は私には謎ですが、キャラクターコントローラーに対して衝突応答を生成することはできません。
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;
}