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.