Exemple #1
0
    def load_3d_texture(cls, fname, tile_size_x, tile_size_y=None, num_tiles=None):
        """ Loads a texture from the given filename and dimensions. If only
        one dimensions is specified, the other dimensions are assumed to be
        equal. This internally loads the texture into ram, splits it into smaller
        sub-images, and then calls the load_3d_texture from the Panda loader """

        # Generate a unique name to prevent caching
        tempfile_name = "$$SliceLoaderTemp-" + str(time.time()) + "/"

        # For quaddratic textures
        tile_size_y = tile_size_x if tile_size_y is None else tile_size_y
        num_tiles = tile_size_x if num_tiles is None else num_tiles

        # Load sliced image from disk
        source = PNMImage(fname)
        width = source.get_x_size()

        # Find slice properties
        num_cols = width // tile_size_x
        temp = PNMImage(
            tile_size_x, tile_size_y, source.get_num_channels(), source.get_maxval())

        # Construct a ramdisk to write the files to
        vfs = VirtualFileSystem.get_global_ptr()
        ramdisk = VirtualFileMountRamdisk()
        vfs.mount(ramdisk, tempfile_name, 0)

        # Extract all slices and write them to the virtual disk
        for z_slice in range(num_tiles):
            slice_x = (z_slice % num_cols) * tile_size_x
            slice_y = (z_slice // num_cols) * tile_size_y
            temp.copy_sub_image(source, 0, 0, slice_x, slice_y, tile_size_x, tile_size_y)
            temp.write(tempfile_name + str(z_slice) + ".png")

        # Load the de-sliced texture from the ramdisk
        texture_handle = Globals.loader.load3DTexture(tempfile_name + "/#.png")

        # This should never trigger, but can't hurt to have
        assert texture_handle.get_x_size() == tile_size_x
        assert texture_handle.get_y_size() == tile_size_y
        assert texture_handle.get_z_size() == num_tiles

        # Finally unmount the ramdisk
        vfs.unmount(ramdisk)

        return texture_handle
    def load_sliced_3d_texture(cls,
                               fname,
                               tile_size_x,
                               tile_size_y=None,
                               num_tiles=None):
        """ Loads a texture from the given filename and dimensions. If only
        one dimensions is specified, the other dimensions are assumed to be
        equal. This internally loads the texture into ram, splits it into smaller
        sub-images, and then calls the load_3d_texture from the Panda loader """

        tempfile_name = "/$$slice_loader_temp-" + str(time.time()) + "/"
        tile_size_y = tile_size_x if tile_size_y is None else tile_size_y
        num_tiles = tile_size_x if num_tiles is None else num_tiles

        # Load sliced image from disk
        tex_handle = cls.load_texture(fname)
        source = PNMImage()
        tex_handle.store(source)
        width = source.get_x_size()

        # Find slice properties
        num_cols = width // tile_size_x
        temp_img = PNMImage(tile_size_x, tile_size_y,
                            source.get_num_channels(), source.get_maxval())

        # Construct a ramdisk to write the files to
        vfs = VirtualFileSystem.get_global_ptr()
        ramdisk = VirtualFileMountRamdisk()
        vfs.mount(ramdisk, tempfile_name, 0)

        # Extract all slices and write them to the virtual disk
        for z_slice in range(num_tiles):
            slice_x = (z_slice % num_cols) * tile_size_x
            slice_y = (z_slice // num_cols) * tile_size_y
            temp_img.copy_sub_image(source, 0, 0, slice_x, slice_y,
                                    tile_size_x, tile_size_y)
            temp_img.write(tempfile_name + str(z_slice) + ".png")

        # Load the de-sliced texture from the ramdisk
        texture_handle = cls.load_3d_texture(tempfile_name + "/#.png")
        vfs.unmount(ramdisk)

        return texture_handle
Exemple #3
0
def get_images(spritesheet: Texture, sprite_sizes: tuple) -> list:
    """Cut provided spritesheet texture into separate PNMImage objects"""
    if _has_remainder(spritesheet, sprite_sizes):
        raise exceptions.InvalidSpriteSize(spritesheet.get_name(),
                                           sprite_sizes)

    sprite_x, sprite_y = sprite_sizes
    columns, rows = _get_columns_and_rows(spritesheet, sprite_sizes)

    # This is safety check to ensure there wont be any weird effects during cutting,
    # caused by texture autorescale. In order to circuimvent this, you need to
    # set "textures-power-2 none" in your Config.rpc.
    # There seem to be setters and getters to deal with it on per-texture basis,
    # but thus far I couldnt figure out how to make them work properly #TODO
    if spritesheet.getTexturesPower2():
        if not _is_power_of_two(columns) or not _is_power_of_two(rows):
            raise exceptions.InvalidSpriteSize(spritesheet.get_name(),
                                               sprite_sizes)

    # Extract texture's image from memory
    sheet_image = Image()
    spritesheet.store(sheet_image)

    images = []
    for row in range(0, rows):
        log.debug(f"Processing row{row}")
        for column in range(0, columns):
            log.debug(f"Processing column {column}")
            # THIS WAS BUGGED - I HAD TO FLIP IT
            x = column * sprite_x
            y = row * sprite_y
            # passing amount of channels is important to allow transparency
            pic = Image(sprite_x, sprite_y, sheet_image.get_num_channels())
            pic.blendSubImage(sheet_image, 0, 0, x, y, sprite_x, sprite_y, 1.0)
            images.append(pic)

    log.debug(f"Got following images: {images}")
    return images
Exemple #4
0
    def load_sliced_3d_texture(cls, fname, tile_size_x, tile_size_y=None, num_tiles=None):
        """ Loads a texture from the given filename and dimensions. If only
        one dimensions is specified, the other dimensions are assumed to be
        equal. This internally loads the texture into ram, splits it into smaller
        sub-images, and then calls the load_3d_texture from the Panda loader """

        tempfile_name = "/$$slice_loader_temp-" + str(time.time()) + "/"
        tile_size_y = tile_size_x if tile_size_y is None else tile_size_y
        num_tiles = tile_size_x if num_tiles is None else num_tiles

        # Load sliced image from disk
        source = PNMImage(fname)
        width = source.get_x_size()

        # Find slice properties
        num_cols = width // tile_size_x
        temp_img = PNMImage(
            tile_size_x, tile_size_y, source.get_num_channels(), source.get_maxval())

        # Construct a ramdisk to write the files to
        vfs = VirtualFileSystem.get_global_ptr()
        ramdisk = VirtualFileMountRamdisk()
        vfs.mount(ramdisk, tempfile_name, 0)

        # Extract all slices and write them to the virtual disk
        for z_slice in range(num_tiles):
            slice_x = (z_slice % num_cols) * tile_size_x
            slice_y = (z_slice // num_cols) * tile_size_y
            temp_img.copy_sub_image(source, 0, 0, slice_x, slice_y, tile_size_x, tile_size_y)
            temp_img.write(tempfile_name + str(z_slice) + ".png")

        # Load the de-sliced texture from the ramdisk
        texture_handle = cls.load_3d_texture(tempfile_name + "/#.png")
        vfs.unmount(ramdisk)

        return texture_handle
Exemple #5
0
 def get_num_channels(self, filepath):
     image = PNMImage()
     image.read(filepath)
     return image.get_num_channels()