我正在使用OpenGL和C ++开发3D游戏,我需要一些信息和帮助来了解如何计算OBB(Oriented Bounding Box)之间的碰撞(OBB vs OBB,OBB vs其他早期。)
我知道构成每个对象的边界框的8个顶点(乘以模型矩阵并在“世界”中获得位置);现在需要知道如何计算OBB之间的碰撞。
答案 0 :(得分:0)
如果只需要知道对象是否碰撞,那么用于两个3D OBB之间的简单碰撞检测的分离轴定理的C ++代码实现将是:
struct vec3
{
float x, y, z;
vec3 operator- (const vec3 & rhs) const { return{ x - rhs.x, y - rhs.y, z - rhs.z }; }
float operator* (const vec3 & rhs) const { return{ x * rhs.x + y * rhs.y + z * rhs.z }; } // DOT PRODUCT
vec3 operator^ (const vec3 & rhs) const { return{ y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x }; } // CROSS PRODUCT
vec3 operator* (const float& rhs)const { return vec3{ x * rhs, y * rhs, z * rhs }; }
};
struct OBB
{
vec3 Pos, AxisX, AxisY, AxisZ, Half_size;
};
bool getSeparatingPlane(const vec3& RPos, const vec3 Plane, const OBB& box1, const OBB&box2)
{
return (fabs(RPos*Plane) > (fabs((box1.AxisX*box1.Half_size.x)*Plane) + fabs((box1.AxisY*box1.Half_size.y)*Plane) + fabs((box1.AxisZ*box1.Half_size.z)*Plane) +
fabs((box2.AxisX*box2.Half_size.x)*Plane) + fabs((box2.AxisY*box2.Half_size.y)*Plane) + fabs((box2.AxisZ*box2.Half_size.z)*Plane)));
}
bool getCollision(const OBB& box1, const OBB&box2)
{
static vec3 RPos;
RPos = box2.Pos - box1.Pos;
if (getSeparatingPlane(RPos, box1.AxisX, box1, box2) || getSeparatingPlane(RPos, box1.AxisY, box1, box2) || getSeparatingPlane(RPos, box1.AxisZ, box1, box2) ||
getSeparatingPlane(RPos, box2.AxisX, box1, box2) || getSeparatingPlane(RPos, box2.AxisY, box1, box2) || getSeparatingPlane(RPos, box2.AxisZ, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisX^box2.AxisX, box1, box2) || getSeparatingPlane(RPos, box1.AxisX^box2.AxisY, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisX^box2.AxisZ, box1, box2) || getSeparatingPlane(RPos, box1.AxisY^box2.AxisX, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisY^box2.AxisY, box1, box2) || getSeparatingPlane(RPos, box1.AxisY^box2.AxisZ, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisZ^box2.AxisX, box1, box2) || getSeparatingPlane(RPos, box1.AxisZ^box2.AxisY, box1, box2) ||
getSeparatingPlane(RPos, box1.AxisZ^box2.AxisZ, box1, box2)) return false;
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
OBB A, B;
A.Pos = { 0.f, 0.f, 0.f };
A.Half_size = {10.f, 1.f, 1.f};
A.AxisX = { 1.f, 0.f, 0.f };
A.AxisY = { 0.f, 1.f, 0.f };
A.AxisZ = { 0.f, 0.f, 1.f };
B.Pos = { 10.f, 0.f, 0.f };
B.Half_size = {10.f, 1.f, 1.f};
B.AxisX = { 1.f, 0.f, 0.f };
B.AxisY = { 0.f, 1.f, 0.f };
B.AxisZ = { 0.f, 0.f, 1.f };
if (getCollision(A, B)) std::cout << "Collision!!!" << std::endl;
else std::cout << "No collision." << std::endl;
std::cout << std::endl;
system("pause");
return 0;
}