Example #1
0
def _generate_mesh(way: Way) -> Geom:
    """Generate mesh for a Way."""
    geometry = way.geometry
    rows = 2 * len(geometry.segments) + 2

    vertex_data = GeomVertexData(str(way.id), VERTEX_FORMAT, Geom.UH_static)
    vertex_data.set_num_rows(rows)
    vertex_writer = GeomVertexWriter(vertex_data, 'vertex')
    normal_writer = GeomVertexWriter(vertex_data, 'normal')
    texcoord_writer = GeomVertexWriter(vertex_data, 'texcoord')

    start_z = way.start.level * LEVEL_HEIGHT
    end_z = way.end.level * LEVEL_HEIGHT
    lanes_float = float(way.total_lane_count)

    segment = geometry.segments[0]
    for vertex in (segment.start_left, segment.start_right):
        vertex_writer.add_data3f(vertex.x, vertex.y, start_z)
        normal_writer.add_data3f(0.0, 0.0, 1.0)
    texture_v = 0.0
    texcoord_writer.add_data2f(0.0, texture_v)
    texcoord_writer.add_data2f(lanes_float, texture_v)

    lengths = [s.length() for s in geometry.segments]
    total_len = sum(lengths)

    for segment, acc_len in zip(geometry.segments, accumulate(lengths)):
        height = start_z + (end_z - start_z) * acc_len / total_len
        for vertex in (segment.end_left, segment.end_right):
            vertex_writer.add_data3f(vertex.x, vertex.y, height)
            normal_writer.add_data3f(0.0, 0.0, 1.0)
        texture_v = acc_len / LANE_WIDTH
        texcoord_writer.add_data2f(0.0, texture_v)
        texcoord_writer.add_data2f(lanes_float, texture_v)

    primitive = GeomTristrips(Geom.UH_static)
    primitive.add_consecutive_vertices(0, rows)
    primitive.close_primitive()
    geom = Geom(vertex_data)
    geom.add_primitive(primitive)
    return geom
Example #2
0
def _generate_mesh(points: List[Point]) -> Geom:
    """Generate mesh for a Path."""
    def calc_color(param):
        return interpolate_rgb(START_COLOR, END_COLOR, param)

    if len(points) < 2:
        return Geom()

    vertex_data = GeomVertexData('path', VERTEX_FORMAT, Geom.UH_static)
    vertex_data.set_num_rows(2 * len(points) + 1)
    vertex_writer = GeomVertexWriter(vertex_data, 'vertex')
    normal_writer = GeomVertexWriter(vertex_data, 'normal')
    color_writer = GeomVertexWriter(vertex_data, 'color')

    length = sum(p1.distance(p2) for p1, p2 in window_iter(points))
    vector = points[1] - points[0]
    distance = vector.norm()
    position = distance / length
    vector = vector.normalized()

    width_vector = LANE_WIDTH * 0.5 * vector.rotated_left()
    for vertex in (points[0] + width_vector, points[0] - width_vector):
        vertex_writer.add_data3f(vertex.x, vertex.y, HEIGHT)
        normal_writer.add_data3f(0.0, 0.0, 1.0)
        color_writer.add_data4f(*START_COLOR)

    last_vector = vector
    for point, next_ in zip(islice(points, 1, None), islice(points, 2, None)):
        vector = next_ - point
        distance = vector.norm()
        vector = vector.normalized()
        try:
            bisector = (last_vector + vector).normalized()
            width_vector = (sec(bisector, vector) * 0.5 * LANE_WIDTH
                            * bisector.rotated_left())
        except ZeroDivisionError:
            width_vector = vector.rotated_right() * 0.5 * LANE_WIDTH
        color = calc_color(position)
        for vertex in (point + width_vector, point - width_vector):
            vertex_writer.add_data3f(vertex.x, vertex.y, HEIGHT)
            normal_writer.add_data3f(0.0, 0.0, 1.0)
            color_writer.add_data4f(*color)
        position = position + distance / length
        last_vector = vector

    point = points[-1]
    width_vector = 0.5 * LANE_WIDTH * last_vector.rotated_left()

    distance = LANE_WIDTH if distance > LANE_WIDTH else distance / 2
    vector = -last_vector * distance

    for vertex in (point + width_vector + vector,
                   point - width_vector + vector,
                   point):
        vertex_writer.add_data3f(vertex.x, vertex.y, HEIGHT)
        normal_writer.add_data3f(0.0, 0.0, 1.0)
        color_writer.add_data4f(*END_COLOR)

    primitive = GeomTristrips(Geom.UH_static)
    primitive.add_consecutive_vertices(0, 2 * len(points) + 1)
    primitive.close_primitive()
    geom = Geom(vertex_data)
    geom.add_primitive(primitive)
    return geom