aboutsummaryrefslogtreecommitdiff
path: root/boltzgas/visual/camera.py
blob: 44831f499370c37c39d040ed690d9d17c42330fd (plain)
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
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