Rename stuff. Collisions don't work right
parent
95d58d4525
commit
343a43bed3
|
@ -2,3 +2,4 @@
|
|||
|
||||
carpy-breakout
|
||||
output.log
|
||||
cpu.prof
|
||||
|
|
5
Makefile
5
Makefile
|
@ -12,6 +12,11 @@ release: linter dependencies
|
|||
linter:
|
||||
golangci-lint run
|
||||
|
||||
clean:
|
||||
rm -f carpy-breakout
|
||||
rm -f output.log
|
||||
rm -f cpu.prof
|
||||
|
||||
cross_windows:
|
||||
export CGO_ENABLED=1
|
||||
export CC=x86_64-w64-mingw32-gcc
|
||||
|
|
|
@ -16,6 +16,12 @@ Press `L` to toggle wireframe mode.
|
|||
|
||||
Press `K` to toggle freelook mode.
|
||||
|
||||
## Coordinate System
|
||||
|
||||
For the code, I was using the right-hand rule (turned around) for the
|
||||
3d coordinates. If you were looking straight ahead, forward is
|
||||
-Z, right is +X, and up is +Y.
|
||||
|
||||
## Why "Carpy"?
|
||||
|
||||
Because it's a funny misspelling of "Crappy". This was originally
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
package breakout
|
||||
|
||||
import (
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/globjects"
|
||||
"log"
|
||||
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/globject"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
||||
type Ball struct {
|
||||
Box *globjects.Box
|
||||
Box *globject.Box
|
||||
}
|
||||
|
||||
func NewBall(box *globjects.Box) *Ball {
|
||||
func NewBall(box *globject.Box) *Ball {
|
||||
ball := Ball{
|
||||
Box: box,
|
||||
}
|
||||
|
@ -32,7 +35,7 @@ func (self *Ball) ToggleWireframe() {
|
|||
self.Box.ToggleWireframe()
|
||||
}
|
||||
|
||||
func (self *Ball) GetAABB() *globjects.AABB {
|
||||
func (self *Ball) GetAABB() *globject.AABB {
|
||||
return self.Box.GetAABB()
|
||||
}
|
||||
|
||||
|
@ -40,15 +43,15 @@ func (self *Ball) HandlePaddleCollision(paddle *Paddle) {
|
|||
aabb := self.GetAABB()
|
||||
p := paddle.GetAABB()
|
||||
|
||||
intersects := aabb.Intersects(p)
|
||||
intersects, diff := aabb.Intersects(p)
|
||||
|
||||
if intersects {
|
||||
newVelocity := self.Box.Velocity
|
||||
if aabb.HorizontalCollision(p) {
|
||||
if globject.XCollision(diff) {
|
||||
newVelocity[0] = -1 * newVelocity[0]
|
||||
}
|
||||
|
||||
if aabb.VerticalCollision(p) {
|
||||
if globject.YCollision(diff) {
|
||||
// Change differently based on which part of the paddle we hit
|
||||
// TODO
|
||||
newVelocity[1] = -1 * newVelocity[1]
|
||||
|
@ -59,49 +62,50 @@ func (self *Ball) HandlePaddleCollision(paddle *Paddle) {
|
|||
}
|
||||
|
||||
func (self *Ball) HandleTargetCollisions(targets *Targets) {
|
||||
intersects := false
|
||||
aabb := self.GetAABB()
|
||||
for _, brick := range targets.Bricks {
|
||||
if !brick.Broken() {
|
||||
b := brick.GetAABB()
|
||||
|
||||
intersects = aabb.Intersects(b)
|
||||
intersects, diff := aabb.Intersects(b)
|
||||
|
||||
if intersects {
|
||||
// TODO points
|
||||
brick.Break()
|
||||
|
||||
self.UpdateVelocityFromCollision(aabb, b)
|
||||
self.UpdateElasticCollision(diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Ball) HandleSideWallsCollisions(sidewalls *SideWalls) {
|
||||
intersects := false
|
||||
|
||||
aabb := self.GetAABB()
|
||||
boxes := sidewalls.Boxes
|
||||
for _, box := range boxes {
|
||||
b := box.GetAABB()
|
||||
intersects = aabb.Intersects(b)
|
||||
intersects, diff := aabb.Intersects(b)
|
||||
|
||||
if intersects {
|
||||
self.UpdateVelocityFromCollision(aabb, b)
|
||||
self.UpdateElasticCollision(diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Ball) UpdateVelocityFromCollision(us, them *globjects.AABB) {
|
||||
func (self *Ball) UpdateElasticCollision(diff mgl32.Vec3) {
|
||||
newVelocity := self.Box.Velocity
|
||||
|
||||
if us.HorizontalCollision(them) {
|
||||
if globject.XCollision(diff) {
|
||||
log.Printf("X collision: %v\n", diff)
|
||||
newVelocity[0] = -1 * newVelocity[0]
|
||||
}
|
||||
|
||||
if us.VerticalCollision(them) {
|
||||
if globject.YCollision(diff) {
|
||||
log.Printf("Y collision: %v\n", diff)
|
||||
newVelocity[1] = -1 * newVelocity[1]
|
||||
}
|
||||
|
||||
// No Z collisions for this game
|
||||
|
||||
self.Box.Velocity = newVelocity
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package breakout
|
||||
|
||||
import (
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/globjects"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/globject"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
||||
type Brick struct {
|
||||
Box *globjects.Box
|
||||
Box *globject.Box
|
||||
broken bool
|
||||
}
|
||||
|
||||
|
@ -15,10 +15,10 @@ func NewBrick(
|
|||
brickHeight float32,
|
||||
brickDepth float32,
|
||||
position mgl32.Vec3,
|
||||
material *globjects.Material) *Brick {
|
||||
material *globject.Material) *Brick {
|
||||
|
||||
brick := Brick{
|
||||
Box: globjects.NewBox(brickWidth, brickHeight, brickDepth, position, material),
|
||||
Box: globject.NewBox(brickWidth, brickHeight, brickDepth, position, material),
|
||||
broken: false,
|
||||
}
|
||||
return &brick
|
||||
|
@ -42,7 +42,7 @@ func (b *Brick) ToggleWireframe() {
|
|||
b.Box.ToggleWireframe()
|
||||
}
|
||||
|
||||
func (b *Brick) GetAABB() *globjects.AABB {
|
||||
func (b *Brick) GetAABB() *globject.AABB {
|
||||
return b.Box.GetAABB()
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ func (b *Brick) Broken() bool {
|
|||
func (b *Brick) Break() {
|
||||
b.broken = true
|
||||
|
||||
clear := globjects.NewMaterial()
|
||||
clear := globject.NewMaterial()
|
||||
|
||||
clear.Color = mgl32.Vec4{0, 0, 0, 0}
|
||||
clear.Shininess = 0
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package breakout
|
||||
|
||||
import "gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/globjects"
|
||||
import "gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/globject"
|
||||
|
||||
type Paddle struct {
|
||||
Box *globjects.Box
|
||||
Box *globject.Box
|
||||
}
|
||||
|
||||
func (self *Paddle) Update() {
|
||||
|
@ -22,11 +22,11 @@ func (self *Paddle) ToggleWireframe() {
|
|||
self.Box.ToggleWireframe()
|
||||
}
|
||||
|
||||
func (self *Paddle) GetAABB() *globjects.AABB {
|
||||
func (self *Paddle) GetAABB() *globject.AABB {
|
||||
return self.Box.GetAABB()
|
||||
}
|
||||
|
||||
func NewPaddle(box *globjects.Box) *Paddle {
|
||||
func NewPaddle(box *globject.Box) *Paddle {
|
||||
paddle := Paddle{
|
||||
Box: box,
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package breakout
|
||||
|
||||
import (
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/globjects"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/globject"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
||||
type SideWalls struct {
|
||||
Boxes []*globjects.Box
|
||||
Boxes []*globject.Box
|
||||
}
|
||||
|
||||
func NewSideWalls(aabb *globjects.AABB, material *globjects.Material) *SideWalls {
|
||||
func NewSideWalls(aabb *globject.AABB, material *globject.Material) *SideWalls {
|
||||
|
||||
topRight := aabb.TopRight
|
||||
bottomLeft := aabb.BottomLeft
|
||||
|
@ -18,23 +18,23 @@ func NewSideWalls(aabb *globjects.AABB, material *globjects.Material) *SideWalls
|
|||
var height float32 = 4.0
|
||||
var offset float32 = height / 2.0
|
||||
|
||||
boxes := make([]*globjects.Box, 4)
|
||||
boxes := make([]*globject.Box, 4)
|
||||
|
||||
// Top
|
||||
topPos := mgl32.Vec3{0, topRight.Y() + offset, topRight.Z()}
|
||||
boxes[0] = globjects.NewBox(topRight.X()-bottomLeft.X()+height*2, height, depth, topPos, material)
|
||||
boxes[0] = globject.NewBox(topRight.X()-bottomLeft.X()+height*2, height, depth, topPos, material)
|
||||
|
||||
// Bottom
|
||||
bottomPos := mgl32.Vec3{0, bottomLeft.Y() - offset, bottomLeft.Z()}
|
||||
boxes[1] = globjects.NewBox(topRight.X()-bottomLeft.X()+height*2, height, depth, bottomPos, material)
|
||||
boxes[1] = globject.NewBox(topRight.X()-bottomLeft.X()+height*2, height, depth, bottomPos, material)
|
||||
|
||||
// Left
|
||||
leftPos := mgl32.Vec3{bottomLeft.X() - offset, 0, bottomLeft.Z()}
|
||||
boxes[2] = globjects.NewBox(height, topRight.Y()-bottomLeft.Y(), depth, leftPos, material)
|
||||
boxes[2] = globject.NewBox(height, topRight.Y()-bottomLeft.Y(), depth, leftPos, material)
|
||||
|
||||
// Right
|
||||
rightPos := mgl32.Vec3{topRight.X() + offset, 0, topRight.Z()}
|
||||
boxes[3] = globjects.NewBox(height, topRight.Y()-bottomLeft.Y(), depth, rightPos, material)
|
||||
boxes[3] = globject.NewBox(height, topRight.Y()-bottomLeft.Y(), depth, rightPos, material)
|
||||
|
||||
sideWalls := SideWalls{
|
||||
Boxes: boxes,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package breakout
|
||||
|
||||
import (
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/globjects"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/globject"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
||||
|
@ -47,12 +47,12 @@ func NewTargets(numRows, numColumns int, adjustPos mgl32.Vec3) *Targets {
|
|||
targets.TopRight = topRightPos
|
||||
targets.BottomLeft = bottomLeftPos
|
||||
|
||||
materials := make([]*globjects.Material, numColumns)
|
||||
materials := make([]*globject.Material, numColumns)
|
||||
|
||||
for i := 0; i < numColumns; i++ {
|
||||
red := 0 + float32(i)/float32(numColumns)
|
||||
blue := 1 - float32(i)/float32(numColumns)
|
||||
m := globjects.NewMaterial()
|
||||
m := globject.NewMaterial()
|
||||
m.Color = mgl32.Vec4{red, 0, blue, 1}
|
||||
materials[i] = m
|
||||
}
|
||||
|
|
|
@ -1,28 +1,36 @@
|
|||
package breakout
|
||||
package game
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/breakout"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/config"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/glhelpers"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/globjects"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/globject"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/glshader"
|
||||
gl "github.com/go-gl/gl/v3.1/gles2"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
)
|
||||
|
||||
type GLObject interface {
|
||||
Update()
|
||||
GLDraw()
|
||||
GLInit(glProgram uint32)
|
||||
ToggleWireframe()
|
||||
}
|
||||
|
||||
type GameWindow struct {
|
||||
SDLWindow *sdl.Window
|
||||
GLContext *sdl.GLContext
|
||||
GLProgram uint32
|
||||
GLObjects []globjects.GLObject
|
||||
Camera *globjects.Camera
|
||||
Paddle *Paddle
|
||||
Ball *Ball
|
||||
Targets *Targets
|
||||
SideWalls *SideWalls
|
||||
AABB *globjects.AABB // This AABB represents the inside playable area
|
||||
Globject []GLObject
|
||||
Camera *globject.Camera
|
||||
Paddle *breakout.Paddle
|
||||
Ball *breakout.Ball
|
||||
Targets *breakout.Targets
|
||||
SideWalls *breakout.SideWalls
|
||||
AABB *globject.AABB // This AABB represents the inside playable area
|
||||
|
||||
keystates map[sdl.Keycode]bool
|
||||
mouseMoved bool
|
||||
|
@ -71,7 +79,7 @@ func (w *GameWindow) GLInit(glProgram uint32) {
|
|||
}
|
||||
|
||||
func (w *GameWindow) GLInitDefault() error {
|
||||
glProgram, err := glhelpers.NewDefaultProgram()
|
||||
glProgram, err := glshader.NewDefaultProgram()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -81,8 +89,8 @@ func (w *GameWindow) GLInitDefault() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (w *GameWindow) AddObject(object globjects.GLObject) {
|
||||
w.GLObjects = append(w.GLObjects, object)
|
||||
func (w *GameWindow) AddObject(object GLObject) {
|
||||
w.Globject = append(w.Globject, object)
|
||||
}
|
||||
|
||||
func (w *GameWindow) Destroy() {
|
||||
|
@ -130,35 +138,35 @@ func (w *GameWindow) StopRunning() {
|
|||
func (w *GameWindow) WindowProjection() {
|
||||
width, height := w.SDLWindow.GLGetDrawableSize()
|
||||
projection := mgl32.Perspective(mgl32.DegToRad(45.0), float32(width)/float32(height), 0.01, 1000.0)
|
||||
glhelpers.SetUniformMatrix4f(w.GLProgram, "projection", &projection)
|
||||
glshader.SetUniformMatrix4f(w.GLProgram, "projection", &projection)
|
||||
|
||||
gl.Viewport(0, 0, width, height)
|
||||
}
|
||||
|
||||
func (w *GameWindow) SetPaddle(paddle *Paddle) {
|
||||
func (w *GameWindow) SetPaddle(paddle *breakout.Paddle) {
|
||||
w.Paddle = paddle
|
||||
}
|
||||
|
||||
func (w *GameWindow) SetBall(ball *Ball) {
|
||||
func (w *GameWindow) SetBall(ball *breakout.Ball) {
|
||||
w.Ball = ball
|
||||
}
|
||||
|
||||
func (w *GameWindow) SetTargets(targets *Targets) {
|
||||
func (w *GameWindow) SetTargets(targets *breakout.Targets) {
|
||||
w.Targets = targets
|
||||
}
|
||||
|
||||
func (w *GameWindow) SetSideWalls(sidewalls *SideWalls) {
|
||||
func (w *GameWindow) SetSideWalls(sidewalls *breakout.SideWalls) {
|
||||
w.SideWalls = sidewalls
|
||||
}
|
||||
|
||||
func (w *GameWindow) SetCamera(camera *globjects.Camera) {
|
||||
func (w *GameWindow) SetCamera(camera *globject.Camera) {
|
||||
w.Camera = camera
|
||||
}
|
||||
|
||||
func (w *GameWindow) ToggleWireframe() {
|
||||
// TODO figure out concurrency
|
||||
// var wg sync.WaitGroup
|
||||
// for _, o := range w.GLObjects {
|
||||
// for _, o := range w.Globject {
|
||||
// wg.Add(1)
|
||||
// go func() {
|
||||
// o.ToggleWireframe()
|
||||
|
@ -167,7 +175,7 @@ func (w *GameWindow) ToggleWireframe() {
|
|||
// }
|
||||
// wg.Wait()
|
||||
|
||||
for _, o := range w.GLObjects {
|
||||
for _, o := range w.Globject {
|
||||
o.ToggleWireframe()
|
||||
}
|
||||
}
|
||||
|
@ -176,8 +184,8 @@ func (w *GameWindow) GLDraw() {
|
|||
model := mgl32.Ident4()
|
||||
|
||||
// Probably can't do concurrent drawing due to OpenGL
|
||||
for _, o := range w.GLObjects {
|
||||
glhelpers.SetUniformMatrix4f(w.GLProgram, "model", &model)
|
||||
for _, o := range w.Globject {
|
||||
glshader.SetUniformMatrix4f(w.GLProgram, "model", &model)
|
||||
o.GLDraw()
|
||||
}
|
||||
}
|
||||
|
@ -185,7 +193,7 @@ func (w *GameWindow) GLDraw() {
|
|||
func (w *GameWindow) Update() {
|
||||
// TODO figure out concurrency
|
||||
// var wg sync.WaitGroup
|
||||
// for _, o := range w.GLObjects {
|
||||
// for _, o := range w.Globject {
|
||||
// wg.Add(1)
|
||||
// go func() {
|
||||
// o.Update()
|
||||
|
@ -196,10 +204,8 @@ func (w *GameWindow) Update() {
|
|||
|
||||
if w.IsFreelookOn() {
|
||||
w.handleFreelookMovement()
|
||||
} else {
|
||||
if !w.mouseMoved {
|
||||
w.handleGameKeyboardMovement()
|
||||
}
|
||||
} else if !w.mouseMoved {
|
||||
w.handleGameKeyboardMovement()
|
||||
}
|
||||
w.mouseMoved = false
|
||||
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/breakout"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/config"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/globjects"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/globject"
|
||||
"gitea.wisellama.rocks/Wisellama/gosimpleconf"
|
||||
gl "github.com/go-gl/gl/v3.1/gles2"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
|
@ -32,7 +32,7 @@ func Run(configMap gosimpleconf.ConfigMap) {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
gameWindow, err := breakout.NewGameWindow(configMap["game.title"])
|
||||
gameWindow, err := NewGameWindow(configMap["game.title"])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -55,10 +55,10 @@ func Run(configMap gosimpleconf.ConfigMap) {
|
|||
log.Printf("error in gameWindow GLInitDefault: %v", err)
|
||||
}
|
||||
|
||||
sunLight := globjects.NewPointLight(mgl32.Vec3{-10, 10, 30})
|
||||
sunLight := globject.NewPointLight(mgl32.Vec3{-10, 10, 30})
|
||||
sunLight.GLInit(gameWindow.GLProgram)
|
||||
|
||||
camera := globjects.NewCamera(gameWindow.GLProgram)
|
||||
camera := globject.NewCamera(gameWindow.GLProgram)
|
||||
camera.Position = mgl32.Vec3{0, 0, 30}
|
||||
gameWindow.SetCamera(camera)
|
||||
gameWindow.AddObject(camera)
|
||||
|
@ -76,11 +76,11 @@ func Run(configMap gosimpleconf.ConfigMap) {
|
|||
gameWindow.AddObject(brick.Box)
|
||||
}
|
||||
|
||||
gameWindowAABB := globjects.NewAABB(targets.TopRight, targets.TopRight.Mul(-1))
|
||||
gameWindowAABB := globject.NewAABB(targets.TopRight, targets.TopRight.Mul(-1))
|
||||
gameWindow.AABB = gameWindowAABB
|
||||
|
||||
// Side Walls
|
||||
sideWallsMaterial := globjects.NewMaterial()
|
||||
sideWallsMaterial := globject.NewMaterial()
|
||||
sideWallsMaterial.Color = mgl32.Vec4{0.3, 0.3, 0.3, 1}
|
||||
sideWalls := breakout.NewSideWalls(gameWindowAABB, sideWallsMaterial)
|
||||
sideWalls.GLInit(gameWindow.GLProgram)
|
||||
|
@ -90,18 +90,18 @@ func Run(configMap gosimpleconf.ConfigMap) {
|
|||
}
|
||||
|
||||
// Paddle
|
||||
paddleMaterial := globjects.NewMaterial()
|
||||
paddleMaterial := globject.NewMaterial()
|
||||
paddleMaterial.Color = mgl32.Vec4{0, 1, 0, 1}
|
||||
paddleBox := globjects.NewBox(6.0, 1.0, 4.0, mgl32.Vec3{0, -8, 0}, paddleMaterial)
|
||||
paddleBox := globject.NewBox(6.0, 1.0, 4.0, mgl32.Vec3{0, -8, 0}, paddleMaterial)
|
||||
paddle := breakout.NewPaddle(paddleBox)
|
||||
paddle.GLInit(gameWindow.GLProgram)
|
||||
gameWindow.SetPaddle(paddle)
|
||||
gameWindow.AddObject(paddle)
|
||||
|
||||
// Ball
|
||||
ballMaterial := globjects.NewMaterial()
|
||||
ballMaterial := globject.NewMaterial()
|
||||
ballMaterial.Color = mgl32.Vec4{1, 1, 1, 1}
|
||||
ballBox := globjects.NewBox(1, 1, 1, mgl32.Vec3{-8, 0, 0}, ballMaterial)
|
||||
ballBox := globject.NewBox(1, 1, 1, mgl32.Vec3{-8, 0, 0}, ballMaterial)
|
||||
ball := breakout.NewBall(ballBox)
|
||||
ball.GLInit(gameWindow.GLProgram)
|
||||
gameWindow.SetBall(ball)
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
package globject
|
||||
|
||||
import (
|
||||
"gitea.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
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package globjects
|
||||
package globject
|
||||
|
||||
import (
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/glhelpers"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/glshader"
|
||||
gl "github.com/go-gl/gl/v3.1/gles2"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
@ -130,7 +130,7 @@ func (b *Box) GetRotationMatrix() *mgl32.Mat4 {
|
|||
func (b *Box) GLDraw() {
|
||||
model := b.GetModelMatrix()
|
||||
|
||||
glhelpers.SetUniformMatrix4f(b.GLProgram, "model", model)
|
||||
glshader.SetUniformMatrix4f(b.GLProgram, "model", model)
|
||||
|
||||
b.Material.GLDraw(b.GLProgram)
|
||||
|
||||
|
@ -142,7 +142,7 @@ func (b *Box) GLDraw() {
|
|||
}
|
||||
|
||||
func (b *Box) glDrawTriangles() {
|
||||
glhelpers.SetUniformInt(b.GLProgram, "lightsOn", 1)
|
||||
glshader.SetUniformInt(b.GLProgram, "lightsOn", 1)
|
||||
|
||||
gl.BindVertexArray(b.GLVertexArrayID)
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, b.GLVertexBufferID)
|
||||
|
@ -152,12 +152,12 @@ func (b *Box) glDrawTriangles() {
|
|||
gl.BindTexture(gl.TEXTURE_2D, b.Material.TextureID)
|
||||
}
|
||||
|
||||
glhelpers.UpdateVertexAttribs(b.GLProgram, VertexSize)
|
||||
glshader.UpdateVertexAttribs(b.GLProgram, VertexSize)
|
||||
gl.DrawArrays(gl.TRIANGLES, 0, 6*2*3) // 6 sides, 2 triangles, 3 points each
|
||||
}
|
||||
|
||||
func (b *Box) glDrawLineLoop() {
|
||||
glhelpers.SetUniformInt(b.GLProgram, "lightsOn", 0)
|
||||
glshader.SetUniformInt(b.GLProgram, "lightsOn", 0)
|
||||
for _, face := range b.Faces {
|
||||
face.GLDrawLineLoop(b.GLProgram)
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package globjects
|
||||
package globject
|
||||
|
||||
import (
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/glhelpers"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/glshader"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
||||
|
@ -47,8 +47,8 @@ func (c *Camera) GetCenter() mgl32.Vec3 {
|
|||
|
||||
func (c *Camera) GLDraw() {
|
||||
cameraMatrix := mgl32.LookAtV(c.Position, c.GetCenter(), c.Up)
|
||||
glhelpers.SetUniformMatrix4f(c.GLProgram, "camera", &cameraMatrix)
|
||||
glhelpers.SetUniformVec3f(c.GLProgram, "cameraPos", c.Position)
|
||||
glshader.SetUniformMatrix4f(c.GLProgram, "camera", &cameraMatrix)
|
||||
glshader.SetUniformVec3f(c.GLProgram, "cameraPos", c.Position)
|
||||
}
|
||||
|
||||
func (c *Camera) GLInit(glProgram uint32) {
|
|
@ -1,7 +1,7 @@
|
|||
package globjects
|
||||
package globject
|
||||
|
||||
import (
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/glhelpers"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/glshader"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
||||
|
@ -24,8 +24,8 @@ func NewDirectionalLight(direction mgl32.Vec3) *DirectionalLight {
|
|||
}
|
||||
|
||||
func (l *DirectionalLight) GLInit(glProgram uint32) {
|
||||
glhelpers.SetUniformVec3f(glProgram, "dirLight.direction", l.Direction)
|
||||
glhelpers.SetUniformVec4f(glProgram, "dirLight.ambient", l.AmbientColor)
|
||||
glhelpers.SetUniformVec4f(glProgram, "dirLight.diffuse", l.DiffuseColor)
|
||||
glhelpers.SetUniformVec4f(glProgram, "dirLight.specular", l.SpecularColor)
|
||||
glshader.SetUniformVec3f(glProgram, "dirLight.direction", l.Direction)
|
||||
glshader.SetUniformVec4f(glProgram, "dirLight.ambient", l.AmbientColor)
|
||||
glshader.SetUniformVec4f(glProgram, "dirLight.diffuse", l.DiffuseColor)
|
||||
glshader.SetUniformVec4f(glProgram, "dirLight.specular", l.SpecularColor)
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
package globjects
|
||||
package globject
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/glhelpers"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/mathhelpers"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/glshader"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/math"
|
||||
gl "github.com/go-gl/gl/v3.1/gles2"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
@ -77,7 +77,7 @@ func newFaceVertex(
|
|||
v := mgl32.Vec3{xoffset, 0, zoffset}
|
||||
|
||||
up := mgl32.Vec3{0, 1, 0}
|
||||
angle, err := mathhelpers.AngleBetweenVectors(up, normal)
|
||||
angle, err := math.AngleBetweenVectors(up, normal)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return nil
|
||||
|
@ -135,12 +135,12 @@ func (f *Face) GLDrawLineLoop(glProgram uint32) {
|
|||
gl.BindVertexArray(f.GLLineLoopVertexArrayID)
|
||||
gl.BindBuffer(gl.ARRAY_BUFFER, f.GLLineLoopVertexBufferID)
|
||||
|
||||
glhelpers.UpdateVertexAttribs(glProgram, VertexSize)
|
||||
glshader.UpdateVertexAttribs(glProgram, VertexSize)
|
||||
gl.DrawArrays(gl.LINE_LOOP, 0, 4)
|
||||
}
|
||||
|
||||
func (f *Face) GLInit(glProgram uint32) {
|
||||
glhelpers.UpdateVertexAttribs(glProgram, VertexSize)
|
||||
glshader.UpdateVertexAttribs(glProgram, VertexSize)
|
||||
// LineLoop setup
|
||||
gl.GenVertexArrays(1, &f.GLLineLoopVertexArrayID)
|
||||
gl.BindVertexArray(f.GLLineLoopVertexArrayID)
|
|
@ -1,7 +1,7 @@
|
|||
package globjects
|
||||
package globject
|
||||
|
||||
import (
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/glhelpers"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/glshader"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
||||
|
@ -25,15 +25,15 @@ func NewMaterial() *Material {
|
|||
}
|
||||
|
||||
func (m *Material) GLDraw(glProgram uint32) {
|
||||
glhelpers.SetUniformInt(glProgram, "material.textureDiffuse", m.TextureDiffuse)
|
||||
glhelpers.SetUniformInt(glProgram, "material.textureSpecular", m.TextureSpecular)
|
||||
glshader.SetUniformInt(glProgram, "material.textureDiffuse", m.TextureDiffuse)
|
||||
glshader.SetUniformInt(glProgram, "material.textureSpecular", m.TextureSpecular)
|
||||
|
||||
glhelpers.SetUniformFloat(glProgram, "material.shininess", m.Shininess)
|
||||
glhelpers.SetUniformVec4f(glProgram, "material.color", m.Color)
|
||||
glshader.SetUniformFloat(glProgram, "material.shininess", m.Shininess)
|
||||
glshader.SetUniformVec4f(glProgram, "material.color", m.Color)
|
||||
|
||||
var tOn int32 = 0
|
||||
if m.TextureOn {
|
||||
tOn = 1
|
||||
}
|
||||
glhelpers.SetUniformInt(glProgram, "material.textureOn", tOn)
|
||||
glshader.SetUniformInt(glProgram, "material.textureOn", tOn)
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package globjects
|
||||
package globject
|
||||
|
||||
import (
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/glhelpers"
|
||||
"gitea.wisellama.rocks/Wisellama/carpy-breakout/pkg/glshader"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
)
|
||||
|
||||
|
@ -26,8 +26,8 @@ func NewPointLight(position mgl32.Vec3) *PointLight {
|
|||
}
|
||||
|
||||
func (l *PointLight) GLInit(glProgram uint32) {
|
||||
glhelpers.SetUniformVec3f(glProgram, "light.position", l.Position)
|
||||
glhelpers.SetUniformVec4f(glProgram, "light.ambient", l.AmbientColor)
|
||||
glhelpers.SetUniformVec4f(glProgram, "light.diffuse", l.DiffuseColor)
|
||||
glhelpers.SetUniformVec4f(glProgram, "light.specular", l.SpecularColor)
|
||||
glshader.SetUniformVec3f(glProgram, "light.position", l.Position)
|
||||
glshader.SetUniformVec4f(glProgram, "light.ambient", l.AmbientColor)
|
||||
glshader.SetUniformVec4f(glProgram, "light.diffuse", l.DiffuseColor)
|
||||
glshader.SetUniformVec4f(glProgram, "light.specular", l.SpecularColor)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package globjects
|
||||
package globject
|
||||
|
||||
type Triangle struct {
|
||||
Vertices []*Vertex
|
|
@ -1,4 +1,4 @@
|
|||
package globjects
|
||||
package globject
|
||||
|
||||
import (
|
||||
"github.com/go-gl/mathgl/mgl32"
|
|
@ -1,5 +0,0 @@
|
|||
# globjects
|
||||
|
||||
This package contains things that can be drawn with OpenGL along with
|
||||
any helpers. Effectively, anything in here should implement the
|
||||
GLObject interface.
|
|
@ -1,109 +0,0 @@
|
|||
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
|
||||
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package globjects
|
||||
|
||||
type GLObject interface {
|
||||
Update()
|
||||
GLDraw()
|
||||
GLInit(glProgram uint32)
|
||||
ToggleWireframe()
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package glhelpers
|
||||
package glshader
|
||||
|
||||
var FragmentShaderSource string = `
|
||||
#version 330
|
|
@ -1,4 +1,4 @@
|
|||
package glhelpers
|
||||
package glshader
|
||||
|
||||
// https://github.com/go-gl/example
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package glhelpers
|
||||
package glshader
|
||||
|
||||
// Adapted from the OpenGL Superbible
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package mathhelpers
|
||||
package math
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
@ -51,3 +51,13 @@ func Absf32(a float32) float32 {
|
|||
|
||||
return a
|
||||
}
|
||||
|
||||
func AbsVec3(v mgl32.Vec3) mgl32.Vec3 {
|
||||
output := mgl32.Vec3{
|
||||
Absf32(v[0]),
|
||||
Absf32(v[1]),
|
||||
Absf32(v[2]),
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
Loading…
Reference in New Issue