Beispiel #1
0
    def __init__(self, parent=None):
        self.parent = parent
        QtOpenGL.QGLWidget.__init__(self, parent)

        self.shader_program = None  # QtOpenGL.QGLShaderProgram()

        self.camera = Camera(
        )  # initialize a camera object (initially located at the origin and facing (0, 0, -1)

        self.xy_grid = MyGrid()

        self.renderables3d = set(
        )  # this contains all the geometries on canvas

        self.selection_box = None  # this contains at most 1 selection box

        self.last_mouse_position = QPoint(
            0, 0)  # last position of the mouse in viewport-coordinates

        self.bounding_box = Box3D(the_min=Point3(-20, -20, -20),
                                  the_max=Point3(20, 20, 20))
        # the bounding_box of all the geometries in the canvas.
        # BUT is never smaller than the values set here! Because it is used to set the viewport in VIEW_2D mode

        self.mode = Canvas3d.MODE_EXPLORE  # by default in "scene exploration" mode
        self.draw_what = None  # when in MODE_DRAW, this contains an indication of what is being drawn, else None
        self.currently_drawn_geom = None  # this maintains a reference to a geometry being drawn, until the drawing is complete

        self.selected_geoms = set(
        )  # will contain geometries in the canvas selected via the select tool

        self.canvas_cube_proportion = None
        self.setMouseTracking(True)
Beispiel #2
0
def main():
    pyglet.resource.path.append('../data')
    pyglet.resource.reindex()

    entity_manager = EntityManager()
    block_grid = BlockGrid()

    state_update_phase = UpdatePhase()
    update_phases = [state_update_phase]
    update_manager = UpdateManager(update_phases)

    scene = Scene()
    camera = Camera(scale=5.0)
    game_window = GameWindow()
    collision_listener = GameCollisionListener()
    collision_world = CollisionWorld(listener=collision_listener)
    batch = pyglet.graphics.Batch()
    key_state_handler = pyglet.window.key.KeyStateHandler()
    joysticks = open_joysticks()
    block_entity_creator = BlockEntityCreator(collision_world, batch)
    character_entity_creator = CharacterEntityCreator(
        key_state_handler, joysticks, state_update_phase, collision_world,
        batch, block_entity_creator, entity_manager, block_grid)
    game_view = GameView(game_window, batch, key_state_handler, entity_manager,
                         update_manager, collision_world, collision_listener,
                         camera)
    game_window.view = game_view
    for i in xrange(-1, 2):
        position = float(i), 0.0
        block_entity = block_entity_creator.create(position=position)
        game_view.add_entity(block_entity)
    character_entity = character_entity_creator.create(position=(0.0, 2.0))
    game_view.add_entity(character_entity)
    pyglet.app.run()
