Beispiel #1
0
def export_sign(gltf: GLTF, name, ob: Sign):
    _ = get_resource_path("sign_generic/main.gltf")
    tname = ob.get_name_texture()
    logger.info(f"t = {type(ob)} tname = {tname}")
    fn_texture = get_texture_file(tname)[0]
    uri = os.path.join("textures/signs", os.path.basename(fn_texture))
    data = read_bytes_from_file(fn_texture)

    def transform(g: GLTF) -> GLTF:
        rf = FileResource(uri, data=data)
        g.resources.append(rf)
        g.model.images[0] = Image(name=tname, uri=uri)
        return g

    index = embed_external(gltf, _, key=tname, transform=transform)
    # M = SE3_roty(np.pi/5)
    M = SE3_rotz(-np.pi / 2)
    n2 = Node(matrix=gm(M), children=[index])
    return add_node(gltf, n2)
Beispiel #2
0
def export_gltf(dm: DuckietownMap, outdir: str, background: bool = True):
    gltf = GLTF()
    # setattr(gltf, 'md52PV', {})

    scene_index = add_scene(gltf, Scene(nodes=[]))

    map_nodes = []
    it: IterateByTestResult

    tiles = list(iterate_by_class(dm, Tile))
    if not tiles:
        raise ZValueError("no tiles?")
    for it in tiles:
        tile = cast(Tile, it.object)
        name = it.fqn[-1]
        fn = tile.fn
        fn_normal = tile.fn_normal
        fn_emissive = tile.fn_emissive
        fn_metallic_roughness = tile.fn_metallic_roughness
        fn_occlusion = tile.fn_occlusion
        material_index = make_material(
            gltf,
            doubleSided=False,
            baseColorFactor=[1, 1, 1, 1.0],
            fn=fn,
            fn_normals=fn_normal,
            fn_emissive=fn_emissive,
            fn_metallic_roughness=fn_metallic_roughness,
            fn_occlusion=fn_occlusion,
        )
        mi = get_square()
        mesh_index = add_polygon(
            gltf,
            name + "-mesh",
            vertices=mi.vertices,
            texture=mi.textures,
            colors=mi.color,
            normals=mi.normals,
            material=material_index,
        )
        node1_index = add_node(gltf, Node(mesh=mesh_index))

        i, j = ij_from_tilename(name)
        c = (i + j) % 2
        color = [1, 0, 0, 1.0] if c else [0, 1, 0, 1.0]
        add_back = False
        if add_back:

            material_back = make_material(gltf, doubleSided=False, baseColorFactor=color)
            back_mesh_index = add_polygon(
                gltf,
                name + "-mesh",
                vertices=mi.vertices,
                texture=mi.textures,
                colors=mi.color,
                normals=mi.normals,
                material=material_back,
            )

            flip = np.diag([1.0, 1.0, -1.0, 1.0])
            flip[2, 3] = -0.01
            back_index = add_node(gltf, Node(mesh=back_mesh_index, matrix=gm(flip)))
        else:
            back_index = None

        tile_transform = it.transform_sequence
        tile_matrix2d = tile_transform.asmatrix2d().m
        s = dm.tile_size
        scale = np.diag([s, s, s, 1])
        tile_matrix = SE3_from_SE2(tile_matrix2d)
        tile_matrix = tile_matrix @ scale @ SE3_rotz(-np.pi / 2)

        tile_matrix_float = list(tile_matrix.T.flatten())
        if back_index is not None:
            children = [node1_index, back_index]
        else:
            children = [node1_index]
        tile_node = Node(name=name, matrix=tile_matrix_float, children=children)
        tile_node_index = add_node(gltf, tile_node)

        map_nodes.append(tile_node_index)

    if background:
        bg_index = add_background(gltf)
        add_node_to_scene(gltf, scene_index, bg_index)

    exports = {
        "Sign": export_sign,
        # XXX: the tree model is crewed up
        "Tree": export_tree,
        # "Tree": None,
        "Duckie": export_duckie,
        "DB18": export_DB18,
        # "Bus": export_bus,
        # "Truck": export_truck,
        # "House": export_house,
        "TileMap": None,
        "TrafficLight": export_trafficlight,
        "LaneSegment": None,
        "PlacedObject": None,
        "DuckietownMap": None,
        "Tile": None,
    }

    for it in iterate_by_class(dm, PlacedObject):
        ob = it.object

        K = type(ob).__name__
        if isinstance(ob, Sign):
            K = "Sign"

        if K not in exports:
            logger.warn(f"cannot convert {type(ob).__name__}")
            continue

        f = exports[K]
        if f is None:
            continue
        thing_index = f(gltf, it.fqn[-1], ob)

        tile_transform = it.transform_sequence
        tile_matrix2d = tile_transform.asmatrix2d().m
        tile_matrix = SE3_from_SE2(tile_matrix2d) @ SE3_rotz(np.pi / 2)
        sign_node_index = add_node(gltf, Node(children=[thing_index]))
        tile_matrix_float = list(tile_matrix.T.flatten())
        tile_node = Node(name=it.fqn[-1], matrix=tile_matrix_float, children=[sign_node_index])
        tile_node_index = add_node(gltf, tile_node)
        map_nodes.append(tile_node_index)

    mapnode = Node(name="tiles", children=map_nodes)
    map_index = add_node(gltf, mapnode)
    add_node_to_scene(gltf, scene_index, map_index)

    # add_node_to_scene(model, scene_index, node1_index)
    yfov = np.deg2rad(60)
    camera = Camera(
        name="perpcamera",
        type="perspective",
        perspective=PerspectiveCameraInfo(aspectRatio=4 / 3, yfov=yfov, znear=0.01, zfar=1000),
    )
    gltf.model.cameras.append(camera)

    t = np.array([2, 2, 0.15])
    matrix = look_at(pos=t, target=np.array([0, 2, 0]))
    cam_index = add_node(gltf, Node(name="cameranode", camera=0, matrix=list(matrix.T.flatten())))
    add_node_to_scene(gltf, scene_index, cam_index)

    cleanup_model(gltf)

    fn = os.path.join(outdir, "main.gltf")
    make_sure_dir_exists(fn)
    logger.info(f"writing to {fn}")
    gltf.export(fn)
    if True:
        data = read_ustring_from_utf8_file(fn)

        j = json.loads(data)
        data2 = json.dumps(j, indent=2)
        write_ustring_to_utf8_file(data2, fn)

    fnb = os.path.join(outdir, "main.glb")
    logger.info(f"writing to {fnb}")
    gltf.export(fnb)
    verify_trimesh = False
    if verify_trimesh:
        res = trimesh.load(fn)
        # camera_pose, _ = res.graph['cameranode']
        # logger.info(res=res)
        import pyrender

        scene = pyrender.Scene.from_trimesh_scene(res)
