tofu

Making something with OpenGL in Go
Log | Files | Refs

camera.go (2211B)


      1 package tofu
      2 
      3 import (
      4 	"math"
      5 )
      6 
      7 type Camera struct {
      8 	Pos, Front, Up, Right Vec3
      9 	Yaw, Pitch            float32
     10 }
     11 
     12 func NewCamera() *Camera {
     13 	return &Camera{
     14 		Pos:   Vec3{0, 0, 0},
     15 		Front: Vec3{0, 0, 1},
     16 		Up:    Vec3{0, 1, 0},
     17 		Right: Vec3{1, 0, 0},
     18 		Yaw:   -math.Pi / 2,
     19 		Pitch: 0,
     20 	}
     21 }
     22 
     23 func (cam *Camera) MoveTo(target Vec3) {
     24 	cam.Pos = target
     25 }
     26 
     27 func (cam *Camera) Move(right, up, back float32) {
     28 	cam.Pos = cam.Pos.Add(cam.Right.MulF(right)).
     29 		Add(cam.Up.MulF(up)).
     30 		Add(cam.Front.MulF(-back))
     31 }
     32 
     33 func (cam *Camera) Move2(right, back float32) {
     34 	f := Vec3{float32(math.Cos(float64(cam.Yaw))),
     35 		0,
     36 		float32(math.Sin(float64(cam.Yaw)))}
     37 	r := Vec3{-float32(math.Sin(float64(cam.Yaw))),
     38 		0,
     39 		float32(math.Cos(float64(cam.Yaw)))}
     40 	cam.Pos = cam.Pos.Add(r.MulF(right)).
     41 		Add(f.MulF(-back))
     42 }
     43 
     44 func (cam *Camera) MoveVert(up float32) {
     45 	cam.Pos = cam.Pos.Add(Vec3{0, 1, 0}.MulF(up))
     46 }
     47 
     48 // TODO: name
     49 func (cam *Camera) YawPitch(dy, dp float32) {
     50 	const eps = 0.0000001
     51 	cam.Yaw -= dy
     52 	cam.Pitch -= dp
     53 	if cam.Pitch > math.Pi/2 {
     54 		cam.Pitch = math.Pi/2 - eps
     55 	} else if cam.Pitch < -math.Pi/2 {
     56 		cam.Pitch = -math.Pi/2 + eps
     57 	}
     58 	y, p := float64(cam.Yaw), float64(cam.Pitch)
     59 	cam.Front[0] = float32(math.Cos(y) * math.Cos(p))
     60 	cam.Front[1] = float32(math.Sin(p))
     61 	cam.Front[2] = float32(math.Sin(y) * math.Cos(p))
     62 	cam.Front = cam.Front.Normalize()
     63 	cam.Right = cam.Front.Cross(Vec3{0, 1, 0}).Normalize()
     64 	cam.Up = cam.Right.Cross(cam.Front).Normalize()
     65 }
     66 
     67 func (cam *Camera) AddYaw(delta float32) {
     68 	cam.Yaw += delta
     69 	rot := Rotate3(delta, cam.Up)
     70 	cam.Front = rot.MulV(cam.Front)
     71 	cam.Right = rot.MulV(cam.Right)
     72 }
     73 
     74 func (cam *Camera) AddPitch(delta float32) {
     75 	cam.Pitch += delta
     76 	rot := Rotate3(-delta, cam.Right)
     77 	cam.Front = rot.MulV(cam.Front)
     78 	cam.Up = rot.MulV(cam.Up)
     79 }
     80 
     81 func (cam *Camera) LookAt(target Vec3) {
     82 	// TODO: update Yaw and Pitch
     83 	cam.Front = target.Sub(cam.Pos).Normalize()
     84 	cam.Right = cam.Up.Cross(cam.Front.Inverse()).Normalize()
     85 }
     86 
     87 func (cam *Camera) View() Mat4 {
     88 	return Mat4{
     89 		cam.Right[0], cam.Up[0], -cam.Front[0], 0,
     90 		cam.Right[1], cam.Up[1], -cam.Front[1], 0,
     91 		cam.Right[2], cam.Up[2], -cam.Front[2], 0,
     92 		0, 0, 0, 1,
     93 	}.Mul(Translate(cam.Pos.Inverse()))
     94 }