in case heuristic overlapping test fails fallback to common overlapping test; create edge contact if hull is not simplified
This commit is contained in:
parent
f6ba27cbf3
commit
10c01c8fcf
@ -210,6 +210,8 @@ void b3CollideHulls(b3Manifold& manifold,
|
|||||||
const b3Transform& xf1, const b3HullShape* s1,
|
const b3Transform& xf1, const b3HullShape* s1,
|
||||||
const b3Transform& xf2, const b3HullShape* s2)
|
const b3Transform& xf2, const b3HullShape* s2)
|
||||||
{
|
{
|
||||||
|
B3_ASSERT(manifold.pointCount == 0);
|
||||||
|
|
||||||
const b3Hull* hull1 = s1->m_hull;
|
const b3Hull* hull1 = s1->m_hull;
|
||||||
float32 r1 = s1->m_radius;
|
float32 r1 = s1->m_radius;
|
||||||
|
|
||||||
@ -236,7 +238,7 @@ void b3CollideHulls(b3Manifold& manifold,
|
|||||||
return;
|
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)
|
if (edgeQuery.separation > b3Max(faceQuery1.separation, faceQuery2.separation) + kTol)
|
||||||
{
|
{
|
||||||
b3BuildEdgeContact(manifold, xf1, edgeQuery.index1, s1, xf2, edgeQuery.index2, s2);
|
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);
|
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;
|
bool b3_convexCache = true;
|
||||||
|
@ -192,8 +192,7 @@ void b3CollideCache(b3Manifold& manifold,
|
|||||||
return;
|
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)
|
if (edgeQuery.separation > b3Max(faceQuery1.separation, faceQuery2.separation) + kTol)
|
||||||
{
|
{
|
||||||
b3BuildEdgeContact(manifold, xf1, edgeQuery.index1, s1, xf2, edgeQuery.index2, s2);
|
b3BuildEdgeContact(manifold, xf1, edgeQuery.index1, s1, xf2, edgeQuery.index2, s2);
|
||||||
@ -201,6 +200,7 @@ void b3CollideCache(b3Manifold& manifold,
|
|||||||
{
|
{
|
||||||
// Write an overlap cache.
|
// Write an overlap cache.
|
||||||
cache->m_featurePair = b3MakeFeaturePair(b3SATCacheType::e_overlap, b3SATFeatureType::e_edge1, edgeQuery.index1, edgeQuery.index2);
|
cache->m_featurePair = b3MakeFeaturePair(b3SATCacheType::e_overlap, b3SATFeatureType::e_edge1, edgeQuery.index1, edgeQuery.index2);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -212,6 +212,7 @@ void b3CollideCache(b3Manifold& manifold,
|
|||||||
{
|
{
|
||||||
// Write an overlap cache.
|
// Write an overlap cache.
|
||||||
cache->m_featurePair = b3MakeFeaturePair(b3SATCacheType::e_overlap, b3SATFeatureType::e_face1, faceQuery1.index, faceQuery1.index);
|
cache->m_featurePair = b3MakeFeaturePair(b3SATCacheType::e_overlap, b3SATFeatureType::e_face1, faceQuery1.index, faceQuery1.index);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -221,9 +222,57 @@ void b3CollideCache(b3Manifold& manifold,
|
|||||||
{
|
{
|
||||||
// Write an overlap cache.
|
// Write an overlap cache.
|
||||||
cache->m_featurePair = b3MakeFeaturePair(b3SATCacheType::e_overlap, b3SATFeatureType::e_face2, faceQuery2.index, faceQuery2.index);
|
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;
|
extern u32 b3_convexCacheHits;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user