def add_background(gltf: GLTF) -> int:
    model = gltf.model
    resources = gltf.resources
    root = "pannello %02d.pdf.jpg"
    found = []
    for i in range(1, 27):
        basename = root % i
        try:
            fn = get_resource_path(basename)
        except KeyError:
            logger.warn(f"not found {basename!r}")
        else:
            found.append(fn)

    found = found[:9]
    n = len(found)
    if n == 0:
        raise ValueError(root)
    from .export import make_material
    from .export import get_square
    from .export import add_polygon
    from .export import add_node
    from .export import gm

    dist = 30
    fov_y = np.deg2rad(45)
    nodes_panels = []
    for i, fn in enumerate(found):
        # if i > 5:
        #     break
        material_index = make_material(gltf,
                                       doubleSided=True,
                                       baseColorFactor=[0.5, 0.5, 0.5, 1.0],
                                       fn_emissive=fn
                                       # fn=fn, fn_normals=None
                                       )
        print(fn, material_index)

        mi = get_square()

        mesh_index = add_polygon(
            gltf,
            f"bg-{i}",
            vertices=mi.vertices,
            texture=mi.textures,
            colors=mi.color,
            normals=mi.normals,
            material=material_index,
        )
        v = (np.pi * 2) / n
        theta = v * i

        a = 2 * np.tan((2 * np.pi / n) / 2) * dist
        matrix = (SE3_rotz(theta) @ SE3_trans(np.array(
            (dist, 0, 0))) @ SE3_roty(np.pi / 2) @ SE3_rotz(np.pi / 2)
                  @ np.diag(np.array(
                      (a, a, 1, 1))) @ SE3_trans(np.array([0, 0.35, 0])))

        node1_index = add_node(
            gltf, Node(name=f"panel-{i}", mesh=mesh_index, matrix=gm(matrix)))
        nodes_panels.append(node1_index)
    node = Node(children=nodes_panels)
    return add_node(gltf, node)