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 }