【问题标题】:Calculate bounding box collisions Oriented C++ opengl计算边界框碰撞面向C++ opengl
【发布时间】:2014-08-19 03:26:22
【问题描述】:

我正在使用 OpenGL 和 C++ 开发 3D 游戏,我需要一些信息和您的帮助来了解如何计算 OBB(定向边界框)(OBB 与 OBB、OBB 与其他早期)之间的碰撞。

我知道构成每个对象边界框的 8 个顶点(将其乘以模型矩阵并得到在“世界”中的位置);现在需要知道如何计算 OBB 之间的碰撞。

【问题讨论】:

  • 这是用 Java 编写的,但它是对您有所帮助的详尽讨论。 stackoverflow.com/a/10289567/2296458
  • @Cyber​​:该答案描述了轴对齐边界框 (AABB) 的碰撞检测,这是一个非常简单的问题。对于这张海报所询问的任意方向的边界框来说,它要复杂得多。
  • 你好,我需要的是使用OBB(更昂贵但更准确)计算碰撞,因为AABB不准确,因为它覆盖了物体的大面积并且不是很忠实。无论如何,谢谢。

标签: c++ opengl bounding-box


【解决方案1】:

如果您只需要知道对象是否发生碰撞,那么用于两个 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;
}

【讨论】:

    猜你喜欢
    • 2013-02-18
    • 2011-05-10
    • 2015-02-02
    • 2011-04-21
    • 2013-04-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多