Java 计算三维SAT碰撞法向量时出错

Java 计算三维SAT碰撞法向量时出错,java,math,vector,collision-detection,lwjgl,Java,Math,Vector,Collision Detection,Lwjgl,我一直在致力于在我的3d游戏引擎中实现SAT碰撞,使用LWJGL跟踪2d SAT碰撞。 由于本教程是针对2d的,我正在尝试进行3d碰撞,因此我需要稍微更改代码以满足我的需要,但未能成功完成。 这是SAT课程: public class SAT { public static IntersectionData collision(Box box1, Box box2){ float overlap = Float.MAX_VALUE; Vector3f smallest =

我一直在致力于在我的3d游戏引擎中实现SAT碰撞,使用LWJGL跟踪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;
}
}
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);
}
}
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只是一个存储两个对象发生碰撞以及到对象之间的距离的类,它已在引擎的其他部分中使用,并完全发挥作用。


由于某些原因,碰撞无法正确检测,并且对象会直接通过彼此,我怀疑问题的根源在于法向量的计算方式,因为当我运行模拟(引擎)时,我在
normal1.normalise()行上得到了
IllegalStateException:Zero length vector
异常

有人能帮我找到问题吗

编辑:解决方案:
问题是,在函数
重叠(投影)
中,返回条件是使用
|
而不是
&

这看起来有点可疑,特别是最后一行中的
i+1
Java Vector3f p1=顶点[i];向量3f p2=顶点[i+1==顶点.length?0:i+1];向量3f p3=顶点[i+2>=顶点。长度?1:i+1]我将其简化并更改为:
javavector3fp1=顶点[I];向量3f p2=顶点[(i+1)%vertexts.length];向量3f p3=顶点[(i+2)%vertexts.length]@httpdigest你好!谢谢你的回答!无论如何,这确实解决了异常,并且不再发生。但是碰撞仍然没有被发现。。。你知道为什么吗?再次感谢你。