(output *B2RayCastOutput, input B2RayCastInput, xf B2Transform, childIndex int)
| 273 | } |
| 274 | |
| 275 | func (poly B2PolygonShape) RayCast(output *B2RayCastOutput, input B2RayCastInput, xf B2Transform, childIndex int) bool { |
| 276 | |
| 277 | // Put the ray into the polygon's frame of reference. |
| 278 | p1 := B2RotVec2MulT(xf.Q, B2Vec2Sub(input.P1, xf.P)) |
| 279 | p2 := B2RotVec2MulT(xf.Q, B2Vec2Sub(input.P2, xf.P)) |
| 280 | d := B2Vec2Sub(p2, p1) |
| 281 | |
| 282 | lower := 0.0 |
| 283 | upper := input.MaxFraction |
| 284 | |
| 285 | index := -1 |
| 286 | |
| 287 | for i := 0; i < poly.M_count; i++ { |
| 288 | // p = p1 + a * d |
| 289 | // dot(normal, p - v) = 0 |
| 290 | // dot(normal, p1 - v) + a * dot(normal, d) = 0 |
| 291 | numerator := B2Vec2Dot(poly.M_normals[i], B2Vec2Sub(poly.M_vertices[i], p1)) |
| 292 | denominator := B2Vec2Dot(poly.M_normals[i], d) |
| 293 | |
| 294 | if denominator == 0.0 { |
| 295 | if numerator < 0.0 { |
| 296 | return false |
| 297 | } |
| 298 | } else { |
| 299 | // Note: we want this predicate without division: |
| 300 | // lower < numerator / denominator, where denominator < 0 |
| 301 | // Since denominator < 0, we have to flip the inequality: |
| 302 | // lower < numerator / denominator <==> denominator * lower > numerator. |
| 303 | if denominator < 0.0 && numerator < lower*denominator { |
| 304 | // Increase lower. |
| 305 | // The segment enters this half-space. |
| 306 | lower = numerator / denominator |
| 307 | index = i |
| 308 | } else if denominator > 0.0 && numerator < upper*denominator { |
| 309 | // Decrease upper. |
| 310 | // The segment exits this half-space. |
| 311 | upper = numerator / denominator |
| 312 | } |
| 313 | } |
| 314 | |
| 315 | // The use of epsilon here causes the assert on lower to trip |
| 316 | // in some cases. Apparently the use of epsilon was to make edge |
| 317 | // shapes work, but now those are handled separately. |
| 318 | //if (upper < lower - b2_epsilon) |
| 319 | if upper < lower { |
| 320 | return false |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | B2Assert(0.0 <= lower && lower <= input.MaxFraction) |
| 325 | |
| 326 | if index >= 0 { |
| 327 | output.Fraction = lower |
| 328 | output.Normal = B2RotVec2Mul(xf.Q, poly.M_normals[index]) |
| 329 | return true |
| 330 | } |
| 331 | |
| 332 | return false |
nothing calls this directly
no test coverage detected