-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbox_orientedbox_sweep2.go
More file actions
64 lines (54 loc) · 1.66 KB
/
box_orientedbox_sweep2.go
File metadata and controls
64 lines (54 loc) · 1.66 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
package coll
import (
"math"
"github.com/setanarut/v"
)
// BoxOrientedBoxSweep2 tests if a moving AABB and moving OBB intersect during their motion.
// Uses swept volume testing to prevent tunneling for fast-moving objects.
func BoxOrientedBoxSweep2(a *AABB, o *OBB, deltaA v.Vec, deltaO v.Vec) bool {
relVx := deltaO.X - deltaA.X
relVy := deltaO.Y - deltaA.Y
tx := o.Pos.X - a.Pos.X
ty := o.Pos.Y - a.Pos.Y
bAx := v.FromAngle(o.Angle)
bAy := v.Vec{X: -bAx.Y, Y: bAx.X}
absAx := bAx.Abs()
absAy := bAy.Abs()
projB_on_GlobalX := (absAx.X * o.Half.X) + (absAy.X * o.Half.Y)
limitX := a.Half.X + projB_on_GlobalX
if (tx > 0 && relVx < 0) || (tx < 0 && relVx > 0) {
limitX += math.Abs(relVx)
}
if math.Abs(tx) > limitX {
return false
}
projB_on_GlobalY := (absAx.Y * o.Half.X) + (absAy.Y * o.Half.Y)
limitY := a.Half.Y + projB_on_GlobalY
if (ty > 0 && relVy < 0) || (ty < 0 && relVy > 0) {
limitY += math.Abs(relVy)
}
if math.Abs(ty) > limitY {
return false
}
dotT_Ax := (tx * bAx.X) + (ty * bAx.Y)
projA_on_ObbX := (absAx.X * a.Half.X) + (absAx.Y * a.Half.Y)
dotV_Ax := (relVx * bAx.X) + (relVy * bAx.Y)
limitObbX := o.Half.X + projA_on_ObbX
if (dotT_Ax > 0 && dotV_Ax < 0) || (dotT_Ax < 0 && dotV_Ax > 0) {
limitObbX += math.Abs(dotV_Ax)
}
if math.Abs(dotT_Ax) > limitObbX {
return false
}
dotT_Ay := (tx * bAy.X) + (ty * bAy.Y)
projA_on_ObbY := (absAy.X * a.Half.X) + (absAy.Y * a.Half.Y)
dotV_Ay := (relVx * bAy.X) + (relVy * bAy.Y)
limitObbY := o.Half.Y + projA_on_ObbY
if (dotT_Ay > 0 && dotV_Ay < 0) || (dotT_Ay < 0 && dotV_Ay > 0) {
limitObbY += math.Abs(dotV_Ay)
}
if math.Abs(dotT_Ay) > limitObbY {
return false
}
return true
}