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
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