110 lines
2.8 KiB
Go
110 lines
2.8 KiB
Go
package globjects
|
|
|
|
import (
|
|
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/mathhelpers"
|
|
"github.com/go-gl/mathgl/mgl32"
|
|
)
|
|
|
|
// AABB implements a simple Axis-Aligned Bounding Box for collision detection.
|
|
type AABB struct {
|
|
TopRight mgl32.Vec3
|
|
BottomLeft mgl32.Vec3
|
|
}
|
|
|
|
func NewAABB(topRight, bottomLeft mgl32.Vec3) *AABB {
|
|
aabb := AABB{
|
|
TopRight: topRight,
|
|
BottomLeft: bottomLeft,
|
|
}
|
|
|
|
return &aabb
|
|
}
|
|
|
|
func NewAABBFromBox(box *Box) *AABB {
|
|
xOffset := box.Width / 2.0
|
|
yOffset := box.Height / 2.0
|
|
zOffset := box.Depth / 2.0
|
|
|
|
offset := mgl32.Vec4{
|
|
xOffset,
|
|
yOffset,
|
|
zOffset,
|
|
1,
|
|
}
|
|
|
|
// Apply the rotation to the offset vector
|
|
rotatedOffset := box.GetRotationMatrix().Mul4x1(offset)
|
|
|
|
// Use the offset and the negation as the top right and bottom left
|
|
topRight := rotatedOffset
|
|
bottomLeft := rotatedOffset.Mul(-1)
|
|
|
|
// Then get the axis-align version of this box using min/max
|
|
max := mgl32.Vec3{
|
|
mathhelpers.Maxf32(topRight.X(), bottomLeft.X()),
|
|
mathhelpers.Maxf32(topRight.Y(), bottomLeft.Y()),
|
|
mathhelpers.Maxf32(topRight.Z(), bottomLeft.Z()),
|
|
}
|
|
|
|
min := mgl32.Vec3{
|
|
mathhelpers.Minf32(topRight.X(), bottomLeft.X()),
|
|
mathhelpers.Minf32(topRight.Y(), bottomLeft.Y()),
|
|
mathhelpers.Minf32(topRight.Z(), bottomLeft.Z()),
|
|
}
|
|
|
|
// Then move it into position based on the translation
|
|
pos := box.Translation
|
|
return NewAABB(max.Add(pos), min.Add(pos))
|
|
}
|
|
|
|
func (self *AABB) Intersects(other *AABB) bool {
|
|
boolArray := self.IntersectsArray(other)
|
|
|
|
intersects := boolArray[0] && boolArray[1] && boolArray[2]
|
|
|
|
return intersects
|
|
}
|
|
|
|
func (self *AABB) IntersectsArray(other *AABB) []bool {
|
|
|
|
boolArray := make([]bool, 3)
|
|
if other == nil {
|
|
return boolArray
|
|
}
|
|
|
|
boolArray[0] = self.BottomLeft.X() <= other.TopRight.X() && self.TopRight.X() >= other.BottomLeft.X()
|
|
boolArray[1] = self.BottomLeft.Y() <= other.TopRight.Y() && self.TopRight.Y() >= other.BottomLeft.Y()
|
|
boolArray[2] = self.BottomLeft.Z() <= other.TopRight.Z() && self.TopRight.Z() >= other.BottomLeft.Z()
|
|
|
|
return boolArray
|
|
}
|
|
|
|
// HorizontalCollisions returns true if the our box hit the 'other' box on the X axis.
|
|
// This is expected to be called after checking for a general intersection with Intersects()
|
|
func (self *AABB) HorizontalCollision(other *AABB) bool {
|
|
|
|
right := self.TopRight.X() - other.BottomLeft.X()
|
|
left := self.BottomLeft.X() - other.TopRight.X()
|
|
|
|
right = mathhelpers.Absf32(right)
|
|
left = mathhelpers.Absf32(left)
|
|
|
|
min := mathhelpers.Minf32(right, left)
|
|
|
|
return mathhelpers.Absf32(min) < 0.1
|
|
|
|
}
|
|
|
|
func (self *AABB) VerticalCollision(other *AABB) bool {
|
|
top := self.TopRight.Y() - other.BottomLeft.Y()
|
|
bottom := self.BottomLeft.Y() - other.TopRight.Y()
|
|
|
|
top = mathhelpers.Absf32(top)
|
|
bottom = mathhelpers.Absf32(bottom)
|
|
|
|
min := mathhelpers.Minf32(top, bottom)
|
|
|
|
return mathhelpers.Absf32(min) < 0.1
|
|
|
|
}
|