def open_window(self): if not self._window: self.input = {'down':False, 'mouse':(0,0)} self.trackball = Trackball() # get glfw started glfwInit() self._window = glfwCreateWindow(width, height, self.name, None, None) glfwMakeContextCurrent(self._window) if not self._window: exit() glfwSetWindowPos(self._window,2000,0) # Register callbacks window glfwSetFramebufferSizeCallback(self._window,self.on_resize) glfwSetWindowIconifyCallback(self._window,self.on_iconify) glfwSetKeyCallback(self._window,self.on_key) glfwSetCharCallback(self._window,self.on_char) glfwSetMouseButtonCallback(self._window,self.on_button) glfwSetCursorPosCallback(self._window,self.on_pos) glfwSetScrollCallback(self._window,self.on_scroll) glfwSetWindowCloseCallback(self._window,self.on_close) init() glutInit() self.basic_gl_setup() self.gui = ui.UI() self.on_resize(self._window,*glfwGetFramebufferSize(self._window))
def __init__(self, parent=None): QGLWidget.__init__(self, parent) self.setAutoBufferSwap(False) self.resize(640, 480) self.opengl_thread = QThread() QCoreApplication.instance().aboutToQuit.connect(self.clean_up_before_quit) self.trackball = Trackball() self.preferredSize = None self.setFocusPolicy(Qt.WheelFocus)
def cam0Event(self): if self.trackball is not None: self.glwidget.tb = eval(repr(self.trackball)) # Make a deepcopy return self.glwidget.tb = Trackball(phi=-0.0, theta=0.0, zoom=1.0, rot=[-0.02, -0.71, -0.02, 0.71], trans=[0.02, 0.09, -0.69])
def open_window(self): if not self._window: self.input = {'button':None, 'mouse':(0,0)} self.trackball = Trackball() # get glfw started if self.run_independently: glfwInit() window = glfwGetCurrentContext() self._window = glfwCreateWindow(640, 480, self.name, None, window) glfwMakeContextCurrent(self._window) if not self._window: exit() glfwSetWindowPos(self._window,2000,0) # Register callbacks window glfwSetFramebufferSizeCallback(self._window,self.on_resize) glfwSetWindowIconifyCallback(self._window,self.on_iconify) glfwSetKeyCallback(self._window,self.on_key) glfwSetCharCallback(self._window,self.on_char) glfwSetMouseButtonCallback(self._window,self.on_button) glfwSetCursorPosCallback(self._window,self.on_pos) glfwSetScrollCallback(self._window,self.on_scroll) glfwSetWindowCloseCallback(self._window,self.on_close) # get glfw started if self.run_independently: init() glutInit() self.basic_gl_setup() self.glfont = fs.Context() self.glfont.add_font('opensans',get_opensans_font_path()) self.glfont.set_size(22) self.glfont.set_color_float((0.2,0.5,0.9,1.0)) # self.gui = ui.UI() self.on_resize(self._window,*glfwGetFramebufferSize(self._window))
def __init__(self): ''' Constructor ''' self._initialViewM = np.eye(4,dtype=np.float32) self._viewM = np.copy(self._initialViewM) self.trackball = Trackball() self.keyDict = { ord('r') : self.reset, key.UP: self.up, key.DOWN: self.down, key.LEFT: self.left, key.RIGHT: self.right, ord('w'): self.forward, ord('s'): self.backward, ord('a'): self.left, ord('d'): self.right, ord('q'): self.rollLeft, ord('e'): self.rollRight, ord('z'): self.pitchUp, ord('x'): self.pitchDown, ord('i'): self.info, ord('1'): self.toggleMesh, ord('2'): self.toggleFaces, ord('3'): self.toggleNormals, } self.translateMult = -1.0 self.dragMult = -0.01 self.zoomMult = 0.01 self._zoom = 1.0 self.showMesh = True self.showFaces = False self.showNormals = False
class CinemolCanvas(QGLWidget): # Singleton thread for all OpenGL actions def __init__(self, parent=None): QGLWidget.__init__(self, parent) self.setAutoBufferSwap(False) self.resize(640, 480) self.opengl_thread = QThread() QCoreApplication.instance().aboutToQuit.connect(self.clean_up_before_quit) self.trackball = Trackball() self.preferredSize = None self.setFocusPolicy(Qt.WheelFocus) # delegate opengl tasks to separate non-qt-gui Renderer object def set_gl_renderer(self, renderer): self.renderer = renderer self.renderer.set_gl_widget(self) bUseSeparateOpenGLThread = False if bUseSeparateOpenGLThread: self.renderer.moveToThread(self.opengl_thread) self.opengl_thread.start() self.trackball.rotation_incremented.connect(self.renderer.increment_rotation) self.trackball.zoom_incremented.connect(self.renderer.increment_zoom) self.trackball.pixel_translated.connect(self.renderer.translate_pixel) self.trackball.pixel_centered.connect(self.renderer.center_pixel) def paintEvent(self, event): self.doneCurrent() self.paint_requested.emit() def resizeEvent(self, event): self.doneCurrent() sz = event.size() self.resize_requested.emit(sz.width(), sz.height()) def sizeHint(self): if self.preferredSize is None: return QGLWidget.sizeHint(self) return self.preferredSize @QtCore.Slot(int, int) def special_resize(self, w, h): self.preferredSize = QSize(w, h) self.resize(w, h) @QtCore.Slot() def clean_up_before_quit(self): self.opengl_thread.quit() self.opengl_thread.wait() paint_requested = QtCore.Signal() resize_requested = QtCore.Signal(int, int) save_image_requested = QtCore.Signal(str) save_lenticular_series_requested = QtCore.Signal(str, float, int) def save_image(self, file_name): self.save_image_requested.emit(file_name) def save_lenticular_series(self, file_name, angle, count=18): self.save_lenticular_series_requested.emit(file_name, angle, count) def keyPressEvent(self, event): if event.key() == Qt.Key_Left: r = Rotation().set_from_angle_about_unit_vector(-0.05, [0, 0, -1]) self.trackball.rotation_incremented.emit(r) elif event.key() == Qt.Key_Right: r = Rotation().set_from_angle_about_unit_vector( 0.05, [0, 0, -1]) self.trackball.rotation_incremented.emit(r) elif event.key() == Qt.Key_Up: self.trackball.pixel_translated.emit(0, 0, 50); elif event.key() == Qt.Key_Down: self.trackball.pixel_translated.emit(0, 0, -50); QGLWidget.keyPressEvent(self, event) # not my event # Delegate mouse events to trackball class def mouseMoveEvent(self, event): self.trackball.mouseMoveEvent(event, self.size()) def mousePressEvent(self, event): self.trackball.mousePressEvent(event) def mouseReleaseEvent(self, event): self.trackball.mouseReleaseEvent(event) def mouseDoubleClickEvent(self, event): self.trackball.mouseDoubleClickEvent(event, self.size()) def wheelEvent(self, event): self.trackball.wheelEvent(event)
def run(args): # Command line arguments address = args.address show_window = args.show_window poll_timeout = args.poll_timeout width = args.width height = args.height mesh_filename = args.mesh_filename use_msgpack_for_mesh = args.use_msgpack_for_mesh window_width = args.window_width if window_width is None: window_width = width window_height = args.window_height if window_height is None: window_height = height window_pos_x = args.window_pos_x window_pos_y = args.window_pos_y model_scale = args.model_scale model_rpy = [args.model_roll, args.model_pitch, args.model_yaw] depth_scale = args.depth_scale yaw_speed = args.yaw_speed pitch_speed = args.pitch_speed # Compute vertical field of view (needed for glm.perspective) horz_fov = args.horz_fov focal_length = camera_utils.fov_to_focal_length( math_utils.degrees_to_radians(horz_fov), width) vert_fov = math_utils.radians_to_degrees( camera_utils.focal_length_to_fov(focal_length, height)) logger.info("Horizontal FOV: {:.4f}, vertical FOV: {:.4f}".format( horz_fov, vert_fov)) window_focal_length = camera_utils.fov_to_focal_length( math_utils.degrees_to_radians(horz_fov), window_width) window_vert_fov = math_utils.radians_to_degrees( camera_utils.focal_length_to_fov(window_focal_length, window_height)) logger.info("Window vertical FOV: {:.4f}".format(window_vert_fov)) # Fixed parameters initial_distance = 10 # initial camera distance # Glumpy initialization # glumpy.app.use("glfw") # glumpy.app.use("glfw", 'ES', 3, 3) glumpy_config = glumpy.app.configuration.get_default() glumpy_config.double_buffer = True glumpy_config.samples = 0 glumpy_config.api = "ES" glumpy_config.depth_size = 32 glumpy_config.major_version = 3 glumpy_config.minor_version = 1 glumpy_config.profile = "core" # if show_window: window = Window(width=window_width, height=window_height, fov=window_vert_fov, znear=0.5, zfar=1000, config=glumpy_config, visible=show_window, title=b"mesh_renderer_zmq") trackball = Trackball(pitch=0, yaw=0) window.glumpy_window.attach(trackball) app = Application() logger.info("Glumpy backend: {}".format(glumpy.app.__backend__)) # Process initial events if window_pos_x is not None or window_pos_y is not None: if window_pos_x is None: window_pos_x, _ = window.glumpy_window.get_position() if window_pos_y is None: _, window_pos_y = window.glumpy_window.get_position() window.glumpy_window.set_position(window_pos_x, window_pos_y) # Offscreen surface initialization framebuffer = Framebuffer(width, height, num_color_attachments=3, color_dtypes=[np.ubyte, np.float32, np.float32]) fb_color_drawer = FramebufferDrawer(framebuffer, color_index=0, draw_mode=FramebufferDrawer.BLIT) fb_depth_drawer = FramebufferDrawer(framebuffer, color_index=1, draw_mode=FramebufferDrawer.DRAW_QUAD) fb_depth_drawer.set_color_scale(depth_scale) fb_normal_drawer = FramebufferDrawer(framebuffer, color_index=2, draw_mode=FramebufferDrawer.DRAW_QUAD) fb_normal_drawer.set_color_scale(0.5) fb_normal_drawer.set_color_offset(0.5) # Offscreen surface initialization window_framebuffer = Framebuffer( window_width, window_height, num_color_attachments=3, color_dtypes=[np.ubyte, np.float32, np.float32]) window_fb_color_drawer = FramebufferDrawer( window_framebuffer, color_index=0, draw_mode=FramebufferDrawer.BLIT) window_fb_depth_drawer = FramebufferDrawer( window_framebuffer, color_index=1, draw_mode=FramebufferDrawer.DRAW_QUAD) window_fb_depth_drawer.set_color_scale(depth_scale) window_fb_normal_drawer = FramebufferDrawer( window_framebuffer, color_index=2, draw_mode=FramebufferDrawer.DRAW_QUAD) window_fb_normal_drawer.set_color_scale(0.5) window_fb_normal_drawer.set_color_offset(0.5) # Add framebuffer draw for normals window.add_drawer(window_fb_normal_drawer) # Transformation from world coordinates (z up, x foward, y left) to opengl coordinates (z backward, x right, y up) world_to_opengl_mat = np.eye(4, dtype=np.float32) world_to_opengl_mat = glm.xrotate(world_to_opengl_mat, -90) world_to_opengl_mat = glm.zrotate(world_to_opengl_mat, 90) opengl_to_world_mat = np.linalg.inv(world_to_opengl_mat) # Mesh loading if mesh_filename is not None: mesh = None if use_msgpack_for_mesh: msgpack_mesh_filename = mesh_filename + ".msgpack" if os.path.isfile(msgpack_mesh_filename): logger.info("Loading mesh from msgpack file {}".format( msgpack_mesh_filename)) mesh = SimpleMesh.read_from_msgpack(msgpack_mesh_filename) if mesh is None: logger.info("Loading mesh from file {}".format(mesh_filename)) mesh = SimpleMesh.read_from_file(mesh_filename) if use_msgpack_for_mesh: logger.info("Saving mesh to msgpack file {}".format( msgpack_mesh_filename)) mesh.write_to_msgpack(msgpack_mesh_filename) else: mesh = CubeMesh() logger.info("Setting uniform color") mesh.set_colors_uniform([0.5, 0.5, 0.5, 1]) # logger.info("Computing mesh colors with z-colormap") # mesh.set_colors_with_coordinate_colormap(min_coord=0, max_coord=10) # Drawer initialization # cube_mesh = CubeMesh() # cube_drawer = MeshDrawer(cube_mesh) # cube_drawer.depth_scale = 0.1 # cube_drawer.normal_scale = 0.1 # mesh = SimpleMesh.read_from_ply(sys.argv[1]) # mesh.write_to_pickle("mesh.pickle") # mesh = SimpleMesh.read_from_pickle("mesh2.pickle") # mesh = Mesh.from_file(filename) # mesh_drawer = MeshDrawer(mesh) mesh_drawer = MeshDrawer(mesh) mesh_drawer.transform.scale = model_scale mesh_drawer.transform.orientation_rpy = model_rpy # Assume mesh is in world coordinate system # mesh_drawer.model = np.matmul(np.transpose(world_to_opengl_mat), mesh_drawer.model) # mesh_drawer.color_scale = color_scale # mesh_drawer.normal_scale = normal_scale # mesh_drawer.depth_scale = depth_scale # glm.scale(mesh_drawer.model, 0.01) # cube_drawer = CubeDrawer() # Server initialization logger.info("Starting ZMQ server on address {}".format(address)) server_conn = zmq_utils.Connection(address, zmq_utils.zmq.REP) server_conn.bind() renderer_service = renderer_zmq_service.RendererZMQService( framebuffer, mesh_drawer, vert_fov, initial_distance, trackball, world_to_opengl_mat) global input_enabled global override_renderer_service_transform global window_enabled input_enabled = args.input_enabled window_enabled = window.visible override_renderer_service_transform = False def window_visible_callback(visible): if visible: logger.info("Showing window") window.show() else: logger.info("Hiding window") window.hide() def window_active_callback(active): global window_enabled if active: logger.info("Activating window") else: logger.info("Deactivating window") window_enabled = active renderer_service.window_visible_callbacks.register(window_visible_callback) renderer_service.window_active_callbacks.register(window_active_callback) # Some keyboard input handling @window.glumpy_window.event def on_key_press(symbol, modifiers): try: character = chr(symbol).lower() except ValueError as err: character = "" logger.debug("Key pressed: {}, modifiers: {}, character: {}".format( symbol, modifiers, character)) if character == 'n': logger.info("Showing normals") window.clear_drawers() window.add_drawer(window_fb_normal_drawer) elif character == 'c': logger.info("Showing colors") window.clear_drawers() window.add_drawer(window_fb_color_drawer) elif character == 'd': logger.info("Showing depth") window.clear_drawers() window.add_drawer(window_fb_depth_drawer) elif character == 'i': global input_enabled if input_enabled: logger.info("Disabling input") input_enabled = False else: logger.info("Enabling input") input_enabled = True elif character == 'a': global window_enabled if window_enabled: logger.info("Disabling window") window_enabled = False else: logger.info("Enabling window") window_enabled = True elif character == 'o': global override_renderer_service_transform if override_renderer_service_transform: logger.info("Not overriding renderer service transform input") override_renderer_service_transform = False else: logger.info("Overriding renderer service transform input") override_renderer_service_transform = True elif character == 'p': logger.info("Current location: {}".format(trackball.location)) logger.info("Current world location: {}".format( np.dot(opengl_to_world_mat[:3, :3], trackball.camera_location))) logger.info("Current orientation_rpy: {}".format( trackball.orientation_rpy)) timer = utils.RateTimer(reset_interval=500) while True: dt = app.clock.tick() # Handle network requests request_dump = server_conn.recv(timeout=poll_timeout * 1000) if request_dump is not None: response_dump = renderer_service.handle_request_msg( request_dump, raise_exception=True) if response_dump is not None: server_conn.send(response_dump) # Perform any drawer processing mesh_drawer.tick(dt) # Animate model if desired if yaw_speed != 0: mesh_drawer.transform.yaw += yaw_speed * dt if pitch_speed != 0: mesh_drawer.transform.pitch += pitch_speed * dt if override_renderer_service_transform: renderer_service.view_transform = trackball.transform.copy() if window.visible and window_enabled: if input_enabled and renderer_service.input_enabled: view_transform = trackball.transform else: view_transform = renderer_service.view_transform with window_framebuffer.activate(clear=True): mesh_drawer.draw(window.projection, view_transform.matrix, window.width, window.height) # For debugging # color_pixels = framebuffer.read_rgba_pixels() # depth_pixels = framebuffer.read_rgba_pixels(color_index=1) # import cv2 # cv2.imshow("color", color_pixels) # cv2.imshow("depth", depth_pixels[:, :, 0]) # cv2.waitKey(50) window.override_view(trackball.view) app.process(dt) timer.update_and_print_rate(print_interval=100)
class Visualizer(): def __init__(self,name = "unnamed", focal_length = 554.25625, intrinsics = None, run_independently = False): self.sphere = geometry.Sphere() #the eyeball, initialized as something random self.ellipses = [] #collection of ellipses self.circles = [] #collection of all 3D circles on the sphere self.video_frame = (np.linspace(0,1,num=(400*400*4))*255).astype(np.uint8).reshape((400,400,4)) #the randomized image, should be video frame # self.screen_points = [] #collection of points if intrinsics == None: intrinsics = np.identity(3) if focal_length != None: intrinsics[0,0] = focal_length intrinsics[1,1] = focal_length logger.warning('no camera intrinsic input, set to focal length') else: logger.warning('no camera intrinsic input, set to default identity matrix') # transformation matrices self.intrinsics = intrinsics #camera intrinsics of our webcam. self.scale = 1 self.name = name self._window = None self.input = None self.trackball = None self.run_independently = run_independently self.window_should_close = False ############## MATRIX FUNCTIONS ############################## def get_pixel_space_matrix(self): # returns a homoegenous matrix temp = self.get_anthropomorphic_matrix() temp[3,3] *= self.scale return temp def get_adjusted_pixel_space_matrix(self,scale): # returns a homoegenous matrix temp = self.get_pixel_space_matrix() temp[3,3] *= scale return temp def get_anthropomorphic_matrix(self): temp = np.identity(4) temp[2,2] *=-1 #consistent with our 3d coord system return temp def get_image_space_matrix(self,scale=1.): temp = self.get_adjusted_pixel_space_matrix(scale) temp[1,1] *=-1 #image origin is top left temp[0,3] = -self.intrinsics[0,2] #cx temp[1,3] = self.intrinsics[1,2] #cy temp[2,3] = -self.intrinsics[0,0] #focal length return temp.T def get_pupil_transformation_matrix(self,circle): """ OpenGL matrix convention for typical GL software with positive Y=up and positive Z=rearward direction RT = right UP = up BK = back POS = position/translation US = uniform scale float transform[16]; [0] [4] [8 ] [12] [1] [5] [9 ] [13] [2] [6] [10] [14] [3] [7] [11] [15] [RT.x] [UP.x] [BK.x] [POS.x] [RT.y] [UP.y] [BK.y] [POS.y] [RT.z] [UP.z] [BK.z] [POS.Z] [ ] [ ] [ ] [US ] """ temp = self.get_anthropomorphic_matrix() right = temp[:3,0] up = temp[:3,1] back = temp[:3,2] translation = temp[:3,3] back[:] = np.array(circle.normal) back[-2] *=-1 #our z axis is inverted back[-0] *=-1 #our z axis is inverted back[:] /= np.linalg.norm(back) right[:] = get_perpendicular_vector(back)/np.linalg.norm(get_perpendicular_vector(back)) up[:] = np.cross(right,back)/np.linalg.norm(np.cross(right,back)) translation[:] = np.array((circle.center[0],circle.center[1],-circle.center[2])) return temp.T def get_rotated_sphere_matrix(self,circle,sphere): """ OpenGL matrix convention for typical GL software with positive Y=up and positive Z=rearward direction RT = right UP = up BK = back POS = position/translation US = uniform scale float transform[16]; [0] [4] [8 ] [12] [1] [5] [9 ] [13] [2] [6] [10] [14] [3] [7] [11] [15] [RT.x] [UP.x] [BK.x] [POS.x] [RT.y] [UP.y] [BK.y] [POS.y] [RT.z] [UP.z] [BK.z] [POS.Z] [ ] [ ] [ ] [US ] """ temp = self.get_anthropomorphic_matrix() right = temp[:3,0] up = temp[:3,1] back = temp[:3,2] translation = temp[:3,3] back[:] = np.array(circle.normal) back[-2] *=-1 #our z axis is inverted back[-0] *=-1 #our z axis is inverted back[:] /= np.linalg.norm(back) right[:] = get_perpendicular_vector(back)/np.linalg.norm(get_perpendicular_vector(back)) up[:] = np.cross(right,back)/np.linalg.norm(np.cross(right,back)) translation[:] = np.array((sphere.center[0],sphere.center[1],-sphere.center[2])) return temp.T ############## DRAWING FUNCTIONS ############################## def draw_rect(self): glBegin(GL_QUADS) glColor4f(0.0, 0.0, 0.5,0.2) #set color to light blue glVertex2f(0,0) glVertex2f(0 + 32, 0) glVertex2f(0 + 32, 0 + 16) glVertex2f(0, 0 + 16) glEnd() def draw_frustum(self, scale=1): # average focal length #f = (K[0, 0] + K[1, 1]) / 2 # compute distances for setting up the camera pyramid W = self.intrinsics[0,2] H = self.intrinsics[1,2] Z = self.intrinsics[0,0] # scale the pyramid W *= scale H *= scale Z *= scale # draw it glColor4f( 1, 0.5, 0, 0.5 ) glBegin( GL_LINE_LOOP ) glVertex3f( 0, 0, 0 ) glVertex3f( -W, H, Z ) glVertex3f( W, H, Z ) glVertex3f( 0, 0, 0 ) glVertex3f( W, H, Z ) glVertex3f( W, -H, Z ) glVertex3f( 0, 0, 0 ) glVertex3f( W, -H, Z ) glVertex3f( -W, -H, Z ) glVertex3f( 0, 0, 0 ) glVertex3f( -W, -H, Z ) glVertex3f( -W, H, Z ) glEnd( ) def draw_coordinate_system(self,l=1): # Draw x-axis line. RED glLineWidth(2) glColor3f( 1, 0, 0 ) glBegin( GL_LINES ) glVertex3f( 0, 0, 0 ) glVertex3f( l, 0, 0 ) glEnd( ) # Draw y-axis line. GREEN. glColor3f( 0, 1, 0 ) glBegin( GL_LINES ) glVertex3f( 0, 0, 0 ) glVertex3f( 0, l, 0 ) glEnd( ) # Draw z-axis line. BLUE glColor3f( 0, 0,1 ) glBegin( GL_LINES ) glVertex3f( 0, 0, 0 ) glVertex3f( 0, 0, l ) glEnd( ) def draw_sphere(self,circle): # this function draws the location of the eye sphere glPushMatrix() glColor4f(0.0, 1.0, 1.0,0.2) #set color to blue glLoadMatrixf(self.get_rotated_sphere_matrix(circle,self.sphere)) glutSolidSphere(self.sphere.radius,20,10) glColor4f(0.0, 0.0, 1.0,0.8) #set color to blue glutWireSphere(self.sphere.radius,20,10) glPopMatrix() def draw_all_ellipses(self): # draws all ellipses in self.ellipses. glPushMatrix() for ellipse in self.ellipses[-10:]: glColor3f(0.0, 1.0, 0.0) #set color to green pts = cv2.ellipse2Poly( (int(ellipse.center[0]),int(ellipse.center[1])), (int(ellipse.major_radius),int(ellipse.minor_radius)), int(ellipse.angle*180/scipy.pi),0,360,15) draw_polyline(pts,2,color = RGBA(0,1,1,.5)) glPopMatrix() def draw_circle(self,circle): glPushMatrix() glLoadMatrixf(self.get_pupil_transformation_matrix(circle)) draw_points(((0,0),),color=RGBA(1.1,0.2,.8)) glColor4f(0.0, 0.0, 0.0,0.5) #set color to green glBegin(GL_POLYGON) #draw circle for i in xrange(45): rad = i*16*scipy.pi/360. glVertex2f(np.cos(rad)*circle.radius,np.sin(rad)*circle.radius) glEnd() glPopMatrix() def draw_video_screen(self): # Function to draw self.video_frame. # Need to scale glPushMatrix() tex_id = create_named_texture(self.video_frame.shape) update_named_texture(tex_id,self.video_frame) #since image doesn't change, do not need to put in while loop draw_named_texture(tex_id) glPopMatrix() ########## Setup functions I don't really understand ############ def basic_gl_setup(self): glEnable(GL_POINT_SPRITE ) glEnable(GL_VERTEX_PROGRAM_POINT_SIZE) # overwrite pointsize glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glEnable(GL_BLEND) glClearColor(.8,.8,.8,1.) glEnable(GL_LINE_SMOOTH) # glEnable(GL_POINT_SMOOTH) glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) glEnable(GL_LINE_SMOOTH) glEnable(GL_POLYGON_SMOOTH) glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST) def adjust_gl_view(self,w,h): """ adjust view onto our scene. """ glViewport(0, 0, w, h) glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(0, w, h, 0, -1, 1) glMatrixMode(GL_MODELVIEW) glLoadIdentity() def clear_gl_screen(self): glClearColor(.9,.9,0.9,1.) glClear(GL_COLOR_BUFFER_BIT) ########### Open, update, close ##################### def open_window(self): if not self._window: self.input = {'button':None, 'mouse':(0,0)} self.trackball = Trackball() # get glfw started if self.run_independently: glfwInit() window = glfwGetCurrentContext() self._window = glfwCreateWindow(640, 480, self.name, None, window) glfwMakeContextCurrent(self._window) if not self._window: exit() glfwSetWindowPos(self._window,2000,0) # Register callbacks window glfwSetFramebufferSizeCallback(self._window,self.on_resize) glfwSetWindowIconifyCallback(self._window,self.on_iconify) glfwSetKeyCallback(self._window,self.on_key) glfwSetCharCallback(self._window,self.on_char) glfwSetMouseButtonCallback(self._window,self.on_button) glfwSetCursorPosCallback(self._window,self.on_pos) glfwSetScrollCallback(self._window,self.on_scroll) glfwSetWindowCloseCallback(self._window,self.on_close) # get glfw started if self.run_independently: init() glutInit() self.basic_gl_setup() self.glfont = fs.Context() self.glfont.add_font('opensans',get_opensans_font_path()) self.glfont.set_size(22) self.glfont.set_color_float((0.2,0.5,0.9,1.0)) # self.gui = ui.UI() self.on_resize(self._window,*glfwGetFramebufferSize(self._window)) def update_window(self, g_pool = None,model = None): if self.window_should_close: self.close_window() if self._window != None: glfwMakeContextCurrent(self._window) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glClearDepth(1.0) glDepthFunc(GL_LESS) glEnable(GL_DEPTH_TEST) glAlphaFunc(GL_GREATER, 0) self.clear_gl_screen() self.trackball.push() # print glGetFloatv(GL_MODELVIEW_MATRIX).T #THINGS I NEED TO DRAW # 1. in anthromorphic space, draw pupil sphere and circles on it glLoadMatrixf(self.get_anthropomorphic_matrix()) if model: #if we are feeding in spheres to draw for pupil in model.observations[-10:]: #draw the last 10 self.draw_circle(pupil.circle) self.draw_sphere(pupil.circle) #draw the eyeball self.draw_coordinate_system(4) glTranslatef(*self.sphere.center) glScalef(0.1,0.1,0.1) self.glfont.draw_multi_line_text(0,0,'Eyeball location: \n %s'%self.sphere.center) # 1a. draw frustum in pixel scale, but retaining origin glLoadMatrixf(self.get_adjusted_pixel_space_matrix(30)) self.draw_frustum() # 2. in pixel space, draw ellipses, and video frame glLoadMatrixf(self.get_image_space_matrix(30)) if g_pool: #if display eye camera frames draw_named_texture(g_pool.image_tex,quad=((0,480),(640,480),(640,0),(0,0)),alpha=0.5) self.draw_all_ellipses() # 3. display text on screen # glWindowPos2i(100, 100) # glutPrint("SAMPLE TEXT") # glFontBegin(font); # glScalef(8.0, 8.0, 8.0); # glTranslatef(30, 30, 0); # glFontTextOut("Test", 5, 5, 0); # glFontEnd(); # glFlush(); self.trackball.pop() glfwSwapBuffers(self._window) glfwPollEvents() return True def close_window(self): if self.window_should_close == True: glfwDestroyWindow(self._window) if self.run_independently: glfwTerminate() self._window = None self.window_should_close = False logger.debug("Process done") ############ window callbacks ################# def on_resize(self,window,w, h): h = max(h,1) w = max(w,1) self.trackball.set_window_size(w,h) active_window = glfwGetCurrentContext() glfwMakeContextCurrent(window) self.adjust_gl_view(w,h) glfwMakeContextCurrent(active_window) def on_iconify(self,window,x,y): pass def on_key(self,window, key, scancode, action, mods): pass #self.gui.update_key(key,scancode,action,mods) def on_char(window,char): pass # self.gui.update_char(char) def on_button(self,window,button, action, mods): # self.gui.update_button(button,action,mods) if action == GLFW_PRESS: self.input['button'] = button self.input['mouse'] = glfwGetCursorPos(window) if action == GLFW_RELEASE: self.input['button'] = None # pos = normalize(pos,glfwGetWindowSize(window)) # pos = denormalize(pos,(frame.img.shape[1],frame.img.shape[0]) ) # Position in img pixels def on_pos(self,window,x, y): hdpi_factor = float(glfwGetFramebufferSize(window)[0]/glfwGetWindowSize(window)[0]) x,y = x*hdpi_factor,y*hdpi_factor # self.gui.update_mouse(x,y) if self.input['button']==GLFW_MOUSE_BUTTON_RIGHT: old_x,old_y = self.input['mouse'] self.trackball.drag_to(x-old_x,y-old_y) self.input['mouse'] = x,y if self.input['button']==GLFW_MOUSE_BUTTON_LEFT: old_x,old_y = self.input['mouse'] self.trackball.pan_to(x-old_x,y-old_y) self.input['mouse'] = x,y def on_scroll(self,window,x,y): # self.gui.update_scroll(x,y) self.trackball.zoom_to(y) def on_close(self,window=None): self.window_should_close = True
def demo(video_frame = None): user_input = {'down':False, 'mouse':(0,0)} # Callback functions def on_resize(window,w, h): h = max(h,1) w = max(w,1) gui.update_window(w,h) active_window = glfwGetCurrentContext() glfwMakeContextCurrent(window) # norm_size = normalize((w,h),glfwGetWindowSize(window)) # fb_size = denormalize(norm_size,glfwGetFramebufferSize(window)) adjust_gl_view(w,h) glfwMakeContextCurrent(active_window) track.set_window_size(w,h) def on_iconify(window,iconfied): pass def on_key(window, key, scancode, action, mods): gui.update_key(key,scancode,action,mods) def on_char(window,char): gui.update_char(char) def on_button(window,button, action, mods): gui.update_button(button,action,mods) if action == GLFW_PRESS: user_input['down'] = True user_input['mouse'] = glfwGetCursorPos(window) if action == GLFW_RELEASE: user_input['down'] = False # pos = normalize(pos,glfwGetWindowSize(window)) # pos = denormalize(pos,(frame.img.shape[1],frame.img.shape[0]) ) # Position in img pixels def on_pos(window,x, y): hdpi_factor = float(glfwGetFramebufferSize(window)[0]/glfwGetWindowSize(window)[0]) x,y = x*hdpi_factor,y*hdpi_factor gui.update_mouse(x,y) if user_input['down']: old_x,old_y = user_input['mouse'] track.drag_to(x-old_x,y-old_y) user_input['mouse'] = x,y def on_scroll(window,x,y): gui.update_scroll(x,y) track.zoom_to(y) # get glfw started glfwInit() window = glfwCreateWindow(width, height, "pyglui demo", None, None) glfwMakeContextCurrent(window) if not window: exit() glfwSetWindowPos(window,0,0) # Register callbacks window glfwSetFramebufferSizeCallback(window,on_resize) glfwSetWindowIconifyCallback(window,on_iconify) glfwSetKeyCallback(window,on_key) glfwSetCharCallback(window,on_char) glfwSetMouseButtonCallback(window,on_button) glfwSetCursorPosCallback(window,on_pos) glfwSetScrollCallback(window,on_scroll) init() glutInit() basic_gl_setup() gui = ui.UI() track = Trackball() on_resize(window,*glfwGetFramebufferSize(window)) if video_frame == None: video_frame = (np.linspace(0,1,num=(400*400*4))*255).astype(np.uint8).reshape((400,400,4)) #the randomized image test_sphere = geometry.Sphere([0,5,0],1) test_ellipse = geometry.Ellipse((0,3),5,3,0) #return window #def demo_update(window): while not glfwWindowShouldClose(window): clear_gl_screen() track.push() #glutils.draw_polyline3d([(0,0,2),(1,1,2)],color=RGBA(0.4,0.5,0.3,0.5)) draw_sphere(test_sphere) draw_ellipse(test_ellipse) draw_video_screen(video_frame) draw_coordinate_system(20) track.pop() glfwSwapBuffers(window) glfwPollEvents() #def demo_close(window): glfwDestroyWindow(window) glfwTerminate() logger.debug("Process done")
glTexImage2D(GL_TEXTURE_2D, 4, GL_RGB, 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData32) glTexImage2D(GL_TEXTURE_2D, 5, GL_RGB, 16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData16) glTexImage2D(GL_TEXTURE_2D, 6, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData8) glTexImage2D(GL_TEXTURE_2D, 7, GL_RGB, 4, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData4) glTexImage2D(GL_TEXTURE_2D, 8, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData2) glTexImage2D(GL_TEXTURE_2D, 9, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData1) glEnable(GL_TEXTURE_2D) GLUT_WHEEL = 1 prevPos = [0, 0] translate = [0, 0] is_right_button_down = False is_wheel_down = False trackball = Trackball(45, 135, 5, 4) glutMouseFunc(on_mouse) glutMouseWheelFunc(on_wheel) glutReshapeFunc(on_reshape) glutDisplayFunc(on_draw) glutMotionFunc(on_motion) glutKeyboardFunc(on_keyboard) glutSpecialFunc(on_special) glutMainLoop()
def cam1Event(self): self.glwidget.tb = Trackball(phi=-0.0, theta=0.0, zoom=1.0, rot=[-0.02, -0.71, -0.02, 0.71], trans=[0.06, 0.26, -1.23])
# Read the various information coming from the trackball # # See GitHub: https://github.com/mchobby/esp8266-upy/tree/master/trackball from machine import I2C from trackball import Trackball import time i2c = I2C(2) # Y9=scl, Y10=sda or Pyboard-Uno-R3 (I2C over pin 13) # initialize the trackball trackball = Trackball(i2c) trackball.set_rgbw(255, 0, 0, 0) while True: up, down, left, right, switch, state = trackball.read() print("r: {:02d} u: {:02d} d: {:02d} l: {:02d} switch: {:03d} state: {}". format(right, up, down, left, switch, state)) time.sleep(0.200)
class Visualizer(): def __init__(self,name = "unnamed"): self.name = name self.sphere = geometry.Sphere() self.ellipses = [] #collection of ellipses to display self.projected_lines = [] #collection of projected lines to display self.frame = None #video frame from eye self._window = None self.input = None self.trackball = None self.window_should_close = False self.video_frame = (np.linspace(0,1,num=(400*400*4))*255).astype(np.uint8).reshape((400,400,4)) #the randomized image self.test_sphere = geometry.Sphere([0,5,0],1) self.test_ellipse = geometry.Ellipse((0,3),5,3,0) ############## DRAWING FUNCTIONS ############################## def draw_coordinate_system(self,l=1): # Draw x-axis line. RED glColor3f( 1, 0, 0 ) glBegin( GL_LINES ) glVertex3f( 0, 0, 0 ) glVertex3f( l, 0, 0 ) glEnd( ) # Draw y-axis line. GREEN. #not working... why? glColor3f( 0, 1, 0 ) glBegin( GL_LINES ) glVertex3f( 0, 0, 0 ) glVertex3f( 0, l, 0 ) glEnd( ) # Draw z-axis line. BLUE glColor3f( 0, 0,1 ) glBegin( GL_LINES ) glVertex3f( 0, 0, 0 ) glVertex3f( 0, 0, l ) glEnd( ) def draw_sphere(self,sphere): # this function draws the location of the eye sphere glPushMatrix() glColor3f(0.0, 0.0, 1.0) glTranslate(sphere.center[0], sphere.center[1], sphere.center[2]) glutWireSphere(sphere.radius,20,20) glPopMatrix() def draw_ellipse(self,ellipse): glPushMatrix() glTranslate(ellipse.center[0], ellipse.center[1], 0) glBegin(GL_LINE_LOOP) for i in xrange(360): rad = i*2*scipy.pi/360. glVertex2f(np.cos(rad)*ellipse.major_radius,np.sin(rad)*ellipse.minor_radius) glEnd() glPopMatrix() def draw_projected_line(self,line): #draw a line from projected sphere center to the ellipse on frame. """ TO BE IMPLEMENTED """ pass def draw_video_screen(self,frame): glPushMatrix() tex_id = create_named_texture(frame.shape) update_named_texture(tex_id,frame) #since image doesn't change, do not need to put in while loop draw_named_texture(tex_id) glPopMatrix() ########## Setup functions I don't really understand ############ def basic_gl_setup(self): glEnable(GL_POINT_SPRITE ) glEnable(GL_VERTEX_PROGRAM_POINT_SIZE) # overwrite pointsize glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glEnable(GL_BLEND) glClearColor(.8,.8,.8,1.) glEnable(GL_LINE_SMOOTH) # glEnable(GL_POINT_SMOOTH) glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) glEnable(GL_LINE_SMOOTH) glEnable(GL_POLYGON_SMOOTH) glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST) def adjust_gl_view(self,w,h): """ adjust view onto our scene. """ glViewport(0, 0, w, h) glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(0, w, h, 0, -1, 1) glMatrixMode(GL_MODELVIEW) glLoadIdentity() def clear_gl_screen(self): glClearColor(.9,.9,0.9,1.) glClear(GL_COLOR_BUFFER_BIT) ########### Open, update, close ##################### def open_window(self): if not self._window: self.input = {'down':False, 'mouse':(0,0)} self.trackball = Trackball() # get glfw started glfwInit() self._window = glfwCreateWindow(width, height, self.name, None, None) glfwMakeContextCurrent(self._window) if not self._window: exit() glfwSetWindowPos(self._window,2000,0) # Register callbacks window glfwSetFramebufferSizeCallback(self._window,self.on_resize) glfwSetWindowIconifyCallback(self._window,self.on_iconify) glfwSetKeyCallback(self._window,self.on_key) glfwSetCharCallback(self._window,self.on_char) glfwSetMouseButtonCallback(self._window,self.on_button) glfwSetCursorPosCallback(self._window,self.on_pos) glfwSetScrollCallback(self._window,self.on_scroll) glfwSetWindowCloseCallback(self._window,self.on_close) init() glutInit() self.basic_gl_setup() self.gui = ui.UI() self.on_resize(self._window,*glfwGetFramebufferSize(self._window)) def update_window(self): if self.window_should_close: self.close_window() if self._window != None: self.clear_gl_screen() self.trackball.push() #glutils.draw_polyline3d([(0,0,2),(1,1,2)],color=RGBA(0.4,0.5,0.3,0.5)) self.draw_sphere(self.test_sphere) self.draw_ellipse(self.test_ellipse) self.draw_video_screen(self.video_frame) self.draw_coordinate_system(20) self.trackball.pop() glfwSwapBuffers(self._window) glfwPollEvents() return True def close_window(self): if self.window_should_close == True: glfwDestroyWindow(self._window) glfwTerminate() self._window = None self.window_should_close = False logger.debug("Process done") ############ window callbacks ################# def on_resize(self,window,w, h): h = max(h,1) w = max(w,1) self.trackball.set_window_size(w,h) active_window = glfwGetCurrentContext() glfwMakeContextCurrent(window) self.adjust_gl_view(w,h) glfwMakeContextCurrent(active_window) def on_iconify(self,window,x,y): pass def on_key(self,window, key, scancode, action, mods): self.gui.update_key(key,scancode,action,mods) def on_char(window,char): self.gui.update_char(char) def on_button(self,window,button, action, mods): self.gui.update_button(button,action,mods) if action == GLFW_PRESS: self.input['down'] = True self.input['mouse'] = glfwGetCursorPos(window) if action == GLFW_RELEASE: self.input['down'] = False # pos = normalize(pos,glfwGetWindowSize(window)) # pos = denormalize(pos,(frame.img.shape[1],frame.img.shape[0]) ) # Position in img pixels def on_pos(self,window,x, y): hdpi_factor = float(glfwGetFramebufferSize(window)[0]/glfwGetWindowSize(window)[0]) x,y = x*hdpi_factor,y*hdpi_factor self.gui.update_mouse(x,y) if self.input['down']: old_x,old_y = self.input['mouse'] self.trackball.drag_to(x-old_x,y-old_y) self.input['mouse'] = x,y def on_scroll(self,window,x,y): self.gui.update_scroll(x,y) self.trackball.zoom_to(y) def on_close(self,window=None): self.window_should_close = True
# Change the color of the trackball LED depending on the trackball movement # - Move up/down, right/left to modify color and saturation # - Press the button to light on/off # # See GitHub: https://github.com/mchobby/esp8266-upy/tree/master/trackball from machine import I2C from trackball import Trackball import time i2c = I2C(2) # Y9=scl, Y10=sda or Pyboard-Uno-R3 (I2C over pin 13) trackball = Trackball(i2c) x = 0 y = 50.0 toggled = False def hsv_to_rgb(h, s, v): if s == 0.0: return v, v, v i = int(h * 6.0) # XXX assume int() truncates! f = (h * 6.0) - i p = v * (1.0 - s) q = v * (1.0 - s * f) t = v * (1.0 - s * (1.0 - f)) i = i % 6 if i == 0: return v, t, p if i == 1:
class ViewController(object): ''' Creates a view matrix based on mouse and keyboard input. ''' def __init__(self): ''' Constructor ''' self._initialViewM = np.eye(4,dtype=np.float32) self._viewM = np.copy(self._initialViewM) self.trackball = Trackball() self.keyDict = { ord('r') : self.reset, key.UP: self.up, key.DOWN: self.down, key.LEFT: self.left, key.RIGHT: self.right, ord('w'): self.forward, ord('s'): self.backward, ord('a'): self.left, ord('d'): self.right, ord('q'): self.rollLeft, ord('e'): self.rollRight, ord('z'): self.pitchUp, ord('x'): self.pitchDown, ord('i'): self.info, ord('1'): self.toggleMesh, ord('2'): self.toggleFaces, ord('3'): self.toggleNormals, } self.translateMult = -1.0 self.dragMult = -0.01 self.zoomMult = 0.01 self._zoom = 1.0 self.showMesh = True self.showFaces = False self.showNormals = False def info(self): print "OpenGL Version: ",GL.glGetString(GL.GL_VERSION) print "OpenGL Vendor: ",GL.glGetString(GL.GL_VENDOR) print "OpenGL Renderer: ",GL.glGetString(GL.GL_RENDERER) print "OpenGL GLSL Version: ",GL.glGetString(GL.GL_SHADING_LANGUAGE_VERSION) print "OpenGL Extensions: \n",GL.glGetString(GL.GL_EXTENSIONS).split() print "FBO Max color attachments: ",GL.glGetIntegerv(GL.GL_MAX_COLOR_ATTACHMENTS) # print "FBO Max Width: ",GL.glGetInteger(GL.GL_MAX_FRAMEBUFFER_WIDTH) # print "FBO Max Height: ",GL.glGetInteger(GL.GL_MAX_FRAMEBUFFER_HEIGHT) # print "FBO Max Samples: ",GL.glGetInteger(GL.GL_MAX_FRAMEBUFFER_SAMPLES) # print "FBO Max Layers: ",GL.glGetInteger(GL.GL_MAX_FRAMEBUFFER_LAYERS) def unmapped(self): # self.width = 640 # self.height =480 # # # Read image from the OpenGL buffer # buffer = ( GL.GLfloat * (self.width*self.height) )(0) # GL.glReadPixels(0, 0, self.width, self.height, GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT, buffer) # depth = np.flipud(np.array(buffer, np.float32).reshape(self.height,self.width)) # # # Read depth from the OpenGL buffer # buffer = ( GL.GLubyte * (3*self.width*self.height) )(0) # GL.glReadPixels(0, 0, self.width, self.height, GL.GL_BGR, GL.GL_UNSIGNED_BYTE, buffer) # bgr = np.flipud(np.array(buffer, np.uint8).reshape(self.height,self.width,3)) # # # image.show("Depth", depth) # image.show("BGR", bgr,30) # print "Unmapped key pressed." pass def toggleMesh(self): self.showMesh = not self.showMesh self.parentWindow.redraw() def toggleFaces(self): self.showFaces = not self.showFaces self.parentWindow.redraw() def toggleNormals(self): self.showNormals = not self.showNormals self.parentWindow.redraw() def on_key_press(self,symbol, modifiers): self.keyDict.get(symbol, self.unmapped)(); self.parentWindow.redraw() def on_mouse_scroll(self,dx, dy,s0,s1): self._zoom += self.zoomMult * s1 if self._zoom<self.zoomMult:# do not allow negative zoom self._zoom = self.zoomMult # print "Zoom ",self._zoom self.parentWindow.redraw() def on_mouse_drag(self, x, y, dx, dy, buttons): # print "Mouse Drag ",x,y," => ",dx,dy," Buttons: ",mouse.buttons_string(buttons) if buttons&mouse.MIDDLE: self.translate(-dx*self.dragMult, dy*self.dragMult, 0) elif buttons&mouse.RIGHT: self.translate(0, 0, dy*self.dragMult) else: self.trackball.dragTo(x, y, -dx, dy) self.parentWindow.redraw() pass def on_mouse_release(self,x,y,buttons): # print "Mouse Release ",x,y," => Buttons: ",buttons pass def rollLeft(self): self.rotate(0,-1) def rollRight(self): self.rotate(0,+1) def pitchUp(self): self.rotate(-1,0) def pitchDown(self): self.rotate(1,0) def rotate(self,dTheta, dPhi): theta,phi = self.trackball.getOrientation() phi += dPhi theta +=dTheta self.trackball.setOrientation(theta,phi) def registerEvents(self,window): window.event(self.on_key_press) window.event(self.on_mouse_drag) window.event(self.on_mouse_scroll) window.event(self.on_mouse_release) self.parentWindow=window def reset(self): print "Reset View." self._viewM = self._initialViewM.copy() self._zoom = 1.0 self.trackball.setOrientation(0, 0) def up(self): # print "Up." dy = -1.0 * self.translateMult self.translate(0, dy, 0) def down(self): # print "Down." dy = 1.0 * self.translateMult self.translate(0, dy, 0) def left(self): # print "Left." dx = -1.0 * self.translateMult self.translate(dx, 0, 0) def right(self): # print "Right." dx = 1.0 * self.translateMult self.translate(dx, 0, 0) def forward(self): # print "Forward." dz = 1.0 * self.translateMult self.translate(0, 0, dz) def backward(self): # print "Backward." dz = -1.0 * self.translateMult self.translate(0, 0, dz) def translate(self,dx,dy,dz): tr = np.eye(4,dtype=np.float32) tr[0:3,3] = np.array([dx,dy,dz],dtype=np.float32) self._viewM = tr.dot(self._viewM) def getViewM(self): ''' Return the view matrix in PyOpenGL usable format (flat list of floats, column major) ''' scaleM = np.diag([self._zoom,self._zoom,self._zoom,1.0]) viewM = self._viewM.dot(self.trackball.getRotMat().dot(scaleM)) return viewM.transpose().reshape(-1).tolist() def setCameraPosition(self,trXYZ,rotQuat=[1,0,0,0],scale=1): ''' set the camera orientation. This will not set the reset location. :param trXYZ: :param rotQuat: in the form of: x,y,z,w :param scale: :return: ''' tr = np.eye(4,dtype=np.float32) tr[0:3,3] = np.array(trXYZ,dtype=np.float32) self._viewM = tr self._zoom = scale self.trackball.setRotation(rotQuat) def getCameraPosition(self): quat = self.trackball.getRotation() tr = self._viewM[0:3,3] return tr,quat,self._zoom
# Make a rainbow color cycle on the trackball # # See GitHub: https://github.com/mchobby/esp8266-upy/tree/master/trackball from machine import I2C from trackball import Trackball import time i2c = I2C(2) # Y9=scl, Y10=sda or Pyboard-Uno-R3 (I2C over pin 13) trackball = Trackball(i2c) def hsv_to_rgb(h, s, v): if s == 0.0: return v, v, v i = int(h * 6.0) # XXX assume int() truncates! f = (h * 6.0) - i p = v * (1.0 - s) q = v * (1.0 - s * f) t = v * (1.0 - s * (1.0 - f)) i = i % 6 if i == 0: return v, t, p if i == 1: return q, v, p if i == 2: return p, v, t if i == 3: return p, q, v if i == 4: return t, p, v