opengl-deferred/utils/fpscontrols/fpscontrols.go

143 lines
2.7 KiB
Go
Raw Normal View History

2024-10-12 16:25:54 +00:00
package fpscontrols
import (
2024-10-15 14:52:21 +00:00
"math"
2024-10-12 16:25:54 +00:00
"github.com/go-gl/glfw/v3.3/glfw"
"github.com/go-gl/mathgl/mgl32"
)
type FPSControls struct {
lookSpeed float32
moveSpeed float32
position mgl32.Vec3
rotation mgl32.Vec2
lastMousePos mgl32.Vec2
2024-10-15 14:52:21 +00:00
view mgl32.Mat4
2024-12-16 12:23:34 +00:00
window *glfw.Window
2024-10-15 14:52:21 +00:00
lastTime float64
2024-10-12 16:25:54 +00:00
}
var instance *FPSControls
2024-10-15 14:52:21 +00:00
func (c *FPSControls) Update() {
time := glfw.GetTime()
2024-12-16 12:23:34 +00:00
var deltaTime float32 = float32(time - c.lastTime)
2024-10-15 14:52:21 +00:00
c.lastTime = time
2024-12-16 12:23:34 +00:00
_, right, _ := c.directions()
2024-10-15 14:52:21 +00:00
globalUp := mgl32.Vec3{0, 1, 0}
2024-12-16 12:23:34 +00:00
move := mgl32.Vec3{0, 0, 0}
if c.window.GetKey(glfw.KeyA) == glfw.Press {
move[0] += 1
}
if c.window.GetKey(glfw.KeyD) == glfw.Press {
move[0] -= 1
}
if c.window.GetKey(glfw.KeySpace) == glfw.Press {
move[1] += 1
}
if c.window.GetKey(glfw.KeyLeftShift) == glfw.Press {
move[1] -= 1
}
if c.window.GetKey(glfw.KeyW) == glfw.Press {
move[2] += 1
}
if c.window.GetKey(glfw.KeyS) == glfw.Press {
move[2] -= 1
}
move = right.Mul(move.X()).Add(globalUp.Mul(move.Y())).Add(right.Cross(globalUp).Mul(move.Z()))
c.position = c.position.Add(move.Mul(deltaTime * c.moveSpeed))
2024-10-15 14:52:21 +00:00
2024-12-16 12:23:34 +00:00
x, y := c.window.GetCursorPos()
look := mgl32.Vec2{
float32(y) - c.lastMousePos.X(),
c.lastMousePos.Y() - float32(x),
}.Mul(deltaTime * c.lookSpeed)
c.rotation = c.rotation.Add(look)
c.rotation = mgl32.Vec2{
min(max(-89.9, c.rotation.X()), 89.9),
float32(int32(c.rotation.Y())%360) + c.rotation.Y() - float32(int32(c.rotation.Y())),
}
c.lastMousePos[0] = float32(y)
c.lastMousePos[1] = float32(x)
forward, _, _ := c.directions()
c.view = mgl32.LookAtV(c.position, c.position.Add(forward), globalUp)
2024-10-15 14:52:21 +00:00
}
2024-10-12 16:25:54 +00:00
func Get(lookSpeed, moveSpeed float32, position mgl32.Vec3, rotation mgl32.Vec2, window *glfw.Window) *FPSControls {
if instance != nil {
return instance
}
instance = &FPSControls{
moveSpeed: moveSpeed,
lookSpeed: lookSpeed,
position: position,
rotation: rotation,
2024-12-16 12:23:34 +00:00
window: window,
2024-10-12 16:25:54 +00:00
}
2024-10-15 14:52:21 +00:00
window.SetInputMode(glfw.CursorMode, glfw.CursorDisabled)
2024-10-12 16:25:54 +00:00
return instance
}
2024-10-15 14:52:21 +00:00
func (c *FPSControls) directions() (mgl32.Vec3, mgl32.Vec3, mgl32.Vec3) {
rad := mgl32.Vec2{
mgl32.DegToRad(c.rotation.X()),
mgl32.DegToRad(c.rotation.Y()),
}
sin := mgl32.Vec2{
float32(math.Sin(float64(rad.X()))),
float32(math.Sin(float64(rad.Y()))),
}
cos := mgl32.Vec2{
float32(math.Cos(float64(rad.X()))),
float32(math.Cos(float64(rad.Y()))),
}
forward := mgl32.Vec3{
cos.X() * sin.Y(),
-sin.X(),
cos.X() * cos.Y(),
}
right := mgl32.Vec3{
cos.Y(),
0,
-sin.Y(),
}
2024-10-12 16:25:54 +00:00
2024-10-15 14:52:21 +00:00
up := forward.Cross(right)
return forward, right, up
2024-10-12 16:25:54 +00:00
}
func (c *FPSControls) View() mgl32.Mat4 {
2024-10-15 14:52:21 +00:00
return c.view
}
func (c *FPSControls) Position() mgl32.Vec3 {
return c.position
}
2024-10-12 16:25:54 +00:00
2024-10-15 14:52:21 +00:00
func (c *FPSControls) Rotation() mgl32.Vec2 {
return c.rotation
2024-10-12 16:25:54 +00:00
}