|
from pyglet.window import key |
|
from pyglet.window.mouse import LEFT, RIGHT, MIDDLE |
|
from sympy.plotting.pygletplot.util import get_direction_vectors, get_basis_vectors |
|
|
|
|
|
class PlotController: |
|
|
|
normal_mouse_sensitivity = 4.0 |
|
modified_mouse_sensitivity = 1.0 |
|
|
|
normal_key_sensitivity = 160.0 |
|
modified_key_sensitivity = 40.0 |
|
|
|
keymap = { |
|
key.LEFT: 'left', |
|
key.A: 'left', |
|
key.NUM_4: 'left', |
|
|
|
key.RIGHT: 'right', |
|
key.D: 'right', |
|
key.NUM_6: 'right', |
|
|
|
key.UP: 'up', |
|
key.W: 'up', |
|
key.NUM_8: 'up', |
|
|
|
key.DOWN: 'down', |
|
key.S: 'down', |
|
key.NUM_2: 'down', |
|
|
|
key.Z: 'rotate_z_neg', |
|
key.NUM_1: 'rotate_z_neg', |
|
|
|
key.C: 'rotate_z_pos', |
|
key.NUM_3: 'rotate_z_pos', |
|
|
|
key.Q: 'spin_left', |
|
key.NUM_7: 'spin_left', |
|
key.E: 'spin_right', |
|
key.NUM_9: 'spin_right', |
|
|
|
key.X: 'reset_camera', |
|
key.NUM_5: 'reset_camera', |
|
|
|
key.NUM_ADD: 'zoom_in', |
|
key.PAGEUP: 'zoom_in', |
|
key.R: 'zoom_in', |
|
|
|
key.NUM_SUBTRACT: 'zoom_out', |
|
key.PAGEDOWN: 'zoom_out', |
|
key.F: 'zoom_out', |
|
|
|
key.RSHIFT: 'modify_sensitivity', |
|
key.LSHIFT: 'modify_sensitivity', |
|
|
|
key.F1: 'rot_preset_xy', |
|
key.F2: 'rot_preset_xz', |
|
key.F3: 'rot_preset_yz', |
|
key.F4: 'rot_preset_perspective', |
|
|
|
key.F5: 'toggle_axes', |
|
key.F6: 'toggle_axe_colors', |
|
|
|
key.F8: 'save_image' |
|
} |
|
|
|
def __init__(self, window, *, invert_mouse_zoom=False, **kwargs): |
|
self.invert_mouse_zoom = invert_mouse_zoom |
|
self.window = window |
|
self.camera = window.camera |
|
self.action = { |
|
|
|
'left': False, |
|
'right': False, |
|
|
|
'up': False, |
|
'down': False, |
|
|
|
'spin_left': False, |
|
'spin_right': False, |
|
|
|
'rotate_z_neg': False, |
|
'rotate_z_pos': False, |
|
|
|
'reset_camera': False, |
|
|
|
'zoom_in': False, |
|
'zoom_out': False, |
|
|
|
'modify_sensitivity': False, |
|
|
|
'rot_preset_xy': False, |
|
'rot_preset_xz': False, |
|
'rot_preset_yz': False, |
|
'rot_preset_perspective': False, |
|
|
|
'toggle_axes': False, |
|
'toggle_axe_colors': False, |
|
|
|
'save_image': False |
|
} |
|
|
|
def update(self, dt): |
|
z = 0 |
|
if self.action['zoom_out']: |
|
z -= 1 |
|
if self.action['zoom_in']: |
|
z += 1 |
|
if z != 0: |
|
self.camera.zoom_relative(z/10.0, self.get_key_sensitivity()/10.0) |
|
|
|
dx, dy, dz = 0, 0, 0 |
|
if self.action['left']: |
|
dx -= 1 |
|
if self.action['right']: |
|
dx += 1 |
|
if self.action['up']: |
|
dy -= 1 |
|
if self.action['down']: |
|
dy += 1 |
|
if self.action['spin_left']: |
|
dz += 1 |
|
if self.action['spin_right']: |
|
dz -= 1 |
|
|
|
if not self.is_2D(): |
|
if dx != 0: |
|
self.camera.euler_rotate(dx*dt*self.get_key_sensitivity(), |
|
*(get_direction_vectors()[1])) |
|
if dy != 0: |
|
self.camera.euler_rotate(dy*dt*self.get_key_sensitivity(), |
|
*(get_direction_vectors()[0])) |
|
if dz != 0: |
|
self.camera.euler_rotate(dz*dt*self.get_key_sensitivity(), |
|
*(get_direction_vectors()[2])) |
|
else: |
|
self.camera.mouse_translate(0, 0, dx*dt*self.get_key_sensitivity(), |
|
-dy*dt*self.get_key_sensitivity()) |
|
|
|
rz = 0 |
|
if self.action['rotate_z_neg'] and not self.is_2D(): |
|
rz -= 1 |
|
if self.action['rotate_z_pos'] and not self.is_2D(): |
|
rz += 1 |
|
|
|
if rz != 0: |
|
self.camera.euler_rotate(rz*dt*self.get_key_sensitivity(), |
|
*(get_basis_vectors()[2])) |
|
|
|
if self.action['reset_camera']: |
|
self.camera.reset() |
|
|
|
if self.action['rot_preset_xy']: |
|
self.camera.set_rot_preset('xy') |
|
if self.action['rot_preset_xz']: |
|
self.camera.set_rot_preset('xz') |
|
if self.action['rot_preset_yz']: |
|
self.camera.set_rot_preset('yz') |
|
if self.action['rot_preset_perspective']: |
|
self.camera.set_rot_preset('perspective') |
|
|
|
if self.action['toggle_axes']: |
|
self.action['toggle_axes'] = False |
|
self.camera.axes.toggle_visible() |
|
|
|
if self.action['toggle_axe_colors']: |
|
self.action['toggle_axe_colors'] = False |
|
self.camera.axes.toggle_colors() |
|
|
|
if self.action['save_image']: |
|
self.action['save_image'] = False |
|
self.window.plot.saveimage() |
|
|
|
return True |
|
|
|
def get_mouse_sensitivity(self): |
|
if self.action['modify_sensitivity']: |
|
return self.modified_mouse_sensitivity |
|
else: |
|
return self.normal_mouse_sensitivity |
|
|
|
def get_key_sensitivity(self): |
|
if self.action['modify_sensitivity']: |
|
return self.modified_key_sensitivity |
|
else: |
|
return self.normal_key_sensitivity |
|
|
|
def on_key_press(self, symbol, modifiers): |
|
if symbol in self.keymap: |
|
self.action[self.keymap[symbol]] = True |
|
|
|
def on_key_release(self, symbol, modifiers): |
|
if symbol in self.keymap: |
|
self.action[self.keymap[symbol]] = False |
|
|
|
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers): |
|
if buttons & LEFT: |
|
if self.is_2D(): |
|
self.camera.mouse_translate(x, y, dx, dy) |
|
else: |
|
self.camera.spherical_rotate((x - dx, y - dy), (x, y), |
|
self.get_mouse_sensitivity()) |
|
if buttons & MIDDLE: |
|
self.camera.zoom_relative([1, -1][self.invert_mouse_zoom]*dy, |
|
self.get_mouse_sensitivity()/20.0) |
|
if buttons & RIGHT: |
|
self.camera.mouse_translate(x, y, dx, dy) |
|
|
|
def on_mouse_scroll(self, x, y, dx, dy): |
|
self.camera.zoom_relative([1, -1][self.invert_mouse_zoom]*dy, |
|
self.get_mouse_sensitivity()) |
|
|
|
def is_2D(self): |
|
functions = self.window.plot._functions |
|
for i in functions: |
|
if len(functions[i].i_vars) > 1 or len(functions[i].d_vars) > 2: |
|
return False |
|
return True |
|
|