Skip to content

Commit f31db34

Browse files
committed
refactoring
1 parent 21cabca commit f31db34

File tree

21 files changed

+219
-211
lines changed

21 files changed

+219
-211
lines changed

box_box_sweep1.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import "github.com/setanarut/v"
44

55
// BoxBoxSweep1 Returns true if collision occurs during movement.
66
// Fills hit info h for dynamicB if not nil.
7-
func BoxBoxSweep1(staticA, dynamicB *AABB, velB v.Vec, h *Hit) bool {
8-
if velB.IsZero() {
7+
func BoxBoxSweep1(staticA, dynamicB *AABB, deltaB v.Vec, h *Hit) bool {
8+
if deltaB.IsZero() {
99
return BoxBoxOverlap(staticA, dynamicB, h)
1010
}
11-
result := BoxSegmentOverlap(staticA, dynamicB.Pos, velB, dynamicB.Half, h)
11+
result := BoxSegmentOverlap(staticA, dynamicB.Pos, deltaB, dynamicB.Half, h)
1212
if result && h != nil {
1313
h.Data = max(0, min(1, h.Data-Epsilon))
1414
}

box_box_sweep2.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package coll
33
import "github.com/setanarut/v"
44

55
// BoxBoxSweep2 Returns true if collision occurs during movement. Fills hit info h for b if not nil.
6-
func BoxBoxSweep2(a, b *AABB, velA, velB v.Vec, h *Hit) bool {
7-
delta := velB.Sub(velA)
6+
func BoxBoxSweep2(a, b *AABB, deltaA, deltaB v.Vec, h *Hit) bool {
7+
delta := deltaB.Sub(deltaA)
88
return BoxBoxSweep1(a, b, delta, h)
99
}

box_circle_overlap.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,19 @@ import (
1212
// - Normal: the surface normal of box
1313
// - Data: penetration depth (distance to move the box)
1414
//
15-
// To resolve the overlap: newBoxPos = box.Pos.Add(hit.Normal.Neg().Scale(hit.Data))
16-
func BoxCircleOverlap(box *AABB, circle *Circle, h *Hit) bool {
15+
// To resolve the overlap:
16+
//
17+
// newBoxPos = box.Pos.Add(hit.Normal.Neg().Scale(hit.Data))
18+
func BoxCircleOverlap(a *AABB, c *Circle, h *Hit) bool {
1719

1820
// intersection test
19-
diff := circle.Pos.Sub(box.Pos)
21+
diff := c.Pos.Sub(a.Pos)
2022
clamped := v.Vec{
21-
X: max(-box.Half.X, min(diff.X, box.Half.X)),
22-
Y: max(-box.Half.Y, min(diff.Y, box.Half.Y)),
23+
X: max(-a.Half.X, min(diff.X, a.Half.X)),
24+
Y: max(-a.Half.Y, min(diff.Y, a.Half.Y)),
2325
}
24-
closest := box.Pos.Add(clamped)
25-
if !(circle.Pos.DistSq(closest) <= circle.Radius*circle.Radius) {
26+
closest := a.Pos.Add(clamped)
27+
if !(c.Pos.DistSq(closest) <= c.Radius*c.Radius) {
2628
return false
2729
}
2830

@@ -42,25 +44,25 @@ func BoxCircleOverlap(box *AABB, circle *Circle, h *Hit) bool {
4244
h.Normal = normal.DivS(dist) // Box pushed away from circle
4345

4446
// Penetration depth (how far to move)
45-
penetration := circle.Radius - dist
47+
penetration := c.Radius - dist
4648
h.Data = penetration
4749

4850
} else {
4951
// Box center is inside circle - push along shortest axis
5052
absD := diff.Abs()
51-
px := box.Half.X - absD.X
52-
py := box.Half.Y - absD.Y
53+
px := a.Half.X - absD.X
54+
py := a.Half.Y - absD.Y
5355

5456
if px < py {
5557
// Push horizontally
5658
sx := math.Copysign(1, diff.X)
57-
pushDistance := px + circle.Radius
59+
pushDistance := px + c.Radius
5860
h.Normal = v.Vec{X: sx, Y: 0} // Box pushed away from circle
5961
h.Data = pushDistance
6062
} else {
6163
// Push vertically
6264
sy := math.Copysign(1, diff.Y)
63-
pushDistance := py + circle.Radius
65+
pushDistance := py + c.Radius
6466
h.Normal = v.Vec{X: 0, Y: sy} // Box pushed away from circle
6567
h.Data = pushDistance
6668
}

box_circle_sweep2.go

Lines changed: 43 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,24 @@ import (
99
// BoxCircleSweep2 checks for collision between a moving AABB and a moving Circle.
1010
//
1111
// Returns true if collision occurs during movement, false otherwise.
12-
func BoxCircleSweep2(box *AABB, circle *Circle, boxVel, circleVel v.Vec, h *Hit) bool {
13-
// Relative velocity (circle relative to box)
14-
relVelX := circleVel.X - boxVel.X
15-
relVelY := circleVel.Y - boxVel.Y
12+
func BoxCircleSweep2(a *AABB, b *Circle, deltaA, deltaB v.Vec, h *Hit) bool {
13+
relDeltaX := deltaB.X - deltaA.X
14+
relDeltaY := deltaB.Y - deltaA.Y
1615

1716
// If no relative movement, check overlap directly
18-
relVelMagSq := relVelX*relVelX + relVelY*relVelY
19-
if relVelMagSq < 1e-8 {
17+
relDeltaMagSq := relDeltaX*relDeltaX + relDeltaY*relDeltaY
18+
if relDeltaMagSq < 1e-8 {
2019
// Find closest point on AABB to circle center
21-
closestX := math.Max(box.Pos.X-box.Half.X, math.Min(circle.Pos.X, box.Pos.X+box.Half.X))
22-
closestY := math.Max(box.Pos.Y-box.Half.Y, math.Min(circle.Pos.Y, box.Pos.Y+box.Half.Y))
20+
closestX := math.Max(a.Pos.X-a.Half.X, math.Min(b.Pos.X, a.Pos.X+a.Half.X))
21+
closestY := math.Max(a.Pos.Y-a.Half.Y, math.Min(b.Pos.Y, a.Pos.Y+a.Half.Y))
2322

2423
// Vector from closest point to circle center
25-
distX := circle.Pos.X - closestX
26-
distY := circle.Pos.Y - closestY
24+
distX := b.Pos.X - closestX
25+
distY := b.Pos.Y - closestY
2726
distSq := distX*distX + distY*distY
2827

2928
// Check if overlapping
30-
if distSq >= circle.Radius*circle.Radius {
29+
if distSq >= b.Radius*b.Radius {
3130
return false
3231
}
3332

@@ -37,10 +36,10 @@ func BoxCircleSweep2(box *AABB, circle *Circle, boxVel, circleVel v.Vec, h *Hit)
3736
// If circle center is inside box
3837
if distSq < 1e-8 {
3938
// Calculate penetration depths for each side
40-
leftDist := (circle.Pos.X - (box.Pos.X - box.Half.X)) + circle.Radius
41-
rightDist := ((box.Pos.X + box.Half.X) - circle.Pos.X) + circle.Radius
42-
topDist := (circle.Pos.Y - (box.Pos.Y - box.Half.Y)) + circle.Radius
43-
bottomDist := ((box.Pos.Y + box.Half.Y) - circle.Pos.Y) + circle.Radius
39+
leftDist := (b.Pos.X - (a.Pos.X - a.Half.X)) + b.Radius
40+
rightDist := ((a.Pos.X + a.Half.X) - b.Pos.X) + b.Radius
41+
topDist := (b.Pos.Y - (a.Pos.Y - a.Half.Y)) + b.Radius
42+
bottomDist := ((a.Pos.Y + a.Half.Y) - b.Pos.Y) + b.Radius
4443

4544
// Find minimum penetration
4645
minDist := math.Min(math.Min(leftDist, rightDist), math.Min(topDist, bottomDist))
@@ -71,42 +70,42 @@ func BoxCircleSweep2(box *AABB, circle *Circle, boxVel, circleVel v.Vec, h *Hit)
7170
}
7271

7372
// Expanded box bounds (box + circle radius)
74-
halfX := box.Half.X + circle.Radius
75-
halfY := box.Half.Y + circle.Radius
76-
boxMinX := box.Pos.X - halfX
77-
boxMaxX := box.Pos.X + halfX
78-
boxMinY := box.Pos.Y - halfY
79-
boxMaxY := box.Pos.Y + halfY
73+
halfX := a.Half.X + b.Radius
74+
halfY := a.Half.Y + b.Radius
75+
boxMinX := a.Pos.X - halfX
76+
boxMaxX := a.Pos.X + halfX
77+
boxMinY := a.Pos.Y - halfY
78+
boxMaxY := a.Pos.Y + halfY
8079

8180
// AABB ray intersection (slab method)
8281
var tminX, tmaxX, tminY, tmaxY float64
8382
var hitX, hitY bool
8483

85-
if math.Abs(relVelX) > 1e-8 {
86-
invDirX := 1.0 / relVelX
87-
t1 := (boxMinX - circle.Pos.X) * invDirX
88-
t2 := (boxMaxX - circle.Pos.X) * invDirX
84+
if math.Abs(relDeltaX) > 1e-8 {
85+
invDirX := 1.0 / relDeltaX
86+
t1 := (boxMinX - b.Pos.X) * invDirX
87+
t2 := (boxMaxX - b.Pos.X) * invDirX
8988
tminX = min(t1, t2)
9089
tmaxX = max(t1, t2)
9190
hitX = true
9291
} else {
93-
if circle.Pos.X < boxMinX || circle.Pos.X > boxMaxX {
92+
if b.Pos.X < boxMinX || b.Pos.X > boxMaxX {
9493
return false
9594
}
9695
tminX = -math.MaxFloat64
9796
tmaxX = math.MaxFloat64
9897
hitX = false
9998
}
10099

101-
if math.Abs(relVelY) > 1e-8 {
102-
invDirY := 1.0 / relVelY
103-
t3 := (boxMinY - circle.Pos.Y) * invDirY
104-
t4 := (boxMaxY - circle.Pos.Y) * invDirY
100+
if math.Abs(relDeltaY) > 1e-8 {
101+
invDirY := 1.0 / relDeltaY
102+
t3 := (boxMinY - b.Pos.Y) * invDirY
103+
t4 := (boxMaxY - b.Pos.Y) * invDirY
105104
tminY = min(t3, t4)
106105
tmaxY = max(t3, t4)
107106
hitY = true
108107
} else {
109-
if circle.Pos.Y < boxMinY || circle.Pos.Y > boxMaxY {
108+
if b.Pos.Y < boxMinY || b.Pos.Y > boxMaxY {
110109
return false
111110
}
112111
tminY = -math.MaxFloat64
@@ -125,16 +124,16 @@ func BoxCircleSweep2(box *AABB, circle *Circle, boxVel, circleVel v.Vec, h *Hit)
125124
// Already overlapping at t=0
126125
if tmin < 0 {
127126
// Find closest point on AABB to circle center
128-
closestX := math.Max(box.Pos.X-box.Half.X, math.Min(circle.Pos.X, box.Pos.X+box.Half.X))
129-
closestY := math.Max(box.Pos.Y-box.Half.Y, math.Min(circle.Pos.Y, box.Pos.Y+box.Half.Y))
127+
closestX := math.Max(a.Pos.X-a.Half.X, math.Min(b.Pos.X, a.Pos.X+a.Half.X))
128+
closestY := math.Max(a.Pos.Y-a.Half.Y, math.Min(b.Pos.Y, a.Pos.Y+a.Half.Y))
130129

131130
// Vector from closest point to circle center
132-
distX := circle.Pos.X - closestX
133-
distY := circle.Pos.Y - closestY
131+
distX := b.Pos.X - closestX
132+
distY := b.Pos.Y - closestY
134133
distSq := distX*distX + distY*distY
135134

136135
// Check if overlapping
137-
if distSq >= circle.Radius*circle.Radius {
136+
if distSq >= b.Radius*b.Radius {
138137
return false
139138
}
140139

@@ -144,10 +143,10 @@ func BoxCircleSweep2(box *AABB, circle *Circle, boxVel, circleVel v.Vec, h *Hit)
144143
// If circle center is inside box
145144
if distSq < 1e-8 {
146145
// Calculate penetration depths for each side
147-
leftDist := (circle.Pos.X - (box.Pos.X - box.Half.X)) + circle.Radius
148-
rightDist := ((box.Pos.X + box.Half.X) - circle.Pos.X) + circle.Radius
149-
topDist := (circle.Pos.Y - (box.Pos.Y - box.Half.Y)) + circle.Radius
150-
bottomDist := ((box.Pos.Y + box.Half.Y) - circle.Pos.Y) + circle.Radius
146+
leftDist := (b.Pos.X - (a.Pos.X - a.Half.X)) + b.Radius
147+
rightDist := ((a.Pos.X + a.Half.X) - b.Pos.X) + b.Radius
148+
topDist := (b.Pos.Y - (a.Pos.Y - a.Half.Y)) + b.Radius
149+
bottomDist := ((a.Pos.Y + a.Half.Y) - b.Pos.Y) + b.Radius
151150

152151
// Find minimum penetration
153152
minDist := math.Min(math.Min(leftDist, rightDist), math.Min(topDist, bottomDist))
@@ -185,19 +184,19 @@ func BoxCircleSweep2(box *AABB, circle *Circle, boxVel, circleVel v.Vec, h *Hit)
185184
if !hitX {
186185
// Only Y axis moving
187186
h.Normal.X = 0
188-
h.Normal.Y = math.Copysign(1, -relVelY)
187+
h.Normal.Y = math.Copysign(1, -relDeltaY)
189188
} else if !hitY {
190189
// Only X axis moving
191-
h.Normal.X = math.Copysign(1, -relVelX)
190+
h.Normal.X = math.Copysign(1, -relDeltaX)
192191
h.Normal.Y = 0
193192
} else if tminX > tminY {
194193
// X axis constrained the hit
195-
h.Normal.X = math.Copysign(1, -relVelX)
194+
h.Normal.X = math.Copysign(1, -relDeltaX)
196195
h.Normal.Y = 0
197196
} else {
198197
// Y axis constrained the hit
199198
h.Normal.X = 0
200-
h.Normal.Y = math.Copysign(1, -relVelY)
199+
h.Normal.Y = math.Copysign(1, -relDeltaY)
201200
}
202201

203202
h.Data = tmin

box_orientedbox_overlap.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,34 @@ import (
88

99
// BoxOrientedBoxOverlap tests if an AABB and OBB are currently intersecting.
1010
// For moving objects, use BoxOrientedBoxSweep2 to prevent tunneling.
11-
func BoxOrientedBoxOverlap(a *AABB, b *OBB) bool {
12-
d := b.Pos.Sub(a.Pos)
11+
func BoxOrientedBoxOverlap(a *AABB, o *OBB) bool {
12+
d := o.Pos.Sub(a.Pos)
1313

1414
// Precompute axes and their absolute values
15-
bAxisX := v.FromAngle(b.Angle)
15+
bAxisX := v.FromAngle(o.Angle)
1616
bAxisY := v.Vec{X: -bAxisX.Y, Y: bAxisX.X}
1717
bAxisXAbs := bAxisX.Abs()
1818
bAxisYAbs := bAxisY.Abs()
1919

2020
// Check AABB axes
21-
projBOnAx := bAxisXAbs.X*b.Half.X + bAxisYAbs.X*b.Half.Y
21+
projBOnAx := bAxisXAbs.X*o.Half.X + bAxisYAbs.X*o.Half.Y
2222
if math.Abs(d.X) > a.Half.X+projBOnAx {
2323
return false
2424
}
2525

26-
projBOnAy := bAxisXAbs.Y*b.Half.X + bAxisYAbs.Y*b.Half.Y
26+
projBOnAy := bAxisXAbs.Y*o.Half.X + bAxisYAbs.Y*o.Half.Y
2727
if math.Abs(d.Y) > a.Half.Y+projBOnAy {
2828
return false
2929
}
3030

3131
// Check OBB axes
3232
distOnObbX := math.Abs(d.Dot(bAxisX))
3333
projAOnObbX := bAxisXAbs.X*a.Half.X + bAxisXAbs.Y*a.Half.Y
34-
if distOnObbX > b.Half.X+projAOnObbX {
34+
if distOnObbX > o.Half.X+projAOnObbX {
3535
return false
3636
}
3737

3838
distOnObbY := math.Abs(d.Dot(bAxisY))
3939
projAOnObbY := bAxisYAbs.X*a.Half.X + bAxisYAbs.Y*a.Half.Y
40-
return distOnObbY <= b.Half.Y+projAOnObbY
40+
return distOnObbY <= o.Half.Y+projAOnObbY
4141
}

box_orientedbox_sweep2.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,19 @@ import (
88

99
// BoxOrientedBoxSweep2 tests if a moving AABB and moving OBB intersect during their motion.
1010
// Uses swept volume testing to prevent tunneling for fast-moving objects.
11-
func BoxOrientedBoxSweep2(a *AABB, b *OBB, va v.Vec, vb v.Vec) bool {
12-
relVx := vb.X - va.X
13-
relVy := vb.Y - va.Y
14-
tx := b.Pos.X - a.Pos.X
15-
ty := b.Pos.Y - a.Pos.Y
11+
func BoxOrientedBoxSweep2(a *AABB, o *OBB, deltaA v.Vec, deltaO v.Vec) bool {
12+
relVx := deltaO.X - deltaA.X
13+
relVy := deltaO.Y - deltaA.Y
14+
tx := o.Pos.X - a.Pos.X
15+
ty := o.Pos.Y - a.Pos.Y
1616

17-
bAx := v.FromAngle(b.Angle)
17+
bAx := v.FromAngle(o.Angle)
1818
bAy := v.Vec{X: -bAx.Y, Y: bAx.X}
1919

2020
absAx := bAx.Abs()
2121
absAy := bAy.Abs()
2222

23-
projB_on_GlobalX := (absAx.X * b.Half.X) + (absAy.X * b.Half.Y)
23+
projB_on_GlobalX := (absAx.X * o.Half.X) + (absAy.X * o.Half.Y)
2424
limitX := a.Half.X + projB_on_GlobalX
2525
if (tx > 0 && relVx < 0) || (tx < 0 && relVx > 0) {
2626
limitX += math.Abs(relVx)
@@ -29,7 +29,7 @@ func BoxOrientedBoxSweep2(a *AABB, b *OBB, va v.Vec, vb v.Vec) bool {
2929
return false
3030
}
3131

32-
projB_on_GlobalY := (absAx.Y * b.Half.X) + (absAy.Y * b.Half.Y)
32+
projB_on_GlobalY := (absAx.Y * o.Half.X) + (absAy.Y * o.Half.Y)
3333
limitY := a.Half.Y + projB_on_GlobalY
3434
if (ty > 0 && relVy < 0) || (ty < 0 && relVy > 0) {
3535
limitY += math.Abs(relVy)
@@ -41,7 +41,7 @@ func BoxOrientedBoxSweep2(a *AABB, b *OBB, va v.Vec, vb v.Vec) bool {
4141
dotT_Ax := (tx * bAx.X) + (ty * bAx.Y)
4242
projA_on_ObbX := (absAx.X * a.Half.X) + (absAx.Y * a.Half.Y)
4343
dotV_Ax := (relVx * bAx.X) + (relVy * bAx.Y)
44-
limitObbX := b.Half.X + projA_on_ObbX
44+
limitObbX := o.Half.X + projA_on_ObbX
4545
if (dotT_Ax > 0 && dotV_Ax < 0) || (dotT_Ax < 0 && dotV_Ax > 0) {
4646
limitObbX += math.Abs(dotV_Ax)
4747
}
@@ -52,7 +52,7 @@ func BoxOrientedBoxSweep2(a *AABB, b *OBB, va v.Vec, vb v.Vec) bool {
5252
dotT_Ay := (tx * bAy.X) + (ty * bAy.Y)
5353
projA_on_ObbY := (absAy.X * a.Half.X) + (absAy.Y * a.Half.Y)
5454
dotV_Ay := (relVx * bAy.X) + (relVy * bAy.Y)
55-
limitObbY := b.Half.Y + projA_on_ObbY
55+
limitObbY := o.Half.Y + projA_on_ObbY
5656
if (dotT_Ay > 0 && dotV_Ay < 0) || (dotT_Ay < 0 && dotV_Ay > 0) {
5757
limitObbY += math.Abs(dotV_Ay)
5858
}

0 commit comments

Comments
 (0)