我目前正在研究一个小物理引擎,但我遇到了“Sphere To Polygon”碰撞处理的一个小问题。
如您所见,球体只是漂浮在多边形的边缘。 它只是靠近边缘!如果我将球体再移动一点,它就会按原样下降,我真的不明白为什么会这样。这是我的代码,希望你能帮忙(我使用的是分离轴定理):
public static bool SphereToPolygon(Vector3 centerA, float radiusA, Vector3[] verts, short[] inds, Vector3 centerB, out Vector3 normal, out float depth, out Vector3 contactPoint, out int contacts) {
normal = Vector3.Zero;
contactPoint = Vector3.Zero;
depth = float.MaxValue;
contacts = 0;
float minA, maxA, minB, maxB;
for (int i = 0; i < inds.Length; i += 3) {
Vector3 vA = verts[inds[i]];
Vector3 vB = verts[inds[i + 1]];
Vector3 vC = verts[inds[i + 2]];
Vector3 axis = Vector3.Cross(vA - vB, vC - vB);
axis.Normalize();
Solver.ProjectVertices(verts, axis, out minB, out maxB);
Solver.ProjectSphere(centerA, radiusA, axis, out minA, out maxA);
if (maxB < minA|| maxA < minB) {
return false;
}
float overLap = MathF.Min(maxB, maxA) - MathF.Max(minB, minA);
if (overLap < depth) {
depth = overLap;
normal = axis;
contactPoint = centerA - radiusA * axis;
contacts = 1;
}
}
Vector3 direction = centerB - centerA;
if (Vector3.Dot(normal, direction) < 0) {
normal = -normal;
}
return true;
}
这里是我投影顶点和球体的方式:
private static void ProjectVertices(Vector3[] verts, Vector3 axis, out float min, out float max) {
min = float.MaxValue;
max = float.MinValue;
for(int i = 0; i < verts.Length; i++) {
float projectedPoint = Vector3.Dot(verts[i], axis);
if(projectedPoint < min) { min = projectedPoint; }
if(projectedPoint > max) { max = projectedPoint; }
}
}
private static void ProjectSphere(Vector3 center, float radius, Vector3 axis, out float min, out float max) {
min = Vector3.Dot(center, axis) - radius;
max = Vector3.Dot(center, axis) + radius;
if (min > max) {
float t = min;
min = max;
max = t;
}
}
我为多边形提供的顶点只是可以在任何方向缩放的立方体的顶点。