class Window(LogExperiment): ''' Generic stereo window ''' status = dict(draw=dict(stop=None)) state = "draw" stop = False window_size = traits.Tuple((1920 * 2, 1080), descr='window size, in pixels') # window_size = (1920*2, 1080) background = (0, 0, 0, 1) #Screen parameters, all in centimeters -- adjust for monkey fov = np.degrees(np.arctan(14.65 / (44.5 + 3))) * 2 screen_dist = 44.5 + 3 iod = 2.5 # intraocular distance show_environment = traits.Int(0) def __init__(self, *args, **kwargs): super(Window, self).__init__(*args, **kwargs) self.models = [] self.world = None self.event = None # os.popen('sudo vbetool dpms on') if self.show_environment: self.add_model(Box()) def set_os_params(self): os.environ['SDL_VIDEO_WINDOW_POS'] = config.display_start_pos os.environ['SDL_VIDEO_X11_WMCLASS'] = "monkey_experiment" def screen_init(self): self.set_os_params() pygame.init() pygame.display.gl_set_attribute(pygame.GL_DEPTH_SIZE, 24) flags = pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.OPENGL | pygame.NOFRAME try: pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLEBUFFERS, 1) self.surf = pygame.display.set_mode(self.window_size, flags) except: pygame.display.gl_set_attribute(pygame.GL_MULTISAMPLEBUFFERS, 0) self.surf = pygame.display.set_mode(self.window_size, flags) glEnable(GL_BLEND) glDepthFunc(GL_LESS) glEnable(GL_DEPTH_TEST) glEnable(GL_TEXTURE_2D) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glClearColor(*self.background) glClearDepth(1.0) glDepthMask(GL_TRUE) self.renderer = self._get_renderer() #this effectively determines the modelview matrix self.world = Group(self.models) self.world.init() #up vector is always (0,0,1), why would I ever need to roll the camera?! self.set_eye((0, -self.screen_dist, 0), (0, 0)) def _get_renderer(self): near = 1 far = 1024 return stereo.MirrorDisplay(self.window_size, self.fov, near, far, self.screen_dist, self.iod) def set_eye(self, pos, vec, reset=True): '''Set the eye's position and direction. Camera starts at (0,0,0), pointing towards positive y''' self.world.translate(pos[0], pos[2], pos[1], reset=True).rotate_x(-90) self.world.rotate_y(vec[0]).rotate_x(vec[1]) def add_model(self, model): if self.world is None: #world doesn't exist yet, add the model to cache self.models.append(model) else: #We're already running, initialize the model and add it to the world model.init() self.world.add(model) def show_object(self, obj, show=False): ''' Show or hide an object. This function is an abstraction so that tasks don't need to know about attach/detach ''' if show: obj.attach() else: obj.detach() def draw_world(self): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) self.renderer.draw(self.world) pygame.display.flip() self.renderer.draw_done() def _get_event(self): for e in pygame.event.get(pygame.KEYDOWN): return (e.key, e.type) def _start_None(self): pygame.display.quit() def _test_stop(self, ts): ''' Stop the task if the escape key is pressed, or if the super _test_stop instructs a stop ''' super_stop = super(Window, self)._test_stop(ts) from pygame import K_ESCAPE return super_stop or self.event is not None and self.event[ 0] == K_ESCAPE def requeue(self): self.renderer._queue_render(self.world) def _cycle(self): self.requeue() self.draw_world() super(Window, self)._cycle() self.event = self._get_event()