106 lines
2.3 KiB
Go
106 lines
2.3 KiB
Go
package globject
|
|
|
|
import (
|
|
"git.wisellama.rocks/Wisellama/carpy-breakout/pkg/math"
|
|
"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{
|
|
math.Maxf32(topRight.X(), bottomLeft.X()),
|
|
math.Maxf32(topRight.Y(), bottomLeft.Y()),
|
|
math.Maxf32(topRight.Z(), bottomLeft.Z()),
|
|
}
|
|
|
|
min := mgl32.Vec3{
|
|
math.Minf32(topRight.X(), bottomLeft.X()),
|
|
math.Minf32(topRight.Y(), bottomLeft.Y()),
|
|
math.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, mgl32.Vec3) {
|
|
intersects := make([]bool, 3)
|
|
|
|
diff1 := self.BottomLeft.Sub(other.TopRight)
|
|
diff2 := self.TopRight.Sub(other.BottomLeft)
|
|
|
|
intersects[0] = (diff1.X() <= 0) && (diff2.X() >= 0)
|
|
intersects[1] = (diff1.Y() <= 0) && (diff2.Y() >= 0)
|
|
intersects[2] = (diff1.Z() <= 0) && (diff2.Z() >= 0)
|
|
|
|
intersected := intersects[0] && intersects[1] && intersects[2]
|
|
|
|
// Calculate how much they intersected by so we can guess which
|
|
// side the collision occurred.
|
|
smallerDiff := diff1
|
|
if diff2.LenSqr() < diff1.LenSqr() {
|
|
smallerDiff = diff2
|
|
}
|
|
|
|
return intersected, math.AbsVec3(smallerDiff)
|
|
}
|
|
|
|
func XCollision(diff mgl32.Vec3) bool {
|
|
if diff.X() < diff.Y() && diff.X() < diff.Z() {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func YCollision(diff mgl32.Vec3) bool {
|
|
// Slight bias for vertical collisions
|
|
if diff.Y() <= diff.X() && diff.Y() <= diff.Z() {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func ZCollision(diff mgl32.Vec3) bool {
|
|
if diff.Z() < diff.X() && diff.Z() < diff.Y() {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|