简体   繁体   English

libgdx中BoundingBox和Sphere之间的碰撞检测

[英]Collision detection between a BoundingBox and a Sphere in libgdx

In my libgdx game I have 3D BoundingBoxes and Spheres for map and player objects. 在我的libgdx游戏中,我有3D BoundingBoxes和Spheres用于地图和玩家对象。 I want to calculate whether they collide with each other in order to properly simulate the motion of these objects. 我想计算它们是否相互碰撞,以正确模拟这些对象的运动。 What method can I use to calculate whether these objects collide/intersect? 我可以使用什么方法来计算这些对象是否碰撞/相交?

You can use the following method: 您可以使用以下方法:

public static boolean intersectsWith(BoundingBox boundingBox, Sphere sphere) {
    float dmin = 0;

    Vector3 center = sphere.center;
    Vector3 bmin = boundingBox.getMin();
    Vector3 bmax = boundingBox.getMax();

    if (center.x < bmin.x) {
        dmin += Math.pow(center.x - bmin.x, 2);
    } else if (center.x > bmax.x) {
        dmin += Math.pow(center.x - bmax.x, 2);
    }

    if (center.y < bmin.y) {
        dmin += Math.pow(center.y - bmin.y, 2);
    } else if (center.y > bmax.y) {
        dmin += Math.pow(center.y - bmax.y, 2);
    }

    if (center.z < bmin.z) {
        dmin += Math.pow(center.z - bmin.z, 2);
    } else if (center.z > bmax.z) {
        dmin += Math.pow(center.z - bmax.z, 2);
    }

    return dmin <= Math.pow(sphere.radius, 2);
}

It's modeled after 仿照

A Simple Method for Box-Sphere Intersection Testing by Jim Arvo from "Graphics Gems", Academic Press, 1990 盒球相交测试的一种简单方法,Jim Arvo,来自“ Graphics Gems”,学术出版社,1990年

The sample C code for which can be found here: http://www.realtimerendering.com/resources/GraphicsGems/gems/BoxSphere.c 可在以下位置找到其示例C代码: http : //www.realtimerendering.com/resources/GraphicsGems/gems/BoxSphere.c

The above answer is only good for AABB (Axis Aligned Bounding Box). 以上答案仅适用于AABB(轴对齐边界框)。 The method though is concise and beautiful. 该方法虽然简洁美观。 So I have expanded it to include general Bounding Box. 因此,我将其扩展为包括常规边界框。 Bellow is the minimum code that provide the same algorithm as above. 贝娄是提供与上述算法相同的最小代码。 In the code bellow a bounding box is specified by a center and 3 direction vectors R, S, and T. Each represent the direction and length the main edges of the box. 在下面的代码中,边界框由中心和3个方向矢量R,S和T指定。每个方向矢量分别表示框主边缘的方向和长度。

struct OBBox{
    vector3 center; 
    vector3 S; // representing side s.
    vector3 R;
    vector3 T;
     /* s, r, and t take -1 or +1 representing a corner along side S, R, and T correspondingly. If one of s, r, or t is 0 then middle of corresponding edge of the non-zero side is returned. If 2 of them are 0, then middle of the plane of the corresponding side is returned. */
    vector3 getCorner(int s, int r, int t)
    {
        return center + ( s*S + r*R + t*T)/2.0;
    }

}

public static boolean intersectsWith(OBBox bbox, Sphere sphere){
    float dmin = 0.;

    vector3 center = sphere.center;
    float centerS = center.S;
    float centerR = center.R;
    float centerT = center.T;

    vector3 bminS = bbox.getCorner(-1, 0, 0);
    vector3 bmaxS = bbox.getCorner(1, 0, 0);
    vector3 bminR = bbox.getCorner(0, -1, 0);
    vector3 bmaxR = bbox.getCorner(0, 1, 0);
    vector3 bminT = bbox.getCorner(0, 0, -1);
    vector3 bmaxT = bbox.getCorner(0, 0, 1);

    if(centerS < bminS.S) {
        dmin += (centerS-bminS).(centerS-minS); // . means 3d dot product.
    else if(centerS > bmaxS)
        dmin += (centerS-bmaxS).(centerS-bmaxS);
    }

    if(centerR < bminR.R) {
        dmin += (centerR-bminR).(centerR-minR);
    else if(centerR > bmaxR.R)
        dmin += (centerR-bmaxR).(centerR-bmaxR);
    }

    if(centerT < bminT.T) {
        dmin += (centerT-bminT).(centerT-minT);
    else if(centerT > bmaxT)
        dmin += (centerT-bmaxT).(centerT-bmaxT);
    }

    return dmin <= (sphere.radius).(sphere.radius);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM