-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbox_circle_sweep2.go
More file actions
73 lines (61 loc) · 1.68 KB
/
box_circle_sweep2.go
File metadata and controls
73 lines (61 loc) · 1.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package coll
import (
"math"
"github.com/setanarut/v"
)
// BoxCircleSweep2 checks for collision between a moving AABB and a moving Circle.
//
// Returns true if collision occurs during movement, false otherwise.
func BoxCircleSweep2(a *AABB, b *Circle, deltaA, deltaB v.Vec, h *Hit) bool {
relDelta := deltaB.Sub(deltaA)
rad := v.Vec{X: b.Radius, Y: b.Radius}
boxMin := a.Pos.Sub(a.Half).Sub(rad)
boxMax := a.Pos.Add(a.Half).Add(rad)
var tminX, tmaxX, tminY, tmaxY float64
var hitX, hitY bool
if math.Abs(relDelta.X) > 1e-8 {
invX := 1.0 / relDelta.X
t1, t2 := (boxMin.X-b.Pos.X)*invX, (boxMax.X-b.Pos.X)*invX
tminX, tmaxX, hitX = min(t1, t2), max(t1, t2), true
} else if b.Pos.X < boxMin.X || b.Pos.X > boxMax.X {
return false
} else {
tminX, tmaxX = -math.MaxFloat64, math.MaxFloat64
}
if math.Abs(relDelta.Y) > 1e-8 {
invY := 1.0 / relDelta.Y
t3, t4 := (boxMin.Y-b.Pos.Y)*invY, (boxMax.Y-b.Pos.Y)*invY
tminY, tmaxY, hitY = min(t3, t4), max(t3, t4), true
} else if b.Pos.Y < boxMin.Y || b.Pos.Y > boxMax.Y {
return false
} else {
tminY, tmaxY = -math.MaxFloat64, math.MaxFloat64
}
tmin := max(tminX, tminY)
tmax := min(tmaxX, tmaxY)
if tmax < 0 || tmin > tmax || tmin > 1.0 {
return false
}
if tmin < 0 {
hit := BoxCircleOverlap(a, b, h)
if hit && h != nil {
h.Data = 0
}
return hit
}
if h == nil {
return true
}
switch {
case !hitX:
h.Normal = v.Vec{X: 0, Y: math.Copysign(1, -relDelta.Y)}
case !hitY:
h.Normal = v.Vec{X: math.Copysign(1, -relDelta.X), Y: 0}
case tminX > tminY:
h.Normal = v.Vec{X: math.Copysign(1, -relDelta.X), Y: 0}
default:
h.Normal = v.Vec{X: 0, Y: math.Copysign(1, -relDelta.Y)}
}
h.Data = tmin
return true
}