def video_feed():
    """Video streaming route. Put this in the src attribute of an img tag."""
    return Response(gen(Camera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')
Beispiel #4
0
def video_feed():
    camera = Camera()
    return Response(camera.stream(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')
Beispiel #5
0
class Canvas3d(QtOpenGL.QGLWidget):
    MODE_EXPLORE = 0
    MODE_DRAW = 1
    MODE_SELECT = 2
    MODE_ERASE = 3
    MODE_OPERATION = 4

    DRAW_POINTS = 0
    DRAW_SEGMENTS = 1
    DRAW_POLYGONS = 2
    DRAW_POLYLINES = 3

    def __init__(self, parent=None):
        self.parent = parent
        QtOpenGL.QGLWidget.__init__(self, parent)

        self.shader_program = None  # QtOpenGL.QGLShaderProgram()

        self.camera = Camera(
        )  # initialize a camera object (initially located at the origin and facing (0, 0, -1)

        self.xy_grid = MyGrid()

        self.renderables3d = set(
        )  # this contains all the geometries on canvas

        self.selection_box = None  # this contains at most 1 selection box

        self.last_mouse_position = QPoint(
            0, 0)  # last position of the mouse in viewport-coordinates

        self.bounding_box = Box3D(the_min=Point3(-20, -20, -20),
                                  the_max=Point3(20, 20, 20))
        # the bounding_box of all the geometries in the canvas.
        # BUT is never smaller than the values set here! Because it is used to set the viewport in VIEW_2D mode

        self.mode = Canvas3d.MODE_EXPLORE  # by default in "scene exploration" mode
        self.draw_what = None  # when in MODE_DRAW, this contains an indication of what is being drawn, else None
        self.currently_drawn_geom = None  # this maintains a reference to a geometry being drawn, until the drawing is complete

        self.selected_geoms = set(
        )  # will contain geometries in the canvas selected via the select tool

        self.canvas_cube_proportion = None
        self.setMouseTracking(True)

    @pyqtSlot(bool)
    def set_mode_explore(self, toggled):
        if toggled:
            self.mode = Canvas3d.MODE_EXPLORE

    @pyqtSlot(bool)
    def set_mode_select(self, toggled):
        if toggled:
            self.mode = Canvas3d.MODE_SELECT

    @pyqtSlot(bool)
    def set_mode_erase(self, toggled):
        if toggled:
            self.mode = Canvas3d.MODE_ERASE

    @pyqtSlot(bool)
    def set_mode_operation(self, toggled):
        if toggled:
            self.mode = Canvas3d.MODE_OPERATION

    @pyqtSlot(bool)
    def set_mode_draw_points(self, toggled):
        if toggled:
            # print("MODE: DRAW_POINTS")
            self.mode = Canvas3d.MODE_DRAW
            self.draw_what = Canvas3d.DRAW_POINTS

    @pyqtSlot(bool)
    def set_mode_draw_segments(self, toggled):
        if toggled:
            self.mode = Canvas3d.MODE_DRAW
            self.draw_what = Canvas3d.DRAW_SEGMENTS

    @pyqtSlot(bool)
    def set_mode_draw_polygons(self, toggled):
        if toggled:
            self.mode = Canvas3d.MODE_DRAW
            self.draw_what = Canvas3d.DRAW_POLYGONS

    @pyqtSlot(bool)
    def set_mode_draw_polylines(self, toggled):
        if toggled:
            self.mode = Canvas3d.MODE_DRAW
            self.draw_what = Canvas3d.DRAW_POLYLINES

    @pyqtSlot(bool)
    def reset_view_2d(self, toggled):
        GL.glDisable(
            GL.GL_DEPTH_TEST
        )  # disables the depth test (used to display only "visible" faces)
        GL.glDisable(
            GL.GL_CULL_FACE
        )  # disables culling (improves performance as only "visible" faces are processed)

        self.xy_grid.hide()  # hide the grid
        self.camera.set_view_2d(
            toggled)  # reset the position of the camera for 2D View
        self.setMouseTracking(True)

        self.updateGL()  # update the rendered scene

    @pyqtSlot(bool)
    def reset_view_3d(self, toggled):
        GL.glEnable(
            GL.GL_DEPTH_TEST
        )  # enables the depth test (used to display only "visible" faces)
        GL.glEnable(
            GL.GL_CULL_FACE
        )  # enables culling (improves performance as only "visible" faces are processed)

        self.drawingEventEnd()  # if we were drawing something end the drawing

        self.xy_grid.show()  # un-hide the grid
        self.camera.set_view_3d(
            toggled)  # reset the position of the camera for 3D view
        self.window().update_status_bar("3D VIEW")
        self.setMouseTracking(False)
        self.updateGL()  # update the rendered scene

    @pyqtSlot()
    def reset_view(self):
        self.camera.reset_view()  # reset the view
        self.updateGL()  # update the rendered scene

    def mousePressEvent(self, event):
        # when we press a mouse button on the canvas the canvas get the keyboard focus
        self.setFocus()

        # if in drawing mode
        if self.mode == Canvas3d.MODE_DRAW:
            # drawing events are only accepted in 2D View
            if self.camera.view_mode == Camera.VIEW_2D:
                self.drawingEventAddVertex(event=event)

        # if we are in "selection" or "erase" mode
        elif self.mode == Canvas3d.MODE_SELECT or self.mode == Canvas3d.MODE_ERASE:
            # selection events are only accepted in 2D View
            if self.camera.view_mode == Camera.VIEW_2D:
                event_x, event_y, z = self.camera.canvas2world(
                    event.x(), event.y())

                self.selection_box = SelectionBox(Point3(event_x, event_y, 0))

        # update the rendered scene
        self.updateGL()

        self.last_mouse_position = event.pos()
        event.accept()

    def mouseReleaseEvent(self, event):
        # if in drawing mode
        if self.mode == Canvas3d.MODE_DRAW:
            # drawing events are only accepted in 2D View
            if self.camera.view_mode == Camera.VIEW_2D:
                self.drawingEventConfirmLastVertex(event=event)

        # if we are in "selection" mode
        elif self.mode == Canvas3d.MODE_SELECT:
            # selection events are only accepted in 2D View
            if self.camera.view_mode == Camera.VIEW_2D:
                # select geometries inside the box before deleting it
                self.selected_geoms = self.selection_box.select_geometries(
                    self.renderables3d)

                self.window().console_add_line("\nSELECTED SHAPES")
                # self.parent.parent.console_add_line("\nSELECTED SHAPES")
                for g in self.selected_geoms:
                    self.window().console_add_line(str(g))

                self.selection_box = None

        # if we are in "erase" mode
        elif self.mode == Canvas3d.MODE_ERASE:
            # erase events are only accepted in 2D View
            if self.camera.view_mode == Camera.VIEW_2D:
                # select geometries inside the box before deleting it
                selected_geoms = self.selection_box.select_geometries(
                    self.renderables3d)

                for g in selected_geoms:
                    self.remove_geometry(g)

                self.selection_box = None

        # update the rendered scene
        self.updateGL()

        self.last_mouse_position = event.pos()
        event.accept()

    def mouseMoveEvent(self, event):

        if self.camera.view_mode == Camera.VIEW_2D:
            x, y, z = self.camera.canvas2world(event.x(), event.y())
            self.window().update_status_bar("(x, y): ({:.3f}, {:.3f})".format(
                x, y))

        # if moving while pressing the left button
        if event.buttons() and event.buttons() == QtCore.Qt.LeftButton:
            # if in draw mode: continue drawing
            if self.mode == Canvas3d.MODE_DRAW:
                self.drawingEventMoveLastVertex(event)

            # if we are in "selection" or "erase" mode
            elif self.mode == Canvas3d.MODE_SELECT or self.mode == Canvas3d.MODE_ERASE:
                # selection events are only accepted in 2D View
                if self.camera.view_mode == Camera.VIEW_2D:
                    event_x, event_y, z = self.camera.canvas2world(
                        event.x(), event.y())
                    x, y, z = self.camera.canvas2world(
                        self.last_mouse_position.x(),
                        self.last_mouse_position.y())
                    delta_x, delta_y = event_x - x, event_y - y
                    self.selection_box.move_corner2(Point3(
                        delta_x, delta_y, 0))

            # if in exploration mode
            elif self.mode == Canvas3d.MODE_EXPLORE:
                # if no button is held down: pan
                if QtGui.QApplication.keyboardModifiers(
                ) == QtCore.Qt.NoModifier:
                    self.panEvent(event)

                # if in 3D View
                if self.camera.view_mode == Camera.VIEW_3D:
                    # if the ctrl (cmd on mac) button is held down: rotate
                    if QtGui.QApplication.keyboardModifiers(
                    ) == QtCore.Qt.ControlModifier:
                        self.rotateEvent(event)

        # update the rendered scene
        self.updateGL()

        self.last_mouse_position = event.pos()
        event.accept()

    def keyPressEvent(self, event):
        # if in drawing mode
        if self.mode == Canvas3d.MODE_DRAW:
            # if the escape key is pressed: cancel the current drawing
            if event.key() == QtCore.Qt.Key_Escape:
                # print("pressed Esc")
                self.drawingEventCancel()
            # if either enter or return key is pressed: end the current drawing
            elif event.key() in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
                # print("pressed Enter")
                self.drawingEventEnd()
            elif event.key() == QtCore.Qt.Key_Backspace:
                self.drawingEventRemoveLastVertex()

        # update the rendered scene
        self.updateGL()

    def wheelEvent(self, event):
        # if scrolling vertically
        if event.orientation() == QtCore.Qt.Vertical:
            # if in exploration mode: zoom
            if self.mode == Canvas3d.MODE_EXPLORE:
                self.zoomEvent(event)

        # update the rendered scene
        self.updateGL()

        event.accept()

    def rotateEvent(self, event):
        delta_x = event.x() - self.last_mouse_position.x()
        # delta_y is computed the opposite way, because the canvas origin is at the up-left corner
        # with positive y-axis point downwards
        delta_y = self.last_mouse_position.y() - event.y()

        # ORBIT (i.e., rotate) the camera around the camera._target
        self.camera.orbit(delta_x, delta_y)

    def panEvent(self, event):
        delta_x = event.x() - self.last_mouse_position.x()
        # delta_y is computed the opposite way, because the canvas origin is at the up-left corner
        # with positive y-axis point downwards
        delta_y = self.last_mouse_position.y() - event.y()

        # PAN the scene by altering camera._target
        self.camera.pan(delta_x, delta_y)

    def zoomEvent(self, event):
        delta = event.delta()
        # if in 3D View mode, the zoom is obtained by changing the distance of the camera from the target
        if self.camera.view_mode == Camera.VIEW_3D:
            # MOVE the camera wrt its _target (change the distance to _target)
            self.camera.move_radial(delta)

        # else, the zoom is obtained by changing the size of the viewed area
        else:
            # ZOOM
            if delta < 0:
                self.camera.zoom(1.05)
            elif delta > 0:
                self.camera.zoom(0.95)

            x, y, z = self.camera.canvas2world(event.x(), event.y())
            self.window().update_status_bar("(x, y): ({:.3f}, {:.3f})".format(
                x, y))

    def drawingEventAddVertex(self, event):
        """if no geometry is being drawn, create one.
        add a vertex to the drawn geometry"""

        # only if in draw mode
        if self.mode == Canvas3d.MODE_DRAW:
            x, y, z = self.camera.canvas2world(event.x(), event.y())
            new_point = Point3(x, y, z)
            if self.draw_what == Canvas3d.DRAW_POINTS:
                self.currently_drawn_geom = new_point
            elif self.draw_what == Canvas3d.DRAW_SEGMENTS:
                if self.currently_drawn_geom is None:
                    self.currently_drawn_geom = Line()
                self.currently_drawn_geom.add_vertex(new_point)
            elif self.draw_what == Canvas3d.DRAW_POLYGONS:
                if self.currently_drawn_geom is None:
                    self.currently_drawn_geom = Polygon()
                self.currently_drawn_geom.add_vertex(new_point)
            elif self.draw_what == Canvas3d.DRAW_POLYLINES:
                if self.currently_drawn_geom is None:
                    self.currently_drawn_geom = LineString()
                self.currently_drawn_geom.add_vertex(new_point)

            if isinstance(self.currently_drawn_geom, Geometry):
                self.add_geometry(self.currently_drawn_geom)

    def drawingEventRemoveLastVertex(self):
        """if possible, remove the last vertex from the drawn geometry (depends on the type of geometry)"""

        # only if in draw mode
        if self.mode == Canvas3d.MODE_DRAW:
            # if a geom is being drawn
            if self.currently_drawn_geom is not None:
                # if the geometry has at least one vertex
                if len(self.currently_drawn_geom) > 0:
                    self.currently_drawn_geom.remove_vertex()

                # if the current geom has no vertices, cancel it
                if len(self.currently_drawn_geom) == 0:
                    self.drawingEventCancel()

    def drawingEventMoveLastVertex(self, event):
        """move the last drawn vertex of the currently drawn geometry"""

        # only if in draw mode
        if self.mode == Canvas3d.MODE_DRAW:
            if self.currently_drawn_geom is not None:
                x, y, z = self.camera.canvas2world(event.x(), event.y())
                if self.draw_what == Canvas3d.DRAW_POINTS:
                    self.currently_drawn_geom.set_coords(x, y, z)
                elif self.draw_what in (Canvas3d.DRAW_SEGMENTS,
                                        Canvas3d.DRAW_POLYGONS,
                                        Canvas3d.DRAW_POLYLINES):
                    self.currently_drawn_geom.update_vertex(Point3(x, y, z))

    def drawingEventConfirmLastVertex(self, event):
        """this functions does nothing,
        unless the drawn geometry can have at most a fixed number of vertices,
        in which case, end the drawing"""

        # only if in draw mode
        if self.mode == Canvas3d.MODE_DRAW:
            if self.currently_drawn_geom is not None:
                # points and segments have a limited number of vertices. When we reach this amount we end the drawing
                if isinstance(self.currently_drawn_geom, Point3) \
                   or (isinstance(self.currently_drawn_geom, Line) and len(self.currently_drawn_geom) == 2):
                    self.drawingEventEnd()

    def drawingEventCancel(self):
        """cancel the drawing event (including the removal of the geometry drawn so far from the canvas)"""

        # only if in draw mode and there is a geometry being drawn
        if self.mode == Canvas3d.MODE_DRAW and self.currently_drawn_geom is not None:
            self.remove_geometry(self.currently_drawn_geom)
            self.currently_drawn_geom = None

    def drawingEventEnd(self):
        """ends the drawing of the geometry and prepares the canvas for a new drawing"""

        # only if in draw mode and there is a geometry being drawn
        if self.mode == Canvas3d.MODE_DRAW and self.currently_drawn_geom is not None:
            # if the drawn geometry is valid
            if not self.currently_drawn_geom.is_valid():
                self.remove_geometry(self.currently_drawn_geom)
            self.currently_drawn_geom = None

    def prepare_shader_program(self, v_shader_path="", f_shader_path=""):

        v_shader_file = open(v_shader_path, 'r')
        vertex_shader_code = v_shader_file.read()
        v_shader_file.close()

        f_shader_file = open(f_shader_path, 'r')
        fragment_shader_code = f_shader_file.read()
        f_shader_file.close()

        if not self.shader_program:
            # print("The shader is None, initialize it.")
            self.shader_program = GL.glCreateProgram()
            if not self.shader_program:
                print("ERROR in shader PROGRAM creation")
                return

        # VERTEX SHADER
        # create a vertex shader
        vertex_shader = GL.glCreateShader(GL.GL_VERTEX_SHADER)
        # set shader source_vertex
        GL.glShaderSource(vertex_shader, vertex_shader_code)
        # compile shader
        GL.glCompileShader(vertex_shader)

        # FRAGMENT SHADER
        # create a fragment shader
        fragment_shader = GL.glCreateShader(GL.GL_FRAGMENT_SHADER)
        # set shader source_vertex
        GL.glShaderSource(fragment_shader, fragment_shader_code)
        # compile shader
        GL.glCompileShader(fragment_shader)

        # build and link the shader program given the vertex and the fragment shader
        GL.glAttachShader(self.shader_program, vertex_shader)
        GL.glAttachShader(self.shader_program, fragment_shader)
        GL.glLinkProgram(self.shader_program)

        # get rid of the shaders as 1. they have been compiled in the program, 2. we do not need them any longer
        GL.glDetachShader(self.shader_program, vertex_shader)
        GL.glDetachShader(self.shader_program, fragment_shader)

        # make the shader program we just compiled the default program to be run
        GL.glUseProgram(self.shader_program)

    def initializeGL(self):
        # set the background color (to white)
        self.qglClearColor(QtGui.QColor(255, 255, 255))

        GL.glDepthMask(GL.GL_TRUE)

        GL.glEnable(GL.GL_POINT_SMOOTH
                    )  # makes point smooth (looks approx like a sphere)
        GL.glPointSize(config_rendering_point_size)  # size of points

        GL.glEnable(GL.GL_LINE_SMOOTH)
        GL.glLineWidth(config_rendering_line_width)

        GL.glFrontFace(
            GL.GL_CCW
        )  # the "front" of a face is those for which vertices are seen in CCW order

        # FOR TRANSPARENCY?
        # GL.glAlphaFunc(GL.GL_GREATER, 0.1)
        # GL.glEnable(GL.GL_ALPHA_TEST)
        # FOR TRANSPARENCY?
        GL.glEnable(GL.GL_BLEND)
        GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)

        # load and link the shader program
        self.prepare_shader_program('shaders/vertex_shader.glsl',
                                    'shaders/fragment_shader.glsl')

    def resizeGL(self, width, height):
        """This function is called automatically by QT when a resize event occurs.
        We need to resize the viewport accordingly"""
        # print("resizeGL")

        # resize the viewport
        GL.glViewport(0, 0, width, height)

        # adjust the view accordingly with the new size of the canvas
        self.camera.resize_view(width, height)

    def paintGL(self):
        # print("paintGL")
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

        # bind (i.e., pass) the up-to-date view matrix to the vertex shader
        loc = GL.glGetUniformLocation(self.shader_program, "u_view")
        GL.glUniformMatrix4fv(loc, 1, GL.GL_FALSE,
                              self.camera.get_view_matrix().data())

        # bind (i.e., pass) the up-to-date projection matrix to the vertex shader
        loc = GL.glGetUniformLocation(self.shader_program, "u_projection")
        GL.glUniformMatrix4fv(loc, 1, GL.GL_FALSE,
                              self.camera.get_projection_matrix().data())

        # if visible not hidden, render the xy grid (only visible in 3D mode)
        self.xy_grid.render(self.shader_program)

        # render all the geometries in the canvas
        for renderable in self.renderables3d:
            # print("Going to paint the renderable: " + str(cube.renderable_vertex_array['position']))
            renderable.render(self.shader_program)

        if self.selection_box is not None:
            self.selection_box.render(self.shader_program)

    def add_geometry(self, *geoms):
        """
        add a geometry to the canvas (namely to the list renderables)
        :param geom: the geometry to add
        :return: None
        """
        for geom in geoms:
            self.renderables3d.add(geom)
        self.updateGL()

    def remove_geometry(self, geom):
        """
        removes the given geometry from the canvas
        :param geom: the geometry to be removed
        :return: None
        """
        self.renderables3d.remove(geom)
        self.updateGL()