in case heuristic overlapping test fails fallback to common overlapping test; create edge contact if hull is not simplified

This commit is contained in:
Irlan 2018-05-03 21:45:00 -03:00
parent f6ba27cbf3
commit 10c01c8fcf
2 changed files with 104 additions and 18 deletions

View File

@ -210,6 +210,8 @@ void b3CollideHulls(b3Manifold& manifold,
const b3Transform& xf1, const b3HullShape* s1,
const b3Transform& xf2, const b3HullShape* s2)
{
B3_ASSERT(manifold.pointCount == 0);
const b3Hull* hull1 = s1->m_hull;
float32 r1 = s1->m_radius;
@ -236,7 +238,7 @@ void b3CollideHulls(b3Manifold& manifold,
return;
}
const float32 kTol = 0.05f * B3_LINEAR_SLOP;
const float32 kTol = 0.1f * B3_LINEAR_SLOP;
if (edgeQuery.separation > b3Max(faceQuery1.separation, faceQuery2.separation) + kTol)
{
b3BuildEdgeContact(manifold, xf1, edgeQuery.index1, s1, xf2, edgeQuery.index2, s2);
@ -252,6 +254,41 @@ void b3CollideHulls(b3Manifold& manifold,
b3BuildFaceContact(manifold, xf2, faceQuery2.index, s2, xf1, s1, true);
}
}
// Heuristic succeded.
if (manifold.pointCount > 0)
{
return;
}
// Heuristic failed. Fallback.
if (edgeQuery.separation > b3Max(faceQuery1.separation, faceQuery2.separation))
{
b3BuildEdgeContact(manifold, xf1, edgeQuery.index1, s1, xf2, edgeQuery.index2, s2);
}
else
{
if (faceQuery1.separation > faceQuery2.separation)
{
b3BuildFaceContact(manifold, xf1, faceQuery1.index, s1, xf2, s2, false);
}
else
{
b3BuildFaceContact(manifold, xf2, faceQuery2.index, s2, xf1, s1, true);
}
}
// When both convex hulls are not simplified clipping might fail and create no contact points.
// For example, when a hull contains tiny faces, coplanar faces, and/or non-sharped edges.
// So we simply create a contact point between the segments.
// The hulls might overlap, but is better than solving no contact points.
if (manifold.pointCount == 0)
{
b3BuildEdgeContact(manifold, xf1, edgeQuery.index1, s1, xf2, edgeQuery.index2, s2);
}
// If the shapes are overlapping then at least on point must be created.
B3_ASSERT(manifold.pointCount > 0);
}
bool b3_convexCache = true;

View File

@ -192,8 +192,7 @@ void b3CollideCache(b3Manifold& manifold,
return;
}
const float32 kTol = 0.05f * B3_LINEAR_SLOP;
const float32 kTol = 0.1f * B3_LINEAR_SLOP;
if (edgeQuery.separation > b3Max(faceQuery1.separation, faceQuery2.separation) + kTol)
{
b3BuildEdgeContact(manifold, xf1, edgeQuery.index1, s1, xf2, edgeQuery.index2, s2);
@ -201,6 +200,7 @@ void b3CollideCache(b3Manifold& manifold,
{
// Write an overlap cache.
cache->m_featurePair = b3MakeFeaturePair(b3SATCacheType::e_overlap, b3SATFeatureType::e_edge1, edgeQuery.index1, edgeQuery.index2);
return;
}
}
else
@ -212,6 +212,7 @@ void b3CollideCache(b3Manifold& manifold,
{
// Write an overlap cache.
cache->m_featurePair = b3MakeFeaturePair(b3SATCacheType::e_overlap, b3SATFeatureType::e_face1, faceQuery1.index, faceQuery1.index);
return;
}
}
else
@ -221,9 +222,57 @@ void b3CollideCache(b3Manifold& manifold,
{
// Write an overlap cache.
cache->m_featurePair = b3MakeFeaturePair(b3SATCacheType::e_overlap, b3SATFeatureType::e_face2, faceQuery2.index, faceQuery2.index);
return;
}
}
}
// Heuristic failed. Fallback.
if (edgeQuery.separation > b3Max(faceQuery1.separation, faceQuery2.separation))
{
b3BuildEdgeContact(manifold, xf1, edgeQuery.index1, s1, xf2, edgeQuery.index2, s2);
if (manifold.pointCount > 0)
{
// Write an overlap cache.
cache->m_featurePair = b3MakeFeaturePair(b3SATCacheType::e_overlap, b3SATFeatureType::e_edge1, edgeQuery.index1, edgeQuery.index2);
return;
}
}
else
{
if (faceQuery1.separation > faceQuery2.separation)
{
b3BuildFaceContact(manifold, xf1, faceQuery1.index, s1, xf2, s2, false);
if (manifold.pointCount > 0)
{
// Write an overlap cache.
cache->m_featurePair = b3MakeFeaturePair(b3SATCacheType::e_overlap, b3SATFeatureType::e_face1, faceQuery1.index, faceQuery1.index);
return;
}
}
else
{
b3BuildFaceContact(manifold, xf2, faceQuery2.index, s2, xf1, s1, true);
if (manifold.pointCount > 0)
{
// Write an overlap cache.
cache->m_featurePair = b3MakeFeaturePair(b3SATCacheType::e_overlap, b3SATFeatureType::e_face2, faceQuery2.index, faceQuery2.index);
return;
}
}
}
// When both convex hulls are not simplified clipping might fail and create no contact points.
// For example, when a hull contains tiny faces, coplanar faces, and/or non-sharped edges.
// So we simply create a contact point between the segments.
// The hulls might overlap, but is better than solving no contact points.
b3BuildEdgeContact(manifold, xf1, edgeQuery.index1, s1, xf2, edgeQuery.index2, s2);
// If the shapes are overlapping then at least on point must be created.
B3_ASSERT(manifold.pointCount > 0);
// Write an overlap cache.
cache->m_featurePair = b3MakeFeaturePair(b3SATCacheType::e_overlap, b3SATFeatureType::e_edge1, edgeQuery.index1, edgeQuery.index2);
}
extern u32 b3_convexCacheHits;