Spaces:
Sleeping
Sleeping
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 = { | |
# Rotation around the view Y (up) vector | |
'left': False, | |
'right': False, | |
# Rotation around the view X vector | |
'up': False, | |
'down': False, | |
# Rotation around the view Z vector | |
'spin_left': False, | |
'spin_right': False, | |
# Rotation around the model Z vector | |
'rotate_z_neg': False, | |
'rotate_z_pos': False, | |
# Reset to the default rotation | |
'reset_camera': False, | |
# Performs camera z-translation | |
'zoom_in': False, | |
'zoom_out': False, | |
# Use alternative sensitivity (speed) | |
'modify_sensitivity': False, | |
# Rotation presets | |
'rot_preset_xy': False, | |
'rot_preset_xz': False, | |
'rot_preset_yz': False, | |
'rot_preset_perspective': False, | |
# axes | |
'toggle_axes': False, | |
'toggle_axe_colors': False, | |
# screenshot | |
'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 | |