Ejemplo n.º 1
0
    def create_objects(self):
        if not self.isValid():
            self.invalid_count += 1
            print 'Radarwidget: Context not valid in create_objects, count=%d' % self.invalid_count
            QTimer.singleShot(100, self.create_objects)
            return

        # Make the radarwidget context current, necessary when create_objects is not called from initializeGL
        self.makeCurrent()

        # Initialize font for radar view with specified settings
        self.font = Font()
        self.font.create_font_array(char_height=text_texture_size,
                                    font_family=font_family,
                                    font_weight=font_weight)
        self.font.init_shader(self.text_shader)

        # Load and bind world texture
        max_texture_size = gl.glGetIntegerv(gl.GL_MAX_TEXTURE_SIZE)
        print 'Maximum supported texture size: %d' % max_texture_size
        for i in [16384, 8192, 4096]:
            if max_texture_size >= i:
                fname = 'data/graphics/world.%dx%d.dds' % (i, i / 2)
                print 'Loading texture ' + fname
                self.map_texture = self.bindTexture(fname)
                break

        # Create initial empty buffers for aircraft position, orientation, label, and color
        self.achdgbuf = create_empty_buffer(MAX_NAIRCRAFT * 4,
                                            usage=gl.GL_STREAM_DRAW)
        self.aclatbuf = create_empty_buffer(MAX_NAIRCRAFT * 4,
                                            usage=gl.GL_STREAM_DRAW)
        self.aclonbuf = create_empty_buffer(MAX_NAIRCRAFT * 4,
                                            usage=gl.GL_STREAM_DRAW)
        self.acaltbuf = create_empty_buffer(MAX_NAIRCRAFT * 4,
                                            usage=gl.GL_STREAM_DRAW)
        self.actasbuf = create_empty_buffer(MAX_NAIRCRAFT * 4,
                                            usage=gl.GL_STREAM_DRAW)
        self.accolorbuf = create_empty_buffer(MAX_NAIRCRAFT * 3,
                                              usage=gl.GL_STREAM_DRAW)
        self.aclblbuf = create_empty_buffer(MAX_NAIRCRAFT * 24,
                                            usage=gl.GL_STREAM_DRAW)
        self.confcpabuf = create_empty_buffer(MAX_NCONFLICTS * 16,
                                              usage=gl.GL_STREAM_DRAW)
        self.polyprevbuf = create_empty_buffer(MAX_POLYPREV_SEGMENTS * 8,
                                               usage=gl.GL_DYNAMIC_DRAW)
        self.allpolysbuf = create_empty_buffer(MAX_ALLPOLYS_SEGMENTS * 16,
                                               usage=gl.GL_DYNAMIC_DRAW)
        self.routebuf = create_empty_buffer(MAX_ROUTE_LENGTH * 8,
                                            usage=gl.GL_DYNAMIC_DRAW)
        self.routewplatbuf = create_empty_buffer(MAX_ROUTE_LENGTH * 4,
                                                 usage=gl.GL_DYNAMIC_DRAW)
        self.routewplonbuf = create_empty_buffer(MAX_ROUTE_LENGTH * 4,
                                                 usage=gl.GL_DYNAMIC_DRAW)
        self.routelblbuf = create_empty_buffer(MAX_ROUTE_LENGTH * 12,
                                               usage=gl.GL_DYNAMIC_DRAW)

        # ------- Map ------------------------------------
        self.map = RenderObject(gl.GL_TRIANGLE_FAN, vertex_count=4)
        mapvertices = np.array([(-90.0, 540.0), (-90.0, -540.0),
                                (90.0, -540.0), (90.0, 540.0)],
                               dtype=np.float32)
        texcoords = np.array([(1, 3), (1, 0), (0, 0), (0, 3)],
                             dtype=np.float32)
        self.map.bind_attrib(ATTRIB_VERTEX, 2, mapvertices)
        self.map.bind_attrib(ATTRIB_TEXCOORDS, 2, texcoords)

        # ------- Coastlines -----------------------------
        self.coastlines = RenderObject(gl.GL_LINES)
        coastvertices, coastindices = load_coastlines()
        self.coastlines.bind_attrib(ATTRIB_VERTEX, 2, coastvertices)
        self.coastlines.bind_attrib(ATTRIB_COLOR,
                                    3,
                                    np.array(lightblue2, dtype=np.uint8),
                                    datatype=gl.GL_UNSIGNED_BYTE,
                                    normalize=True,
                                    instance_divisor=1)
        self.vcount_coast = len(coastvertices)
        self.coastindices = coastindices
        del coastvertices

        # ------- Runways --------------------------------
        self.runways = RenderObject(gl.GL_TRIANGLES)
        self.runways.bind_attrib(ATTRIB_VERTEX, 2, self.vbuf_runways)
        self.runways.bind_attrib(ATTRIB_COLOR,
                                 3,
                                 np.array(grey, dtype=np.uint8),
                                 datatype=gl.GL_UNSIGNED_BYTE,
                                 normalize=True,
                                 instance_divisor=1)
        self.runways.set_vertex_count(len(self.vbuf_runways) / 2)

        #---------Runway Thresholds-----------------------
        self.thresholds = RenderObject(gl.GL_TRIANGLES)
        self.thresholds.bind_attrib(ATTRIB_VERTEX, 2, self.vbuf_rwythr)
        self.thresholds.bind_attrib(ATTRIB_COLOR,
                                    3,
                                    np.array(white, dtype=np.uint8),
                                    datatype=gl.GL_UNSIGNED_BYTE,
                                    normalize=True,
                                    instance_divisor=1)
        self.thresholds.set_vertex_count(len(self.vbuf_rwythr) / 2)

        # ------- Taxiways -------------------------------
        self.taxiways = RenderObject(gl.GL_TRIANGLES)
        self.taxiways.bind_attrib(ATTRIB_VERTEX, 2, self.vbuf_asphalt)
        self.taxiways.bind_attrib(ATTRIB_COLOR,
                                  3,
                                  np.array(grey, dtype=np.uint8),
                                  datatype=gl.GL_UNSIGNED_BYTE,
                                  normalize=True,
                                  instance_divisor=1)
        self.taxiways.set_vertex_count(len(self.vbuf_asphalt) / 2)

        # ------- Pavement -------------------------------
        self.pavement = RenderObject(gl.GL_TRIANGLES)
        self.pavement.bind_attrib(ATTRIB_VERTEX, 2, self.vbuf_concrete)
        self.pavement.bind_attrib(ATTRIB_COLOR,
                                  3,
                                  np.array(lightgrey, dtype=np.uint8),
                                  datatype=gl.GL_UNSIGNED_BYTE,
                                  normalize=True,
                                  instance_divisor=1)
        self.pavement.set_vertex_count(len(self.vbuf_concrete) / 2)

        # Polygon preview object
        self.polyprev = RenderObject(gl.GL_LINE_LOOP)
        self.polyprev.bind_attrib(ATTRIB_VERTEX, 2, self.polyprevbuf)
        self.polyprev.bind_attrib(ATTRIB_COLOR,
                                  3,
                                  np.array(lightblue, dtype=np.uint8),
                                  datatype=gl.GL_UNSIGNED_BYTE,
                                  normalize=True,
                                  instance_divisor=1)

        # Fixed polygons
        self.allpolys = RenderObject(gl.GL_LINES)
        self.allpolys.bind_attrib(ATTRIB_VERTEX, 2, self.allpolysbuf)
        self.allpolys.bind_attrib(ATTRIB_COLOR,
                                  3,
                                  np.array(blue, dtype=np.uint8),
                                  datatype=gl.GL_UNSIGNED_BYTE,
                                  normalize=True,
                                  instance_divisor=1)

        # ------- SSD object -----------------------------
        self.ssd = RenderObject(gl.GL_POINTS)
        self.ssd.bind_attrib(ATTRIB_LAT0, 1, self.aclatbuf, instance_divisor=1)
        self.ssd.bind_attrib(ATTRIB_LON0, 1, self.aclonbuf, instance_divisor=1)
        self.ssd.bind_attrib(ATTRIB_ALT0, 1, self.acaltbuf, instance_divisor=1)
        self.ssd.bind_attrib(ATTRIB_TAS0, 1, self.actasbuf, instance_divisor=1)
        self.ssd.bind_attrib(ATTRIB_TRK0, 1, self.achdgbuf, instance_divisor=1)
        self.ssd.bind_attrib(ATTRIB_LAT1, 1, self.aclatbuf)
        self.ssd.bind_attrib(ATTRIB_LON1, 1, self.aclonbuf)
        self.ssd.bind_attrib(ATTRIB_ALT1, 1, self.acaltbuf)
        self.ssd.bind_attrib(ATTRIB_TAS1, 1, self.actasbuf)
        self.ssd.bind_attrib(ATTRIB_TRK1, 1, self.achdgbuf)

        # ------- Circle ---------------------------------
        # Create a new VAO (Vertex Array Object) and bind it
        self.protectedzone = RenderObject(gl.GL_LINE_LOOP,
                                          vertex_count=self.vcount_circle)
        circlevertices = np.transpose(
            np.array(
                (2.5 * nm *
                 np.cos(np.linspace(0.0, 2.0 * np.pi, self.vcount_circle)),
                 2.5 * nm *
                 np.sin(np.linspace(0.0, 2.0 * np.pi, self.vcount_circle))),
                dtype=np.float32))
        self.protectedzone.bind_attrib(ATTRIB_VERTEX, 2, circlevertices)
        self.protectedzone.bind_attrib(ATTRIB_LAT,
                                       1,
                                       self.aclatbuf,
                                       instance_divisor=1)
        self.protectedzone.bind_attrib(ATTRIB_LON,
                                       1,
                                       self.aclonbuf,
                                       instance_divisor=1)
        self.protectedzone.bind_attrib(ATTRIB_COLOR,
                                       3,
                                       self.accolorbuf,
                                       datatype=gl.GL_UNSIGNED_BYTE,
                                       normalize=True,
                                       instance_divisor=1)

        # ------- A/C symbol -----------------------------
        self.ac_symbol = RenderObject(gl.GL_TRIANGLE_FAN, vertex_count=4)
        acvertices = np.array([(0.0, 0.5 * ac_size),
                               (-0.5 * ac_size, -0.5 * ac_size),
                               (0.0, -0.25 * ac_size),
                               (0.5 * ac_size, -0.5 * ac_size)],
                              dtype=np.float32)
        self.ac_symbol.bind_attrib(ATTRIB_VERTEX, 2, acvertices)
        self.ac_symbol.bind_attrib(ATTRIB_LAT,
                                   1,
                                   self.aclatbuf,
                                   instance_divisor=1)
        self.ac_symbol.bind_attrib(ATTRIB_LON,
                                   1,
                                   self.aclonbuf,
                                   instance_divisor=1)
        self.ac_symbol.bind_attrib(ATTRIB_ORIENTATION,
                                   1,
                                   self.achdgbuf,
                                   instance_divisor=1)
        self.ac_symbol.bind_attrib(ATTRIB_COLOR,
                                   3,
                                   self.accolorbuf,
                                   datatype=gl.GL_UNSIGNED_BYTE,
                                   normalize=True,
                                   instance_divisor=1)
        self.aclabels = self.font.prepare_text_instanced(
            self.aclblbuf, (8, 3),
            self.aclatbuf,
            self.aclonbuf,
            self.accolorbuf,
            char_size=text_size,
            vertex_offset=(ac_size, -0.5 * ac_size))

        # ------- Conflict CPA lines ---------------------
        self.cpalines = RenderObject(gl.GL_LINES)
        self.cpalines.bind_attrib(ATTRIB_VERTEX, 2, self.confcpabuf)
        self.cpalines.bind_attrib(ATTRIB_COLOR,
                                  3,
                                  np.array(amber, dtype=np.uint8),
                                  datatype=gl.GL_UNSIGNED_BYTE,
                                  normalize=True,
                                  instance_divisor=1)

        # ------- Aircraft Route -------------------------
        self.route = RenderObject(gl.GL_LINES)
        self.route.bind_attrib(ATTRIB_VERTEX, 2, self.routebuf)
        self.route.bind_attrib(ATTRIB_COLOR,
                               3,
                               np.array(magenta, dtype=np.uint8),
                               datatype=gl.GL_UNSIGNED_BYTE,
                               normalize=True,
                               instance_divisor=1)
        self.routelbl = self.font.prepare_text_instanced(
            self.routelblbuf, (12, 1),
            self.routewplatbuf,
            self.routewplonbuf,
            char_size=text_size,
            vertex_offset=(wpt_size, 0.5 * wpt_size))

        # ------- Waypoints ------------------------------
        self.nwaypoints = len(self.navdb.wplat)
        self.waypoints = RenderObject(gl.GL_LINE_LOOP,
                                      vertex_count=3,
                                      n_instances=self.nwaypoints)
        wptvertices = np.array([(0.0, 0.5 * wpt_size),
                                (-0.5 * wpt_size, -0.5 * wpt_size),
                                (0.5 * wpt_size, -0.5 * wpt_size)],
                               dtype=np.float32)  # a triangle
        self.waypoints.bind_attrib(ATTRIB_VERTEX, 2, wptvertices)

        # Sort based on id string length
        llid = sorted(zip(self.navdb.wpid, self.navdb.wplat, self.navdb.wplon),
                      key=lambda i: len(i[0]) > 3)
        wplat = [lat for (wpid, lat, lon) in llid]
        wplon = [lon for (wpid, lon, lon) in llid]
        self.wptlatbuf = self.waypoints.bind_attrib(ATTRIB_LAT,
                                                    1,
                                                    np.array(wplat,
                                                             dtype=np.float32),
                                                    instance_divisor=1)
        self.wptlonbuf = self.waypoints.bind_attrib(ATTRIB_LON,
                                                    1,
                                                    np.array(wplon,
                                                             dtype=np.float32),
                                                    instance_divisor=1)
        wptids = ''
        self.nnavaids = 0
        for wptid in llid:
            if len(wptid[0]) <= 3:
                self.nnavaids += 1
            wptids += wptid[0].ljust(5)
        self.wptlabels = self.font.prepare_text_instanced(
            np.array(wptids, dtype=np.string_), (5, 1),
            self.wptlatbuf,
            self.wptlonbuf,
            char_size=text_size,
            vertex_offset=(wpt_size, 0.5 * wpt_size))
        del wptids

        # ------- Airports -------------------------------
        self.nairports = len(self.navdb.aptlat)
        self.airports = RenderObject(gl.GL_LINE_LOOP,
                                     vertex_count=4,
                                     n_instances=self.nairports)
        aptvertices = np.array([(-0.5 * apt_size, -0.5 * apt_size),
                                (0.5 * apt_size, -0.5 * apt_size),
                                (0.5 * apt_size, 0.5 * apt_size),
                                (-0.5 * apt_size, 0.5 * apt_size)],
                               dtype=np.float32)  # a square
        self.airports.bind_attrib(ATTRIB_VERTEX, 2, aptvertices)
        indices = self.navdb.aptype.argsort()
        aplat = np.array(self.navdb.aptlat[indices], dtype=np.float32)
        aplon = np.array(self.navdb.aptlon[indices], dtype=np.float32)
        aptypes = self.navdb.aptype[indices]
        apnames = np.array(self.navdb.aptid)
        apnames = apnames[indices]
        # The number of large, large+med, and large+med+small airports
        self.nairports = [
            aptypes.searchsorted(2),
            aptypes.searchsorted(3), self.nairports
        ]

        self.aptlatbuf = self.airports.bind_attrib(ATTRIB_LAT,
                                                   1,
                                                   aplat,
                                                   instance_divisor=1)
        self.aptlonbuf = self.airports.bind_attrib(ATTRIB_LON,
                                                   1,
                                                   aplon,
                                                   instance_divisor=1)
        aptids = ''
        for aptid in apnames:
            aptids += aptid.ljust(4)
        self.aptlabels = self.font.prepare_text_instanced(
            np.array(aptids, dtype=np.string_), (4, 1),
            self.aptlatbuf,
            self.aptlonbuf,
            char_size=text_size,
            vertex_offset=(apt_size, 0.5 * apt_size))
        del aptids

        # Unbind VAO, VBO
        RenderObject.unbind_all()

        # Set initial values for the global uniforms
        self.globaldata.set_wrap(self.wraplon, self.wrapdir)
        self.globaldata.set_pan_and_zoom(self.panlat, self.panlon, self.zoom)

        # Clean up memory
        del self.vbuf_asphalt, self.vbuf_concrete, self.vbuf_runways, self.vbuf_rwythr

        self.initialized = True
