findSeparatingAxis method
bool
findSeparatingAxis(
- ConvexPolyhedron hullB,
- Vec3 posA,
- Quaternion quatA,
- Vec3 posB,
- Quaternion quatB,
- Vec3 target, [
- List<
int> ? faceListA, - List<
int> ? faceListB,
Find the separating axis between this hull and another @param target The target vector to save the axis in @return Returns false if a separation is found, else true
Implementation
bool findSeparatingAxis(
ConvexPolyhedron hullB,
Vec3 posA,
Quaternion quatA,
Vec3 posB,
Quaternion quatB,
final Vec3 target,[
List<int>? faceListA,
List<int>? faceListB
]) {
final faceANormalWS3 = Vec3();
final worldNormal1 = Vec3();
final deltaC = Vec3();
final worldEdge0 = Vec3();
final worldEdge1 = Vec3();
final cross = Vec3();
double dmin = double.infinity;
final hullA = this;
//int curPlaneTests = 0;
if (hullA.uniqueAxes != null) {
final numFacesA = faceListA != null? faceListA.length : hullA.faces.length;
// Test face normals from hullA
for (int i = 0; i < numFacesA; i++) {
final fi = faceListA != null? faceListA[i] : i;
// Get world face normal
faceANormalWS3.copy(hullA.faceNormals[fi]!);
quatA.vmult(faceANormalWS3, faceANormalWS3);
final d = hullA.testSepAxis(faceANormalWS3, hullB, posA, quatA, posB, quatB);
if (d == null) {
return false;
}
if (d < dmin) {
dmin = d;
target.copy(faceANormalWS3);
}
}
} else if(hullA.uniqueAxes != null){
// Test unique axes
for (int i = 0; i != hullA.uniqueAxes!.length; i++) {
// Get world axis
quatA.vmult(hullA.uniqueAxes![i], faceANormalWS3);
final d = hullA.testSepAxis(faceANormalWS3, hullB, posA, quatA, posB, quatB);
if (d == null) {
return false;
}
if (d < dmin) {
dmin = d;
target.copy(faceANormalWS3);
}
}
}
if (hullB.uniqueAxes != null) {
// Test face normals from hullB
final numFacesB = faceListB != null ? faceListB.length : hullB.faces.length;
for (int i = 0; i < numFacesB; i++) {
final fi = faceListB != null? faceListB[i] : i;
worldNormal1.copy(hullB.faceNormals[fi]!);
quatB.vmult(worldNormal1, worldNormal1);
//curPlaneTests++;
final d = hullA.testSepAxis(worldNormal1, hullB, posA, quatA, posB, quatB);
if (d == null) {
return false;
}
if (d < dmin) {
dmin = d;
target.copy(worldNormal1);
}
}
} else {
// Test unique axes in B
final int len = hullB.uniqueAxes?.length ?? 0;
for (int i = 0; i != len; i++) {
quatB.vmult(hullB.uniqueAxes![i], worldNormal1);
//curPlaneTests++;
final d = hullA.testSepAxis(worldNormal1, hullB, posA, quatA, posB, quatB);
if (d == null) {
return false;
}
if (d < dmin) {
dmin = d;
target.copy(worldNormal1);
}
}
}
// Test edges
for (int e0 = 0; e0 != hullA.uniqueEdges.length; e0++) {
// Get world edge
quatA.vmult(hullA.uniqueEdges[e0], worldEdge0);
for (int e1 = 0; e1 != hullB.uniqueEdges.length; e1++) {
// Get world edge 2
quatB.vmult(hullB.uniqueEdges[e1], worldEdge1);
worldEdge0.cross(worldEdge1, cross);
if (!cross.almostZero()) {
cross.normalize();
final dist = hullA.testSepAxis(cross, hullB, posA, quatA, posB, quatB);
if (dist == null) {
return false;
}
if (dist < dmin) {
dmin = dist;
target.copy(cross);
}
}
}
}
posB.vsub(posA, deltaC);
if (deltaC.dot(target) > 0.0) {
target.negate(target);
}
return true;
}