示例#1
0
 def _create_title_renderer(self):
     if self.args.test_title:
         title = self.args.test_title
     else:
         title = self.torrent_title
     size = self.args.title_size / 1024 * self.width
     self._title_renderer = TitleRenderer(title, size, self)
示例#2
0
 def _create_title_renderer(self):
     if self.args.test_title:
         title = self.args.test_title
     else:
         title = self.torrent_title
     size = self.args.title_size * self._size_factor
     self._title_renderer = TitleRenderer(title, size, self)
示例#3
0
class Waves(visualizer.Visualizer):
    def __init__(self, args):
        self._gathered_segments_layer = None
        visualizer.Visualizer.__init__(self, args,
                                       file_class=File,
                                       peer_class=Peer,
                                       segment_class=Segment)
        if self.args.peer_info:
            self.layout_managers = {"left":  LayoutManager1d(),
                                    "right": LayoutManager1d()}
        self.waves_margin = self.parse_margin_argument(self.args.waves_margin)
        
    @staticmethod
    def add_parser_arguments(parser):
        visualizer.Visualizer.add_parser_arguments(parser)
        parser.add_argument("--peer-info", action="store_true")
        parser.add_argument("--enable-title", action="store_true")
        parser.add_argument("--title-size", type=float, default=30.0)
        parser.add_argument("--test-title", type=str)
        visualizer.Visualizer.add_margin_argument(parser, "--waves-margin")

    def resized_window(self):
        self.waves_margin.update()
        self._waves_width = self.width - self.waves_margin.left - self.waves_margin.right
        self._waves_right = self.width - self.waves_margin.right
        self._waves_height = self.height - self.waves_margin.top - self.waves_margin.bottom
        self._waves_top = self.height - self.waves_margin.top
        self._title_renderer = None

    def configure_2d_projection(self):
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(0.0, self.window_width, 0.0, self.window_height, -1.0, 1.0)
        glMatrixMode(GL_MODELVIEW)

    def synth_address_received(self):
        self.subscribe_to_waveform()

    def reset(self):
        visualizer.Visualizer.reset(self)
        self.playing_segments = collections.OrderedDict()
        self.gatherer = Gatherer()
        if self._gathered_segments_layer:
            self._gathered_segments_layer.refresh()
        self._first_segment_received = False
        self._title_renderer = None

    def pan_segment(self, segment):
        # let orchestra & synth spatialize
        pass

    def InitGL(self):
        visualizer.Visualizer.InitGL(self)
        glClearColor(0.0, 0.0, 0.0, 0.0)
        self._gathered_segments_layer = self.new_layer(self._render_gathered_segments)

    def update(self):
        outdated = []
        for segment in self.playing_segments.values():
            if not segment.is_playing():
                self.gatherer.add(segment)
                outdated.append(segment.id)

        if len(outdated) > 0:
            for segment_id in outdated:
                self.playing_segments[segment_id].free()
                del self.playing_segments[segment_id]
            self._gathered_segments_layer.refresh()

    def render(self):
        self._set_gathered_color()
        self._gathered_segments_layer.draw()
        self.draw_playing_segments()

        if self.args.enable_title:
            if not self._title_renderer and (self._first_segment_received or self.args.test_title):
                self._create_title_renderer()
            if self._title_renderer:
                self._render_title()

    def _create_title_renderer(self):
        if self.args.test_title:
            title = self.args.test_title
        else:
            title = self.torrent_title
        size = self.args.title_size / 1024 * self.width
        self._title_renderer = TitleRenderer(title, size, self)

    def _render_title(self):
        if self.download_completed():
            color = self._fade_out_color()
        else:
            color = Vector3d(1,1,1)
        glColor3f(*color)
        x = self.waves_margin.left + 10.0 / 640 * self.width
        y = self.height * 0.03
        self._title_renderer.render(x, y)

    def _set_gathered_color(self):
        if self.download_completed():
            self.gathered_color = self._fade_out_color()
            self._gathered_segments_layer.refresh()
        elif self.torrent_length > 0:
            torrent_progress = float(self.gatherer.gathered_bytes()) / self.torrent_length
            self.gathered_color = GATHERED_COLOR + (WAVEFORM_COLOR - GATHERED_COLOR) * pow(torrent_progress, 20)
        else:
            self.gathered_color = GATHERED_COLOR

    def _fade_out_color(self):
        time_after_completion = max(self.now - self.torrent_download_completion_time, 0)
        if time_after_completion > FADE_OUT_DURATION:
            return Vector3d(0,0,0)
        else:
            return WAVEFORM_COLOR * pow(1 - time_after_completion/FADE_OUT_DURATION, 0.15)

    def active(self):
        return len(self.playing_segments) > 0

    def finished(self):
        if self.download_completed():
            time_after_completion = max(self.now - self.torrent_download_completion_time, 0)
            if time_after_completion > FADE_OUT_DURATION:
                return True

    def draw_playing_segments(self):
        glEnable(GL_LINE_SMOOTH)
        glHint(GL_LINE_SMOOTH_HINT, GL_NICEST)
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
        for segment in self.playing_segments.values():
            segment.render()

    def _render_gathered_segments(self):
        glBegin(GL_QUADS)
        x1 = self.waves_margin.left
        x2 = self._waves_right
        min_height = GATHERED_LINE_WIDTH * self._waves_height
        for segment in self.gatherer.pieces():
            y1 = self.byte_to_py(segment.torrent_begin)
            y2 = max(self.byte_to_py(segment.torrent_end), y1 + min_height)
            if (y2 - y1) > min_height:
                d = min((y2 - y1) * 0.2, MAX_GRADIENT_HEIGHT * self._waves_height)
                y1d = y1 + d
                y2d = y2 - d

                glColor3f(0, 0, 0)
                glVertex2f(x1, y1)

                glColor3f(*self.gathered_color)
                glVertex2f(x1, y1d)
                glVertex2f(x2, y1d)

                glColor3f(0, 0, 0)
                glVertex2f(x2, y1)



                glColor3f(0, 0, 0)
                glVertex2f(x1, y2)

                glColor3f(*self.gathered_color)
                glVertex2f(x1, y2d)
                glVertex2f(x2, y2d)

                glColor3f(0, 0, 0)
                glVertex2f(x2, y2)


                glColor3f(*self.gathered_color)
                glVertex2f(x1, y1d)
                glVertex2f(x1, y2d)
                glVertex2f(x2, y2d)
                glVertex2f(x2, y1d)
            else:
                glColor3f(0, 0, 0)
                glVertex2f(x1, y1)

                glColor3f(*self.gathered_color)
                glVertex2f(x1, y2)
                glVertex2f(x2, y2)

                glColor3f(0, 0, 0)
                glVertex2f(x2, y1)
        glEnd()

    def byte_to_py(self, byte):
        return int(self.waves_margin.bottom + self.byte_to_relative_y(byte) * self._waves_height)

    def byte_to_relative_y(self, byte):
        return float(byte) / self.torrent_length

    def handle_segment_waveform_value(self, segment, value):
        segment.append_to_waveform(value)
