Created
June 8, 2014 10:19
-
-
Save mr-linch/f6dacd2a069887a47fbc to your computer and use it in GitHub Desktop.
First person camera for pyglet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import math | |
import collections | |
import pyglet | |
class FirstPersonCamera(object): | |
"""First person camera implementation | |
Usage: | |
import pyglet | |
from pyglet.gl import * | |
from camera import FirstPersonCamera | |
window = pyglet.window.Window(fullscreen=True) | |
window.set_exclusive_mouse(True) | |
camera = FirstPersonCamera(window) | |
@window.event | |
def on_draw(): | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) | |
glLoadIdentity() | |
camera.draw() | |
# Your draw code here | |
return pyglet.event.EVENT_HANDLED | |
def on_update(delta_time): | |
camera.update(delta_time) | |
# Your update code here | |
if __name__ == '__main__': | |
pyglet.clock.schedule(on_update) | |
pyglet.app.run() | |
""" | |
DEFAULT_MOVEMENT_SPEED = 10.0 | |
DEFAULT_MOUSE_SENSITIVITY = 0.25 | |
DEFAULT_KEY_MAP = { | |
'forward': pyglet.window.key.W, | |
'backward': pyglet.window.key.S, | |
'left': pyglet.window.key.A, | |
'right': pyglet.window.key.D, | |
'up': pyglet.window.key.SPACE, | |
'down': pyglet.window.key.LSHIFT | |
} | |
class InputHandler(object): | |
def __init__(self): | |
self.pressed = collections.defaultdict(bool) | |
self.dx = 0 | |
self.dy = 0 | |
def on_key_press(self, symbol, modifiers): | |
self.pressed[symbol] = True | |
def on_key_release(self, symbol, modifiers): | |
self.pressed[symbol] = False | |
def on_mouse_motion(self, x, y, dx, dy): | |
self.dx = dx | |
self.dy = dy | |
def __init__(self, window, position=(0, 0, 0), key_map=DEFAULT_KEY_MAP, movement_speed=DEFAULT_MOVEMENT_SPEED, mouse_sensitivity=DEFAULT_MOUSE_SENSITIVITY, y_inv=True): | |
"""Create camera object | |
Arguments: | |
window -- pyglet window which camera attach | |
position -- position of camera | |
key_map -- dict like FirstPersonCamera.DEFAULT_KEY_MAP | |
movement_speed -- speed of camera move (scalar) | |
mouse_sensitivity -- sensitivity of mouse (scalar) | |
y_inv -- inversion turn above y-axis | |
""" | |
self.__position = list(position) | |
self.__yaw = 0.0 | |
self.__pitch = 0.0 | |
self.__input_handler = FirstPersonCamera.InputHandler() | |
window.push_handlers(self.__input_handler) | |
self.y_inv = y_inv | |
self.key_map = key_map | |
self.movement_speed = movement_speed | |
self.mouse_sensitivity = mouse_sensitivity | |
def yaw(self, yaw): | |
"""Turn above x-axis""" | |
self.__yaw += yaw * self.mouse_sensitivity | |
def pitch(self, pitch): | |
"""Turn above y-axis""" | |
self.__pitch += pitch * self.mouse_sensitivity * ((-1) if self.y_inv else 1) | |
def move_forward(self, distance): | |
"""Move forward on distance""" | |
self.__position[0] -= distance * math.sin(math.radians(self.__yaw)) | |
self.__position[2] += distance * math.cos(math.radians(self.__yaw)) | |
def move_backward(self, distance): | |
"""Move backward on distance""" | |
self.__position[0] += distance * math.sin(math.radians(self.__yaw)) | |
self.__position[2] -= distance * math.cos(math.radians(self.__yaw)) | |
def move_left(self, distance): | |
"""Move left on distance""" | |
self.__position[0] -= distance * math.sin(math.radians(self.__yaw - 90)) | |
self.__position[2] += distance * math.cos(math.radians(self.__yaw - 90)) | |
def move_right(self, distance): | |
"""Move right on distance""" | |
self.__position[0] -= distance * math.sin(math.radians(self.__yaw + 90)) | |
self.__position[2] += distance * math.cos(math.radians(self.__yaw + 90)) | |
def move_up(self, distance): | |
"""Move up on distance""" | |
self.__position[1] -= distance | |
def move_down(self, distance): | |
"""Move down on distance""" | |
self.__position[1] += distance | |
def update(self, delta_time): | |
"""Update camera state""" | |
self.yaw(self.__input_handler.dx) | |
self.__input_handler.dx = 0 | |
self.pitch(self.__input_handler.dy) | |
self.__input_handler.dy = 0 | |
if self.__input_handler.pressed[self.key_map['forward']]: | |
self.move_forward(delta_time * self.movement_speed) | |
if self.__input_handler.pressed[self.key_map['backward']]: | |
self.move_backward(delta_time * self.movement_speed) | |
if self.__input_handler.pressed[self.key_map['left']]: | |
self.move_left(delta_time * self.movement_speed) | |
if self.__input_handler.pressed[self.key_map['right']]: | |
self.move_right(delta_time * self.movement_speed) | |
if self.__input_handler.pressed[self.key_map['up']]: | |
self.move_up(delta_time * self.movement_speed) | |
if self.__input_handler.pressed[self.key_map['down']]: | |
self.move_down(delta_time * self.movement_speed) | |
def draw(self): | |
"""Apply transform""" | |
pyglet.gl.glRotatef(self.__pitch, 1.0, 0.0, 0.0) | |
pyglet.gl.glRotatef(self.__yaw, 0.0, 1.0, 0.0) | |
pyglet.gl.glTranslatef(*self.__position) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment