1 Ray-AABB交叉檢測算法
1.求射線與長方體6個面的距離,確定距離最小的三個面
計算射線在這三個面上的交點。從距離最小的交點開始判定是否在AABB盒裏
2 COCOS3.3 Ray-AABB實現
Ray-AABB碰撞檢測
進行求出射線後,需要做的便是與包圍盒的碰撞檢測了,如之前的代碼所示,在做碰撞檢測時,Cocos2d-x 3.3beta0中的Ray類裏面爲我們提供了intersects()方法,該方法的參數有OBB對象和AABB對象兩種,實際上最終都是轉換成了對AABB的檢測,最後來看一下碰撞檢測相關代碼:
bool Ray::intersects(const AABB& aabb) const
{
Vec3 ptOnPlane; //射線與包圍盒某面的交點
Vec3 min = aabb._min; //aabb包圍盒最小點座標
Vec3 max = aabb._max; //aabb包圍盒最大點座標
const Vec3& origin = _origin; //射線起始點
const Vec3& dir = _direction; //方向矢量
float t;
//分別判斷射線與各面的相交情況
//判斷射線與包圍盒x軸方向的面是否有交點
//射線x軸方向分量不爲0 若射線方向矢量的x軸分量爲0,
//射線不可能經過包圍盒朝x
//軸方向的兩個面
if (dir.x != 0.f)
{
/*
使用射線與平面相交的公式求交點
*/
if (dir.x > 0)//若射線沿x軸正方向偏移
t = (min.x - origin.x) / dir.x;
else //射線沿x軸負方向偏移
t = (max.x - origin.x) / dir.x;
if (t > 0.f) //t>0時則射線與平面相交
{
ptOnPlane = origin + t * dir; //計算交點座標
//判斷交點是否在當前面內
if (min.y < ptOnPlane.y && ptOnPlane.y < max.y && min.z < ptOnPlane.z && ptOnPlane.z < max.z)
{
return true; //射線與包圍盒有交點
}
}
}
//若射線沿y軸方向有分量 判斷是否與包圍盒y軸方向有交點
if (dir.y != 0.f)
{
if (dir.y > 0)
t = (min.y - origin.y) / dir.y;
else
t = (max.y - origin.y) / dir.y;
if (t > 0.f)
{
ptOnPlane = origin + t * dir;
if (min.z < ptOnPlane.z && ptOnPlane.z < max.z && min.x < ptOnPlane.x && ptOnPlane.x < max.x)
{
return true;
}
}
}
//若射線沿z軸方向有分量 判斷是否與包圍盒y軸方向有交點
if (dir.z != 0.f)
{
if (dir.z > 0)
t = (min.z - origin.z) / dir.z;
else
t = (max.z - origin.z) / dir.z;
if (t > 0.f)
{
ptOnPlane = origin + t * dir;
if (min.x < ptOnPlane.x && ptOnPlane.x < max.x && min.y < ptOnPlane.y && ptOnPlane.y < max.y)
{
return true;
}
}
}
return false;
}