123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- 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
|