Algorithm: 1. Classify v1 and v2 2. Classify polygon centroid as front or back 3. Flip normal if necessary 4. Initialize normal range to [-pi, pi] about face normal 5. Adjust normal range according to adjacent edges 6. Visit each separating axes, only accept axes within the range 7. Return if _any_
(manifold *B2Manifold, edgeA *B2EdgeShape, xfA B2Transform, polygonB *B2PolygonShape, xfB B2Transform)
| 216 | // 7. Return if _any_ axis indicates separation |
| 217 | // 8. Clip |
| 218 | func (collider *B2EPCollider) Collide(manifold *B2Manifold, edgeA *B2EdgeShape, xfA B2Transform, polygonB *B2PolygonShape, xfB B2Transform) { |
| 219 | |
| 220 | collider.M_xf = B2TransformMulT(xfA, xfB) |
| 221 | |
| 222 | collider.M_centroidB = B2TransformVec2Mul(collider.M_xf, polygonB.M_centroid) |
| 223 | |
| 224 | collider.M_v0 = edgeA.M_vertex0 |
| 225 | collider.M_v1 = edgeA.M_vertex1 |
| 226 | collider.M_v2 = edgeA.M_vertex2 |
| 227 | collider.M_v3 = edgeA.M_vertex3 |
| 228 | |
| 229 | hasVertex0 := edgeA.M_hasVertex0 |
| 230 | hasVertex3 := edgeA.M_hasVertex3 |
| 231 | |
| 232 | edge1 := B2Vec2Sub(collider.M_v2, collider.M_v1) |
| 233 | edge1.Normalize() |
| 234 | collider.M_normal1.Set(edge1.Y, -edge1.X) |
| 235 | offset1 := B2Vec2Dot(collider.M_normal1, B2Vec2Sub(collider.M_centroidB, collider.M_v1)) |
| 236 | offset0 := 0.0 |
| 237 | offset2 := 0.0 |
| 238 | convex1 := false |
| 239 | convex2 := false |
| 240 | |
| 241 | // Is there a preceding edge? |
| 242 | if hasVertex0 { |
| 243 | edge0 := B2Vec2Sub(collider.M_v1, collider.M_v0) |
| 244 | edge0.Normalize() |
| 245 | collider.M_normal0.Set(edge0.Y, -edge0.X) |
| 246 | convex1 = B2Vec2Cross(edge0, edge1) >= 0.0 |
| 247 | offset0 = B2Vec2Dot(collider.M_normal0, B2Vec2Sub(collider.M_centroidB, collider.M_v0)) |
| 248 | } |
| 249 | |
| 250 | // Is there a following edge? |
| 251 | if hasVertex3 { |
| 252 | edge2 := B2Vec2Sub(collider.M_v3, collider.M_v2) |
| 253 | edge2.Normalize() |
| 254 | collider.M_normal2.Set(edge2.Y, -edge2.X) |
| 255 | convex2 = B2Vec2Cross(edge1, edge2) > 0.0 |
| 256 | offset2 = B2Vec2Dot(collider.M_normal2, B2Vec2Sub(collider.M_centroidB, collider.M_v2)) |
| 257 | } |
| 258 | |
| 259 | // Determine front or back collision. Determine collision normal limits. |
| 260 | if hasVertex0 && hasVertex3 { |
| 261 | if convex1 && convex2 { |
| 262 | collider.M_front = offset0 >= 0.0 || offset1 >= 0.0 || offset2 >= 0.0 |
| 263 | if collider.M_front { |
| 264 | collider.M_normal = collider.M_normal1 |
| 265 | collider.M_lowerLimit = collider.M_normal0 |
| 266 | collider.M_upperLimit = collider.M_normal2 |
| 267 | } else { |
| 268 | collider.M_normal = collider.M_normal1.OperatorNegate() |
| 269 | collider.M_lowerLimit = collider.M_normal1.OperatorNegate() |
| 270 | collider.M_upperLimit = collider.M_normal1.OperatorNegate() |
| 271 | } |
| 272 | } else if convex1 { |
| 273 | collider.M_front = offset0 >= 0.0 || (offset1 >= 0.0 && offset2 >= 0.0) |
| 274 | if collider.M_front { |
| 275 | collider.M_normal = collider.M_normal1 |
no test coverage detected