在3d

时间:2018-07-27 12:52:03

标签: java math vector collision-detection lwjgl

我一直在研究this tutorial之后使用LWJGL在3d游戏引擎中实现SAT碰撞的2d SAT碰撞。
由于本教程是针对2d的,并且我正在尝试进行3d碰撞,因此我需要对代码进行一些更改以适合我的需要,但未能成功完成。

这是SAT课程:

public class SAT {

public static IntersectionData collision(Box box1, Box box2){

    float overlap = Float.MAX_VALUE;
    Vector3f smallest = null;

    Vector3f[] box1Vertices = box1.getExtents();
    Vector3f[] box2Vertices = box2.getExtents();
    Vector3f[] box1Axes = getAxes(box1Vertices);
    Vector3f[] box2Axes = getAxes(box2Vertices);

    for (Vector3f axis:box1Axes){
        Projection p1 = Projection.project(box1Vertices, axis);
        Projection p2 = Projection.project(box2Vertices, axis);
        if (!p1.overlap(p2))
            return new IntersectionData(false, p1.getDistance(p2));
        else {
            float o = p1.getOverlap(p2);
            if (o < overlap){
                overlap = o;
                smallest = axis;
            }
        }
    }

    for (Vector3f axis:box2Axes){
        Projection p1 = Projection.project(box1Vertices, axis);
        Projection p2 = Projection.project(box2Vertices, axis);
        if (!p1.overlap(p2))
            return new IntersectionData(false, p1.getDistance(p2));
        else {
            float o = p1.getOverlap(p2);
            if (o < overlap){
                overlap = o;
                smallest = axis;
            }
        }
    }
    MTV mtv = new MTV(smallest, overlap);

    return new IntersectionData(true, mtv.getOverlap());
}

private static Vector3f[] getAxes(Vector3f[] vertices){ // FIXME
    Vector3f[] axes = new Vector3f[vertices.length];
    for (int i = 0; i < vertices.length; i++){
        Vector3f p1 = vertices[i];
        Vector3f p2 = vertices[i + 1 == vertices.length ? 0 : i + 1];
        Vector3f p3 = vertices[i + 2 >= vertices.length ? 1 : i + 1];
        Vector3f edge1 = Vector3f.sub(p2, p1, null);
        Vector3f edge2 = Vector3f.sub(p3, p1, null);
        Vector3f normal1 = Vector3f.cross(edge1, edge2, null);
        normal1.normalise();
        axes[i] = normal1;
    }
    return axes;
}
}

它可以在我创建的其他类中使用,我可以向您保证可以完美地工作(在我开始实施SAT之前就已经在那里,并且已经使用了几次),Vector3f类是在LWJGL和在以下课程中:

投影:

class Projection {

private float min;
private float max;

private Projection(float min, float max) {
    this.min = min;
    this.max = max;
}

float getOverlap(Projection projection){
    if (overlap(projection))
        return Math.min(max, projection.max) - Math.max(min, projection.min);
    return 0;
}

float getDistance(Projection projection){
    if (overlap(projection))
        return getOverlap(projection);
    else
        return Math.max(min, projection.min) - Math.max(max, projection.max);
}

boolean overlap(Projection projection){
    return max > projection.min || projection.max > min;
}

static Projection project(Vector3f[] vertices, Vector3f axis){
    float min = Vector3f.dot(axis, vertices[0]);
    float max = min;

    for (Vector3f vertex:vertices){
        float p = Vector3f.dot(axis, vertex);
        if (p < min)
            min = p;
        else if (p > max)
            max = p;
    }

    return new Projection(min, max);
}
}

MTV:

class MTV {
private Vector3f axis;
private float overlap;

MTV(Vector3f axis, float overlap) {
    this.axis = axis;
    this.overlap = overlap;
}

public Vector3f getAxis() {
    return axis;
}

float getOverlap() {
    return overlap;
}
}

注意:IntersectionData类只是一个用于存储两个对象是否碰撞以及到对象之间的距离的类,该类已经在引擎的其他部分使用,并且可以正常运行。 < / p>


由于某种原因,碰撞将无法正确检测,并且物体彼此正确通过,我怀疑问题的根源是法向矢量的计算方式,因为当我运行模拟(引擎)时,我在行IllegalStateException: Zero length vector处获得normal1.normalise();异常。

有人可以帮我找到问题吗?

编辑:解决方案: 问题在于,在函数overlap(Projection projection)中,返回条件是||而不是&&

0 个答案:

没有答案