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
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
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
def get_num_channels(self, filepath): image = PNMImage() image.read(filepath) return image.get_num_channels()