我正在尝试使用 OpenGL 3.2+ 并开始以 3D 格式加载 Obj 文件/模型并尝试与它们进行交互。(遵循来自本网站等来源的教程)
我想知道在不使用第三方物理引擎等的情况下,在两个现有(加载的)Obj 对象/模型之间设置碰撞检测的最简单方法(如果可能的话)是什么?
我正在尝试使用 OpenGL 3.2+ 并开始以 3D 格式加载 Obj 文件/模型并尝试与它们进行交互。(遵循来自本网站等来源的教程)
我想知道在不使用第三方物理引擎等的情况下,在两个现有(加载的)Obj 对象/模型之间设置碰撞检测的最简单方法(如果可能的话)是什么?
可以满足您的标准的最简单的算法检测球体之间的碰撞,从而得出您的网格。在这里您可以看到实现示例。
最简单的碰撞模型是使用边界框进行碰撞。原理很简单:用一个由最小值和最大值两个点定义的框包围对象。然后,您可以使用这些点来确定两个框是否相交。
在我的引擎中,边界框的结构和碰撞检测方法设置如下:
typedef struct BoundingBox
{
Vector3 min; //Contains lowest corner of the box
Vector3 max; //Contains highest corner of the box
} AABB;
//True if collision is detected, false otherwise
bool detectCollision( BoundingBox a, BoundingBox b )
{
return (a.min <= b.max && b.min <= a.max);
}
其他简单的方法是使用球体。此方法对于在所有维度上都具有相似大小的对象很有用,但如果它们不是,则会产生大量错误碰撞。在这种方法中,你用半径radius
和中心位置围绕你的对象position
,当涉及到碰撞时,你只需检查中心之间的距离是否小于半径之和,如果两个球体相交。
同样,来自我的引擎的代码片段:
struct Sphere
{
Vector3 position; //Center of the sphere
float radius; //Radius of the sphere
};
bool inf::physics::detectCollision( Sphere a, Sphere b )
{
Vector3 tmp = a.position - b.position; //Distance between centers
return (Dot(tmp, tmp) <= pow((a.radius + b.radius), 2));
}
在上面的代码Dot()
中计算两个向量的点积,如果你用它本身做点向量,它会给你(根据定义)向量平方的大小。请注意,我实际上并没有平方根来获得实际距离,而是比较平方以避免额外的计算。
您还应该意识到,这些方法都不是完美的,并且会不时给您错误的碰撞检测(除非对象是完美的盒子或球体),但这是简单实现和计算复杂性的权衡。尽管如此,这是开始检测碰撞的好方法。