-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcamera.py
107 lines (85 loc) · 2.83 KB
/
camera.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import glm
from math import cos, sin, radians
import pyglet
from pyglet.math import Mat4, Vec3, clamp
from pyglet.window import key
import weakref
SENSITIVITY = 0.3
class FPSCamera:
def __init__(
self, window,
position=Vec3(0, 0, 0),
target=Vec3(0, 0, -1),
up=Vec3(0, 1, 0),
pitch=130,
yaw=-137
):
self.position = position
self.target = target
self.up = up
self.speed = 30
# TODO: calculate these values from the passed Vectors
self.pitch = pitch
self.yaw = yaw
self.input_map = {
key.W: "forward",
key.S: "backward",
key.A: "left",
key.D: "right",
}
self.forward = False
self.backward = False
self.left = False
self.right = False
self._window = weakref.proxy(window)
self._window.view = Mat4.look_at(position, target, up)
self._window.push_handlers(self)
def on_resize(self, width, height):
self._window.viewport = (0, 0, *self._window.get_framebuffer_size())
self._window.projection = Mat4.perspective_projection(
self._window.aspect_ratio, z_near=0.1, z_far=1000, fov=45
)
return pyglet.event.EVENT_HANDLED
def on_refresh(self, dt):
# Movement
speed = self.speed * dt
if self.forward:
self.position += (self.target * speed)
if self.backward:
self.position -= (self.target * speed)
if self.left:
self.position -= (self.target.cross(self.up).normalize() * speed)
if self.right:
self.position += (self.target.cross(self.up).normalize() * speed)
# Look
phi = radians(self.yaw)
theta = radians(self.pitch)
self.target = Vec3(
sin(theta) * cos(phi),
cos(theta),
sin(theta) * sin(phi)
)
eye = glm.vec3(*self.position)
center = glm.vec3(*(self.position + self.target))
up = glm.vec3(*self.up)
l = []
m = glm.lookAt(eye, center, up)
for c in m:
l.extend(c)
self._window.view = tuple(l)
# Mouse input
def on_mouse_motion(self, x, y, dx, dy):
pass
def on_mouse_drag(self, x, y, dx, dy, buttons, mod):
self.yaw += dx * SENSITIVITY
self.pitch = clamp(self.pitch - dy * SENSITIVITY, 0, 189.0)
# Keyboard input
def on_key_press(self, symbol, mod):
if symbol in self.input_map:
setattr(self, self.input_map[symbol], True)
elif symbol == key.P:
print(f"position: {self.position}")
print(f"pitch: {self.pitch}, yaw: {self.yaw}")
def on_key_release(self, symbol, mod):
if symbol in self.input_map:
setattr(self, self.input_map[symbol], False)