diff options
Diffstat (limited to 'boltzgas/visual/camera.py')
-rw-r--r-- | boltzgas/visual/camera.py | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/boltzgas/visual/camera.py b/boltzgas/visual/camera.py new file mode 100644 index 0000000..44831f4 --- /dev/null +++ b/boltzgas/visual/camera.py @@ -0,0 +1,106 @@ +from OpenGL.GL import * +from OpenGL.GLUT import * + +from pyrr import matrix44, quaternion + +import numpy as np + +class Projection: + def __init__(self, distance): + self.distance = distance + self.ratio = 4./3. + self.x = 0 + self.y = 0 + self.update() + + def update(self): + projection = matrix44.create_perspective_projection(20.0, self.ratio, 0.1, 5000.0) + look = matrix44.create_look_at( + eye = [self.x, -self.distance, self.y], + target = [self.x, 0, self.y], + up = [0, 0,-1]) + + self.matrix = np.matmul(look, projection) + + def update_ratio(self, width, height, update_viewport = True): + if update_viewport: + glViewport(0,0,width,height) + + self.ratio = width/height + self.update() + + def update_distance(self, change): + self.distance += change + self.update() + + def shift(self, x, y): + self.x -= x + self.y -= y + self.update() + + def get(self): + return self.matrix + +class Rotation: + def __init__(self, shift, x = np.pi, z = np.pi): + self.matrix = matrix44.create_from_translation(shift), + self.rotation_x = quaternion.Quaternion() + self.update(x,z) + + def shift(self, x, z): + self.matrix = np.matmul( + self.matrix, + matrix44.create_from_translation([x,0,z]) + ) + self.inverse_matrix = np.linalg.inv(self.matrix) + + def update(self, x, z): + rotation_x = quaternion.Quaternion(quaternion.create_from_eulers([x,0,0])) + rotation_z = self.rotation_x.conjugate.cross( + quaternion.Quaternion(quaternion.create_from_eulers([0,0,z]))) + self.rotation_x = self.rotation_x.cross(rotation_x) + + self.matrix = np.matmul( + self.matrix, + matrix44.create_from_quaternion(rotation_z.cross(self.rotation_x)) + ) + self.inverse_matrix = np.linalg.inv(self.matrix) + + def get(self): + return self.matrix + + def get_inverse(self): + return self.inverse_matrix + +class MouseDragMonitor: + def __init__(self, button, callback): + self.button = button + self.active = False + self.callback = callback + + def on_mouse(self, button, state, x, y): + if button == self.button: + self.active = (state == GLUT_DOWN) + self.last_x = x + self.last_y = y + + def on_mouse_move(self, x, y): + if self.active: + delta_x = self.last_x - x + delta_y = y - self.last_y + self.last_x = x + self.last_y = y + self.callback(delta_x, delta_y) + +class MouseScrollMonitor: + def __init__(self, callback): + self.callback = callback + + def on_mouse(self, button, state, x, y): + if button == 3: + self.callback(-1.0) + elif button == 4: + self.callback(1.0) + + def on_mouse_move(self, x, y): + pass |