@@ -156,37 +156,60 @@ void ManifoldBetweenTwoFaces(Vec3Arg inContactPoint1, Vec3Arg inContactPoint2, V
156156 // Remember size before adding new points, to check at the end if we added some
157157 ContactPoints::size_type old_size = outContactPoints1.size ();
158158
159- // Check if both shapes have polygon faces
160- if (inShape1Face.size () >= 2 // The dynamic shape needs to have at least 2 points or else there can never be more than 1 contact point
161- && inShape2Face.size () >= 3 ) // The dynamic/static shape needs to have at least 3 points (in the case that it has 2 points only if the edges match exactly you can have 2 contact points, but this situation is unstable anyhow)
159+ // Both faces need to have at least 2 points or else there can never be more than 1 contact point
160+ // At least one face needs to have at least 3 points (in the case that it has 2 points only if the edges match exactly you can have 2 contact points, but this situation is unstable anyhow)
161+ if (min (inShape1Face.size (), inShape2Face.size ()) >= 2
162+ && max (inShape1Face.size (), inShape2Face.size ()) >= 3 )
162163 {
163- // Clip the polygon of face 2 against that of 1
164- ConvexShape::SupportingFace clipped_face;
165- if (inShape1Face.size () >= 3 )
166- ClipPolyVsPoly (inShape2Face, inShape1Face, inPenetrationAxis, clipped_face);
167- else if (inShape1Face.size () == 2 )
168- ClipPolyVsEdge (inShape2Face, inShape1Face[0 ], inShape1Face[1 ], inPenetrationAxis, clipped_face);
164+ // Swap the shapes if the 2nd face doesn't have enough vertices
165+ const ConvexShape::SupportingFace *shape1_face, *shape2_face;
166+ ContactPoints *contact_points1, *contact_points2;
167+ Vec3 penetration_axis;
168+ if (inShape2Face.size () >= 3 )
169+ {
170+ shape1_face = &inShape1Face;
171+ shape2_face = &inShape2Face;
172+ contact_points1 = &outContactPoints1;
173+ contact_points2 = &outContactPoints2;
174+ penetration_axis = inPenetrationAxis;
175+ }
176+ else
177+ {
178+ shape1_face = &inShape2Face;
179+ shape2_face = &inShape1Face;
180+ contact_points1 = &outContactPoints2;
181+ contact_points2 = &outContactPoints1;
182+ penetration_axis = -inPenetrationAxis;
183+ }
184+
185+ // Determine plane origin and first edge direction
186+ Vec3 plane_origin = shape1_face->at (0 );
187+ Vec3 first_edge = shape1_face->at (1 ) - plane_origin;
169188
170- // Determine plane origin and normal for shape 1
171- Vec3 plane_origin = inShape1Face[0 ];
172189 Vec3 plane_normal;
173- Vec3 first_edge = inShape1Face[ 1 ] - plane_origin ;
174- if (inShape1Face. size () >= 3 )
190+ ConvexShape::SupportingFace clipped_face ;
191+ if (shape1_face-> size () >= 3 )
175192 {
193+ // Clip the polygon of face 2 against that of 1
194+ ClipPolyVsPoly (*shape2_face, *shape1_face, penetration_axis, clipped_face);
195+
176196 // Three vertices, can just calculate the normal
177- plane_normal = first_edge.Cross (inShape1Face[ 2 ] - plane_origin);
197+ plane_normal = first_edge.Cross (shape1_face-> at ( 2 ) - plane_origin);
178198 }
179199 else
180200 {
201+ // Clip the polygon of face 2 against edge of 1
202+ ClipPolyVsEdge (*shape2_face, shape1_face->at (0 ), shape1_face->at (1 ), penetration_axis, clipped_face);
203+
181204 // Two vertices, first find a perpendicular to the edge and penetration axis and then use the perpendicular together with the edge to form a normal
182- plane_normal = first_edge.Cross (inPenetrationAxis ).Cross (first_edge);
205+ plane_normal = first_edge.Cross (penetration_axis ).Cross (first_edge);
183206 }
184207
185208 // If penetration axis and plane normal are perpendicular, fall back to the contact points
186- float penetration_axis_dot_plane_normal = inPenetrationAxis .Dot (plane_normal);
209+ float penetration_axis_dot_plane_normal = penetration_axis .Dot (plane_normal);
187210 if (penetration_axis_dot_plane_normal != 0 .0f )
188211 {
189- float penetration_axis_len = inPenetrationAxis .Length ();
212+ float penetration_axis_len = penetration_axis .Length ();
190213
191214 for (Vec3 p2 : clipped_face)
192215 {
@@ -200,9 +223,9 @@ void ManifoldBetweenTwoFaces(Vec3Arg inContactPoint1, Vec3Arg inContactPoint2, V
200223 // If the point is less than inMaxContactDistance in front of the plane of face 2, add it as a contact point
201224 if (distance * penetration_axis_len < inMaxContactDistance)
202225 {
203- Vec3 p1 = p2 - distance * inPenetrationAxis ;
204- outContactPoints1. push_back (p1);
205- outContactPoints2. push_back (p2);
226+ Vec3 p1 = p2 - distance * penetration_axis ;
227+ contact_points1-> push_back (p1);
228+ contact_points2-> push_back (p2);
206229 }
207230 }
208231 }
0 commit comments