示例#4
0
class HeatMap(visualizer.Visualizer):
    def __init__(self, args):
        self._history_layer = None
        self._load_locations()
        visualizer.Visualizer.__init__(
            self, args, file_class=File, peer_class=Peer, segment_class=Segment)
        self._set_horizontal_scope()
        self._set_verical_scope()
        self._map_margin = self.parse_margin_argument(self.args.map_margin)

    def _set_horizontal_scope(self):
        self._hscope_min, self._hscope_max = map(float, self.args.hscope.split(":"))
        self._hscope_size = self._hscope_max - self._hscope_min

    def _set_verical_scope(self):
        self._vscope_min, self._vscope_max = map(float, self.args.vscope.split(":"))
        self._vscope_size = self._vscope_max - self._vscope_min
        
    @staticmethod
    def add_parser_arguments(parser):
        visualizer.Visualizer.add_parser_arguments(parser)
        parser.add_argument("--title-size", type=float, default=30.0)
        parser.add_argument("--disable-title", action="store_true")
        parser.add_argument("--test-title", type=str)
        parser.add_argument("--hscope", type=str, default="0:1")
        parser.add_argument("--vscope", type=str, default="0:1")
        parser.add_argument("--continents", action="store_true")
        visualizer.Visualizer.add_margin_argument(parser, "--map-margin")

    def reset(self):
        visualizer.Visualizer.reset(self)
        self.playing_segments = collections.OrderedDict()
        self._first_segment_received = False
        self._title_renderer = None

    def InitGL(self):
        visualizer.Visualizer.InitGL(self)
        glClearColor(0.0, 0.0, 0.0, 0.0)
        self._history_layer = self.new_layer(self._render_history)
        if self.args.continents:
            import world
            self._world = world.World(1.0, 1.0)
            self._continents_layer = self.new_layer(self._render_continents)

    def resized_window(self):
        self._map_margin.update()
        self._map_width = self.width - self._map_margin.left - self._map_margin.right
        self._map_height = self.height - self._map_margin.top - self._map_margin.bottom
        self._size_factor = (float(self._map_width) + self._map_height) / 2 / ((1024 + 768) / 2)

        self._marker_lists = []
        for n in range(0, MARKER_PRECISION):
            display_list = self.new_display_list_id()
            self._marker_lists.append(display_list)
            glNewList(display_list, GL_COMPILE)
            self._render_marker_circle(n)
            glEndList()

    def configure_2d_projection(self):
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(0.0, self.window_width, 0.0, self.window_height, -1.0, 1.0)
        glMatrixMode(GL_MODELVIEW)

    def _load_locations(self):
        self._locations = collections.defaultdict(int)
        for location in locations.get_locations():
            self._add_location(location)
        self._max_frequency = max(self._locations.values())

    def _add_location(self, location):
        if not location:
            return
        self._locations[Location(location)] += 1
        if self._history_layer:
            self._history_layer.refresh()

    def added_segment(self, segment):
        self._first_segment_received = True
        self.playing_segments[segment.id] = segment

    def added_peer(self, peer):
        self._add_location(peer.location)

    def render(self):
        glEnable(GL_POINT_SMOOTH)
        glHint(GL_POINT_SMOOTH_HINT, GL_NICEST)
        glEnable(GL_LINE_SMOOTH)
        glHint(GL_LINE_SMOOTH_HINT, GL_NICEST)
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

        self._update()
        if self.args.continents:
            self._continents_layer.draw()
        else:
            self._history_layer.draw()
        self._render_activity()

        if not self.args.disable_title:
            if not self._title_renderer and (self._first_segment_received or self.args.test_title):
                self._create_title_renderer()
            if self._title_renderer:
                self._render_title()

    def _render_continents(self):
        glColor4f(0.8,0.8,0.8,1)
        glLineWidth(1.0)
        for path in self._world.paths:
            self._draw_path(path)

    def _draw_path(self, path):
        glBegin(GL_LINE_STRIP)
        for x, y in path:
            self._location_vertex(x, y)
        glEnd()

    def _create_title_renderer(self):
        if self.args.test_title:
            title = self.args.test_title
        else:
            title = self.torrent_title
        size = self.args.title_size * self._size_factor
        self._title_renderer = TitleRenderer(title, size, self)

    def _render_title(self):
        glColor3f(1,1,1)
        x = self._map_margin.left + 10.0 / 640 * self.width
        y = self.height * 0.03
        self._title_renderer.render(x, y)

    def _render_history(self):
        glColor4f(0.8,0.8,0.8,1)
        for location, frequency in self._locations.iteritems():
            point_size = pow(float(frequency) / self._max_frequency, 0.15) * 4 * self._size_factor
            #point_size = max(point_size, 3)
            glPointSize(point_size)
            glBegin(GL_POINTS)
            self._location_vertex(location.x, location.y)
            glEnd()

    def _location_vertex(self, location_x, location_y):
        p = Vector2d(
            (location_x - self._hscope_min) / self._hscope_size,
            (location_y - self._vscope_min) / self._vscope_size)
        glVertex2f(
            self._map_margin.left + p.x * self._map_width,
            self._map_margin.bottom + (1-p.y) * self._map_height)

    def _render_activity(self):
        glColor4f(1,1,1,1)
        for segment in self.playing_segments.values():
            location = self.peers_by_addr[segment.peer.addr].location
            x, y = location

            # #n = int(MARKER_PRECISION * (((self.now - segment.peer.arrival_time) * 0.8))) % MARKER_PRECISION
            # n = clamp(int(segment.relative_size() * MARKER_PRECISION), 0, MARKER_PRECISION-1)
            # glPushMatrix()
            # glTranslatef(x * self.width, y * self.height, 0)
            # #self._render_marker_circle(n)
            # glCallList(self._marker_lists[n])
            # glPopMatrix()

            #size = (1.0 + 0.3 * math.sin((self.now - segment.peer.arrival_time) * 2.0)) * 8 / 640
            #glPointSize(size * self.width)
            glPointSize(max(int(segment.relative_size() * 10.0 * self._size_factor), 1))
            glBegin(GL_POINTS)
            self._location_vertex(x, y)
            glEnd()

    def _render_marker_circle(self, n):
        # t = float(n) / MARKER_PRECISION * 2*math.pi
        # radius = (1.0 + 0.15 * math.sin(t)) * 8 / 640

        stroke_radius = float(n) / MARKER_PRECISION * 8 / 640
        shadow_inner_radius = float(n) / MARKER_PRECISION * 4 / 640
        shadow_outer_radius = float(n) / MARKER_PRECISION * 12 / 640

        glColor4f(0,0,0,0.5)
        glBegin(GL_QUADS)
        for i in range(20):
            a1 = float(i) / 20 * 2*math.pi
            a2 = float(i+1) / 20 * 2*math.pi
            x1 = shadow_outer_radius * math.cos(a1) * self.min_dimension
            y1 = shadow_outer_radius * math.sin(a1) * self.min_dimension
            x2 = shadow_inner_radius * math.cos(a1) * self.min_dimension
            y2 = shadow_inner_radius * math.sin(a1) * self.min_dimension
            x3 = shadow_inner_radius * math.cos(a2) * self.min_dimension
            y3 = shadow_inner_radius * math.sin(a2) * self.min_dimension
            x4 = shadow_outer_radius * math.cos(a2) * self.min_dimension
            y4 = shadow_outer_radius * math.sin(a2) * self.min_dimension
            glVertex2f(x1, y1)
            glVertex2f(x2, y2)
            glVertex2f(x3, y3)
            glVertex2f(x4, y4)
        glEnd()

        glColor4f(1,1,1,1)
        glLineWidth(2.0 * self._size_factor)
        glBegin(GL_LINE_LOOP)
        for i in range(20):
            a = float(i) / 20 * 2*math.pi
            cx = stroke_radius * math.cos(a) * self.min_dimension
            cy = stroke_radius * math.sin(a) * self.min_dimension
            glVertex2f(cx, cy)
        glEnd()

    def _update(self):
        self._delete_outdated_segments()

    def _delete_outdated_segments(self):
        outdated = []
        for segment in self.playing_segments.values():
            if not segment.is_playing():
                outdated.append(segment.id)

        for segment_id in outdated:
            del self.playing_segments[segment_id]