from OpenGL.GL import * from OpenGL.GLUT import * from interacticle.visual import View import numpy as np class SimulationController: def __init__(self, simulation, instruments, steps_per_frame): self.running = False self.simulation = simulation self.instruments = instruments self.steps_per_frame = steps_per_frame def isRunning(self): return self.running def run(self): self.running = True def pause(self): self.running = False def evolve(self): if self.running: for i in range(0,self.steps_per_frame): self.simulation.evolve() for instrument in self.instruments: instrument.update() def shutdown(self): self.pause() for instrument in self.instruments: instrument.shutdown() def make_display_handler(view): def on_display(): view.display() return on_display def make_reshape_handler(view): def on_reshape(width, height): view.reshape(width, height) return on_reshape def make_timer(controller): def on_timer(t): glutTimerFunc(t, on_timer, t) controller.evolve() glutPostRedisplay() return on_timer def make_keyboard_handler(controller, view): def on_keyboard(key, x, y): if key == b' ': if controller.isRunning(): controller.pause() else: controller.run() if key == b'1': view.show_decorations = not view.show_decorations if key == b'2': view.show_windows = not view.show_windows return on_keyboard def make_close_handler(controller): def on_close(): controller.shutdown() return on_close def simulate(config, simulation, instruments, steps_per_frame = 50): glutInit() glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH) glutInitWindowPosition(0, 0) glutCreateWindow("MolDyn") simulation.setup() for instrument in instruments: instrument.setup() view = View(simulation, instruments) controller = SimulationController(simulation, instruments, steps_per_frame) glutDisplayFunc(make_display_handler(view)) glutReshapeFunc(make_reshape_handler(view)) glutTimerFunc(20, make_timer(controller), 20) glutKeyboardFunc(make_keyboard_handler(controller, view)) glutCloseFunc(make_close_handler(controller)) glutMouseFunc(lambda *args: list(map(lambda m: m.on_mouse(*args), view.mouse_monitors))) glutMotionFunc(lambda *args: list(map(lambda m: m.on_mouse_move(*args), view.mouse_monitors))) glutMainLoop()