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