Mouse coordinates
We have a camera and something displayed on the screen, now let's start taking input from the mouse. We will create a new mouse handling class which will allow us to store a series of clicks. We can also use the stored positions for previews at a later date.The new class contains a few simple methods:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
class mouse_state:
""" store mouse clicks so we know where to draw and what to create """
button1 = 0
button2 = 0
button3 = 0
cordinates = []
x = y = 0
def append(self, x, y, button=1):
""" store a new mouse click """
self.x = x
self.y = y
self.cordinates.append((x, y,))
def get_click_position(self):
""" return the position of the last click """
return self.x, self.y
def get_points(self):
""" return all stored points we may want to store lots of points when drawing a line for example"""
if len(self.cordinates) != 2:
return None
result = self.cordinates
self.cordinates = []
return result
def count(self):
"""return number of stored points """
return len(self.cordinates)
def clear(self):
self.x = self.y = 0
self.cordinates = []
|
Let's add a new method to our camera class, which will convert mouse clicks in 2 dimensional space into 3 dimensional coordinates so we can position something on the screen.The 'getclick point' method below takes a tuple containing the x and y coordinates from the mouse. It then converts the y position because in opengl '0' is at the bottom, but drawing area widget has '0' at the top. Finally it uses gluUnProject to convert from 2d space to 3d space.
1 2 3 4 5 6 7 8 9 10 11 |
def get_click_point(self, pos):
""" convert 2d click in the viewport to 3d point in space"""
viewport = glGetIntegerv(GL_VIEWPORT)
modelview = glGetDoublev(GL_MODELVIEW_MATRIX)
projection = glGetDoublev(GL_PROJECTION_MATRIX)
#convert screen ccordinate to opengl cordinates, this means modifying the y axes only
x, y = pos[0], self.viewport[1] - pos[1]
#use unproject to calculate the point and store the resutl in a point object
return createpoint(gluUnProject(x, y, 0.20, modelview, projection, viewport), (250, 0, 0))
|
Let's handle the mouse click events in the drawing area; we will store the 2d x and y coordinates of a mouse click in our new mousestate class. Now we adjust the ondraw method to draw a point at the location we clicked on the page, which gives us visual feedback that everything is working correctly.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
def mouse_click(self, widget, event):
self.mouse.append(event.x, event.y, event.button)
self.test_point = self.camera.get_click_point(self.mouse.get_click_position())
self.on_draw()
def on_draw(self, *args):
""" Test code to make sure we can draw a pixel successfully,
also test we can position our new camera class to lookat the pixel"""
#lets not look directly at the point we are drawing, demonstrating we can lookat points in space
self.camera.lookat.x = 20
self.camera.lookat.y = 20
self.camera.lookat.z = -20
#recalculate our camera based on the new settings
self.camera.update()
glClearColor(0.0, 0.0, 0.0, 0.0)
glClear(GL_COLOR_BUFFER_BIT)
self.glwrap.draw_start()
#place a point we can lookat that will be positioned in our field of view.
self.test_point.draw()
self.glwrap.draw_finish()
|