Ejemplo n.º 2
0
    def create_objects(self):
        self.mcp = RenderObject(gl.GL_TRIANGLES,
                                vertex=np.array(rect(-1, -1, 2, 2),
                                                dtype=np.float32))
        self.mcp_texture = load_texture('mcp737.png')
        self.btn_tex = load_texture('btn_led.png')

        self.lcd_tex = load_lcd_font()

        v_mcp_text = []
        for pos in [
                0.0, 0.03, 0.06, 0.31, 0.34, 0.37, 0.4, 0.43, 0.644, 0.674,
                0.704, 0.955, 0.985, 1.015, 1.045, 1.075, 1.22, 1.25, 1.28,
                1.31, 1.34, 1.69, 1.72, 1.75
        ]:
            v, t = Font.char(-0.886 + pos, 0.45, 0.03, 0.25)
            v_mcp_text += v

        self.mcp_text = RenderObject(gl.GL_TRIANGLES,
                                     vertex=np.array(v_mcp_text,
                                                     dtype=np.float32))
        self.lcd_charcoords = np.zeros(24 * 6, dtype=np.float32)
        self.lcdbuf = self.mcp_text.bind_attrib(1,
                                                1,
                                                self.lcd_charcoords,
                                                datatype=gl.GL_FLOAT)

        btn_leds = []
        for pos in [(-0.74, -0.75), (-0.645, -0.75), (-0.37, -0.75),
                    (-0.232, -0.75), (-0.09, -0.75), (0.105, -0.75),
                    (0.2, -0.75), (-0.37, 0.5), (-0.09, 0.5), (-0.09, -0.125),
                    (0.575, 0.34), (0.575, -0.34), (0.684, 0.34),
                    (0.684, -0.34)]:
            btn_leds += rect(pos[0], pos[1], 0.055, 0.075)
        btn_color = np.zeros(14 * 6 * 4, dtype=np.uint8)
        self.btn_leds = RenderObject(gl.GL_TRIANGLES,
                                     vertex=np.array(btn_leds,
                                                     dtype=np.float32),
                                     color=btn_color)

        # Button up/down indicator
        w, h, offset = 0.04, 0.16, 0.04
        triangles = np.array([
            -w, offset, 0.0, offset + h, w, offset, -w, -offset, 0.0,
            -offset - h, w, -offset
        ],
                             dtype=np.float32)
        col_triangles = np.array(6 * [255, 255, 255, 180], dtype=np.uint8)
        self.updown = RenderObject(gl.GL_TRIANGLES,
                                   vertex=triangles,
                                   color=col_triangles)

        # Use the same font as the radarwidget
        self.font = Font()
        self.font.create_font_array('../../data/graphics/font/')
        self.font.init_shader(self.text_shader)

        edge = np.zeros(120, dtype=np.float32)
        edge[0:120:2] = 1.4 * np.sin(np.radians(np.arange(-60, 60, 2)))
        edge[1:120:2] = 1.4 * np.cos(np.radians(np.arange(-60, 60, 2)))
        self.edge = RenderObject(gl.GL_LINE_STRIP, vertex=edge, color=white)

        arcs = []
        for i in range(1, 4):
            for angle in range(-60, 60, max(2, 6 - 2 * i)):
                arcs.append(float(i) * 0.35 * sin(radians(angle)))
                arcs.append(float(i) * 0.35 * cos(radians(angle)))
                if i == 4:
                    arcs.append(float(i) * 0.35 * sin(radians(angle + 2)))
                    arcs.append(float(i) * 0.35 * cos(radians(angle + 2)))
        arcs = np.array(arcs, dtype=np.float32)
        self.arcs = RenderObject(gl.GL_LINES, vertex=arcs, color=white)

        mask = []
        for angle in range(-60, 60, 2):
            mask.append(1.4 * sin(radians(angle)))
            mask.append(10.0)
            mask.append(1.4 * sin(radians(angle)))
            mask.append(1.4 * cos(radians(angle)))
        mask = np.array(mask, dtype=np.float32)
        self.mask = RenderObject(gl.GL_TRIANGLE_STRIP,
                                 vertex=mask,
                                 color=black)

        ticks = np.zeros(288, dtype=np.float32)
        for i in range(72):
            ticktop = 1.46 if i % 6 == 0 else (1.44 if i % 2 == 0 else 1.42)
            ticks[4 * i:4 * i + 2] = (1.4 * sin(radians(i * 5)),
                                      1.4 * cos(radians(i * 5)))
            ticks[4 * i + 2:4 * i + 4] = (ticktop * sin(radians(i * 5)),
                                          ticktop * cos(radians(i * 5)))
        self.ticks = RenderObject(gl.GL_LINES, vertex=ticks, color=white)

        ticklbls = np.zeros(24 * 36, dtype=np.float32)
        texcoords = np.zeros(36 * 36, dtype=np.float32)

        for i in range(36):
            if i % 3 == 0:
                w, h, y = 0.045, 0.09, 1.48
            else:
                w, h, y = 0.035, 0.07, 1.46
            tmp = [(-w, h + y), (-w, y), (0.0, h + y), (0.0, h + y), (-w, y),
                   (0.0, y), (0.0, h + y), (0.0, y), (w, h + y), (w, h + y),
                   (0.0, y), (w, y)]

            # numerics start at ASCII 48
            c1 = i / 10 + 48
            c2 = i % 10 + 48
            texcoords[36 * i:36 * i + 18] = [
                0, 0, c1, 0, 1, c1, 1, 0, c1, 1, 0, c1, 0, 1, c1, 1, 1, c1
            ]
            texcoords[36 * i + 18:36 * i + 36] = [
                0, 0, c2, 0, 1, c2, 1, 0, c2, 1, 0, c2, 0, 1, c2, 1, 1, c2
            ]
            angle = radians(10 * (36 - i))
            rot = np.array([[cos(angle), -sin(angle)],
                            [sin(angle), cos(angle)]])
            for j in range(12):
                ticklbls[24 * i + 2 * j:24 * i + 2 * j + 2] = rot.dot(tmp[j])

        self.ticklbls = RenderObject(gl.GL_TRIANGLES,
                                     vertex=ticklbls,
                                     color=white,
                                     texcoords=texcoords)

        vown = np.array([
            0.0, 0.0, 0.0, -0.12, 0.065, -0.03, -0.065, -0.03, 0.022, -0.1,
            -0.022, -0.1
        ],
                        dtype=np.float32)
        self.ownship = RenderObject(gl.GL_LINES, vertex=vown, color=yellow)

        self.spdlabel_text = self.font.prepare_text_string(
            'GS    TAS', 0.05, white, (-0.98, 1.6))
        self.spdlabel_val = self.font.prepare_text_string(
            '  000    000', 0.05, green, (-0.97, 1.6))

        self.initialized = True
        # Unbind everything
        RenderObject.unbind_all()