Skip to content

atlas_gen

FreeBodyEngine.build.atlas_gen #

AtlasGen(paths=None, images=None, atlas_size=1024) #

Packs a set of named images into one square texture atlas, using Node's binary-tree packer and growing the atlas (doubling its size) whenever the current size can't fit everything.

Builds the set of images to pack, from paths (a {disk_path: atlas_name} map - each opened lazily here) and/or an already-loaded images ({atlas_name: Image}) map. At least one must yield a non-empty set of images.

Raises:

Type Description
ValueError

if no images were provided by either argument.

atlas_size = atlas_size instance-attribute #

images = {} instance-attribute #

positions = {} instance-attribute #

build_atlas() #

Packs every image into a single square atlas, doubling self.atlas_size and repacking from scratch whenever the current size fails to fit them all. Fills self.positions with each image's {name: (x, y, w, h)} placement, as fractions of the final atlas size (ready to use as UV rects). Returns the packed atlas as an RGBA Image.

prepare_images() #

Sorts images largest-first (by the longer of width/height), so the packer places the hardest-to-fit images before smaller ones - packing smallest-first tends to fragment free space and fail to fit large images later.

save(path, metadata_path=None) #

Builds the atlas and saves it to path; if metadata_path is given, also writes self.positions there as JSON.

Node(x, y, w, h) #

A rectangular free region of the atlas being packed (a binary-tree/ guillotine bin packer) - insert() either places an image directly into this region or recurses into its already-split children.

A w x h free region at atlas position (x, y), not yet split or occupied.

down = None instance-attribute #

right = None instance-attribute #

used = False instance-attribute #

insert(img) #

Attempts to place img into this region, or - once split - into whichever child region has room. Returns the Node img was placed at (its (x, y) is where the caller should paste it), or None if it doesn't fit anywhere under this node.

Placing an image that doesn't exactly fill the region splits it into a right child (same height as img, covering the leftover width) and a down child (full width, covering the leftover height), so the remaining space stays available for later images.