carpy-breakout/pkg/globject/camera.go

145 lines
3.2 KiB
Go

package globject
import (
"git.wisellama.rocks/Wisellama/carpy-breakout/pkg/glshader"
"github.com/go-gl/mathgl/mgl32"
)
/*
Positive X = right
Positive Y = up
Positive Z = backward (outward, towards you)
Negative Z = forwards (inward)
*/
type Camera struct {
Position mgl32.Vec3
Direction mgl32.Vec3
OriginalDirection mgl32.Vec3
Up mgl32.Vec3
OriginalUp mgl32.Vec3
Velocity mgl32.Vec3
FastMoveVelocity float32
MoveStep float32
RotationVelocity float32
RotateStep float32
MouseSensitivity float32
GLProgram uint32
}
func NewCamera(glProgram uint32) *Camera {
camera := Camera{
Up: mgl32.Vec3{0, 1, 0},
OriginalUp: mgl32.Vec3{0, 1, 0},
Direction: mgl32.Vec3{0, 0, -1},
OriginalDirection: mgl32.Vec3{0, 0, -1},
MoveStep: 0.1,
RotateStep: 0.01,
MouseSensitivity: 0.06,
GLProgram: glProgram,
}
return &camera
}
func (c *Camera) GetCenter() mgl32.Vec3 {
return c.Position.Add(c.Direction)
}
func (c *Camera) GLDraw() {
cameraMatrix := mgl32.LookAtV(c.Position, c.GetCenter(), c.Up)
glshader.SetUniformMatrix4f(c.GLProgram, "camera", &cameraMatrix)
glshader.SetUniformVec3f(c.GLProgram, "cameraPos", c.Position)
}
func (c *Camera) GLInit(glProgram uint32) {
}
func (c *Camera) Update() {
c.Rotate(0, 0, c.RotationVelocity)
c.Move(c.Velocity)
}
func (c *Camera) ToggleWireframe() {
}
func (c *Camera) GetAABB() *AABB {
return nil
}
func (c *Camera) Rotate(mouseX, mouseY int32, velocity float32) {
angle := mgl32.Vec3{}
// X Rotation (pitch) - mouse up/down
angle[0] = -1 * float32(mouseY) * c.MouseSensitivity
// Y Rotation (yaw) - mouse left/right
angle[1] = -1 * float32(mouseX) * c.MouseSensitivity
// Z Rotation (roll) - keyboard z/x
angle[2] = velocity
if angle.LenSqr() == 0 {
return
}
angle = angle.Mul(c.RotateStep)
relativeY := c.Up
relativeZ := c.Direction
relativeX := relativeZ.Cross(relativeY)
quatX := mgl32.QuatRotate(angle.X(), relativeX)
c.Up = quatX.Rotate(c.Up)
c.Direction = quatX.Rotate(c.Direction)
quatY := mgl32.QuatRotate(angle.Y(), relativeY)
c.Up = quatY.Rotate(c.Up)
c.Direction = quatY.Rotate(c.Direction)
quatZ := mgl32.QuatRotate(angle.Z(), relativeZ)
c.Up = quatZ.Rotate(c.Up)
c.Direction = quatZ.Rotate(c.Direction)
}
func (c *Camera) Move(vec mgl32.Vec3) {
if vec.LenSqr() == 0 {
return
}
vec = vec.Normalize()
vec = vec.Mul(c.MoveStep)
if c.FastMoveVelocity != 0 {
vec = vec.Mul(c.FastMoveVelocity)
}
perp := c.Direction.Cross(c.Up)
relativeY := c.Up.Mul(vec.Y())
relativeZ := c.Direction.Mul(vec.Z())
relativeX := perp.Mul(vec.X())
relativeMove := mgl32.Vec3{}
relativeMove = relativeMove.Add(relativeX)
relativeMove = relativeMove.Add(relativeY)
relativeMove = relativeMove.Add(relativeZ)
c.Position = c.Position.Add(relativeMove)
}
func (c *Camera) SetXVelocity(v float32) {
c.Velocity[0] = v
}
func (c *Camera) SetYVelocity(v float32) {
c.Velocity[1] = v
}
func (c *Camera) SetZVelocity(v float32) {
c.Velocity[2] = v
}
func (c *Camera) SetRotationVelocity(v float32) {
c.RotationVelocity = v
}
func (c *Camera) SetFastMoveVelocity(v float32) {
c.FastMoveVelocity = v
}