计算三维SAT碰撞法向量时出现java错误
我一直在努力在我的3d游戏引擎中实现SAT碰撞,使用LWJGL跟踪this tutorial进行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之前,这些类就已经存在,我已经多次使用它们)、LWJGL中内置的Vector3f类以及以下类:
投影:
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类只是一个存储两个对象碰撞和对象之间距离的类,它已经在引擎的其他部分中使用,并完全发挥作用
由于某些原因,碰撞无法正确检测,对象会直接通过彼此,我怀疑问题的根源是法向量的计算方式,因为当我运行模拟(引擎)时,我在normal1.normalise();
行处得到了一个IllegalStateException: Zero length vector
异常
有人能帮我找到问题吗
编辑:解决方案:
问题是在函数overlap(Projection projection)
中,返回条件是||
,而不是&&
共 (0) 个答案