From Real-time Collision Detection, p179.
(output *B2RayCastOutput, input B2RayCastInput)
| 384 | |
| 385 | // From Real-time Collision Detection, p179. |
| 386 | func (bb B2AABB) RayCast(output *B2RayCastOutput, input B2RayCastInput) bool { |
| 387 | tmin := -B2_maxFloat |
| 388 | tmax := B2_maxFloat |
| 389 | |
| 390 | p := input.P1 |
| 391 | d := B2Vec2Sub(input.P2, input.P1) |
| 392 | absD := B2Vec2Abs(d) |
| 393 | |
| 394 | normal := MakeB2Vec2(0, 0) |
| 395 | |
| 396 | for i := 0; i < 2; i++ { |
| 397 | if absD.OperatorIndexGet(i) < B2_epsilon { |
| 398 | // Parallel. |
| 399 | if p.OperatorIndexGet(i) < bb.LowerBound.OperatorIndexGet(i) || bb.UpperBound.OperatorIndexGet(i) < p.OperatorIndexGet(i) { |
| 400 | return false |
| 401 | } |
| 402 | } else { |
| 403 | inv_d := 1.0 / d.OperatorIndexGet(i) |
| 404 | t1 := (bb.LowerBound.OperatorIndexGet(i) - p.OperatorIndexGet(i)) * inv_d |
| 405 | t2 := (bb.UpperBound.OperatorIndexGet(i) - p.OperatorIndexGet(i)) * inv_d |
| 406 | |
| 407 | // Sign of the normal vector. |
| 408 | s := -1.0 |
| 409 | |
| 410 | if t1 > t2 { |
| 411 | t1, t2 = t2, t1 |
| 412 | s = 1.0 |
| 413 | } |
| 414 | |
| 415 | // Push the min up |
| 416 | if t1 > tmin { |
| 417 | normal.SetZero() |
| 418 | normal.OperatorIndexSet(i, s) |
| 419 | tmin = t1 |
| 420 | } |
| 421 | |
| 422 | // Pull the max down |
| 423 | tmax = math.Min(tmax, t2) |
| 424 | |
| 425 | if tmin > tmax { |
| 426 | return false |
| 427 | } |
| 428 | } |
| 429 | } |
| 430 | |
| 431 | // Does the ray start inside the box? |
| 432 | // Does the ray intersect beyond the max fraction? |
| 433 | if tmin < 0.0 || input.MaxFraction < tmin { |
| 434 | return false |
| 435 | } |
| 436 | |
| 437 | // Intersection. |
| 438 | output.Fraction = tmin |
| 439 | output.Normal = normal |
| 440 | return true |
| 441 | } |
| 442 | |
| 443 | // Sutherland-Hodgman clipping. |
nothing calls this directly
no test coverage detected