from libs import * import camera import entity def reshape(w, h): glViewport(0, 0, w, h) return (w, h) class InteractiveCamera(camera.Camera): def __init__(self, **kwargs): super().__init__(**kwargs) self.sensitivity = kwargs.get("sensitivity", 0.005) self.rv = vec([0, 0, 0]) self.speed = kwargs.get("speed", 0.05) self.hud = { "crosshair": entity.Entity( [[-0.03, 0.0, 0.0], [0.03, 0.0, 0.0], [0.0, -0.03, 0.0], [0.0, 0.03, 0.0]], [1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0], mode=GL_LINES, hud=True ) } def set_focus(self, f): pygame.event.set_grab(f) pygame.mouse.set_visible(not f) pygame.mouse.set_pos([self.viewport[0] / 2, self.viewport[1] / 2]) self.hud["crosshair"].pos[0] = 2 * (not f) def get_focus(self): return not pygame.mouse.get_visible() def mouse_move(self, dx, dy): self.theta = (self.theta - self.sensitivity * dx) % (2 * np.pi) self.phi = min(np.pi / 2, max(-np.pi / 2, self.phi + self.sensitivity * dy)) def update_motion(self, pk): self.rv = vec([pk[a] - pk[b] for (a, b) in zip(ARROWS[::2], ARROWS[1::2])]) def vdof(self): l = self.looking() l[1] = 0 u = self.up() return vec([normalise(np.cross(l, u)), u, normalise(l)]) def update_pos(self): self.pos += self.speed * self.vdof() @ self.rv.T def handle_event(self, ev, mg): match ev.type: case pygame.KEYUP | pygame.KEYDOWN if ev.key in ARROWS: self.update_motion(pygame.key.get_pressed(), mg) case pygame.MOUSEMOTION if self.get_focus(): self.mouse_move(ev.rel[0], -ev.rel[1]) case pygame.WINDOWSIZECHANGED | pygame.WINDOWRESIZED: self.viewport = reshape(ev.x, ev.y) def draw_hud(self, wrs, perf): for ent in self.hud.values(): self.draw(ent)