Documentation
¶
Overview ¶
Package atlasforge provides 2D atlas packing utilities.
The package is centered around three APIs:
* Plan: calculate deterministic sprite placement using MaxRects. * Render: render a precomputed layout into an atlas image. * Pack: one-shot helper that plans and renders in one call.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrInvalidOptions reports invalid packing options. ErrInvalidOptions = errors.New("invalid options") // ErrInvalidItem reports invalid item dimensions or identifiers. ErrInvalidItem = errors.New("invalid item") // ErrPlacementFailed reports that an item cannot be placed into an atlas. ErrPlacementFailed = errors.New("placement failed") // ErrLayoutRequired reports a missing layout for rendering. ErrLayoutRequired = errors.New("layout is required") // ErrInvalidLayout reports malformed layout dimensions. ErrInvalidLayout = errors.New("invalid layout") // ErrSourceNotFound reports missing image source for a placement ID. ErrSourceNotFound = errors.New("source not found") // ErrSourceImageMissing reports a nil image in provided sources. ErrSourceImageMissing = errors.New("source image is missing") // ErrSourceSizeMismatch reports mismatch between placement size and source image size. ErrSourceSizeMismatch = errors.New("source size mismatch") )
Functions ¶
Types ¶
type Atlas ¶
type Atlas struct {
// Image is the rendered atlas pixels.
Image image.Image `json:"-" yaml:"-"`
// Layout describes where each source item was placed in Image.
Layout Layout `json:"layout" yaml:"layout"`
}
Atlas combines rendered image and the layout used to produce it.
func Pack ¶
Pack plans and renders atlas image in a single call.
Example ¶
sprites := []Sprite{
{ID: "a", Image: image.NewRGBA(image.Rect(0, 0, 2, 2))},
{ID: "b", Image: image.NewRGBA(image.Rect(0, 0, 3, 2))},
}
opts := Options{
MinSize: 8,
MaxSize: 8,
Padding: 0,
Heuristic: HeuristicBestShortSideFit,
AllowRotate: false,
}
atlas, err := Pack(sprites, opts)
if err != nil {
fmt.Println("pack error")
return
}
fmt.Printf(
"%dx%d %d\n",
atlas.Layout.Width,
atlas.Layout.Height,
len(atlas.Layout.Placements),
)
Output: 8x8 2
type Heuristic ¶
type Heuristic int
Heuristic is the MaxRects scoring heuristic used for placement.
const ( // HeuristicBestShortSideFit minimizes the smaller leftover edge first. HeuristicBestShortSideFit Heuristic = iota // HeuristicBestLongSideFit minimizes the larger leftover edge first. HeuristicBestLongSideFit // HeuristicBestAreaFit minimizes wasted free rectangle area first. HeuristicBestAreaFit // HeuristicBottomLeft prefers lower Y, then smaller X placements. HeuristicBottomLeft // HeuristicContactPoint maximizes contact with borders/used rectangles. HeuristicContactPoint // HeuristicFirstFit places into the first matching free rectangle. // It favors planning speed over packing density. HeuristicFirstFit )
type Item ¶
type Item struct {
// ID is a unique stable identifier used in resulting Placement.ID.
ID string `json:"id" yaml:"id"`
// Width is the payload width in pixels and must be > 0.
Width int `json:"width" yaml:"width"`
// Height is the payload height in pixels and must be > 0.
Height int `json:"height" yaml:"height"`
}
Item describes a rectangular payload for layout planning.
type Layout ¶
type Layout struct {
// Placements contains one entry per input item.
// Order follows internal packing workflow, not input order guarantees.
Placements []Placement `json:"placements" yaml:"placements"`
// Width is the final atlas width in pixels.
Width int `json:"width" yaml:"width"`
// Height is the final atlas height in pixels.
Height int `json:"height" yaml:"height"`
}
Layout contains atlas dimensions and all placements.
type Options ¶
type Options struct {
// MinSize is the lower bound for each atlas side candidate.
// Plan will not produce Width/Height below this value.
MinSize int `json:"min_size" yaml:"min_size"`
// MaxSize is the upper bound for each atlas side candidate.
// Plan/Pack fail when items require a larger side.
MaxSize int `json:"max_size" yaml:"max_size"`
// Padding reserves empty pixels around each placed item.
// Higher values reduce packing density and increase atlas size.
Padding int `json:"padding" yaml:"padding"`
// AspectPenalty adds a penalty for non-square atlas shapes.
// Use 0 to disable shape bias and prioritize fit only.
AspectPenalty float64 `json:"aspect_penalty" yaml:"aspect_penalty"`
// Heuristic selects MaxRects placement scoring policy.
// It affects placement order quality and final atlas utilization.
Heuristic Heuristic `json:"heuristic" yaml:"heuristic"`
// PreferHeight controls tie-breaking for equally scored candidates.
// When true, ties prefer taller atlases over wider ones.
PreferHeight bool `json:"prefer_height" yaml:"prefer_height"`
// ForceSquare limits size search to square candidates only (w == h).
// Rectangular candidates are skipped even when they have lower area.
ForceSquare bool `json:"force_square" yaml:"force_square"`
// AllowRotate enables 90-degree clockwise item rotation.
// Rotated placements are reported via Placement.Rotated.
AllowRotate bool `json:"allow_rotate" yaml:"allow_rotate"`
}
Options controls atlas planning behavior.
func DefaultOptions ¶
func DefaultOptions() Options
DefaultOptions returns practical defaults for UI/sprite atlas packing.
type Placement ¶
type Placement struct {
// ID matches Item.ID / Sprite.ID used for this placement.
ID string `json:"id" yaml:"id"`
// X is the top-left X coordinate in atlas pixels.
X int `json:"x" yaml:"x"`
// Y is the top-left Y coordinate in atlas pixels.
Y int `json:"y" yaml:"y"`
// Width is the original source width before rotation.
Width int `json:"width" yaml:"width"`
// Height is the original source height before rotation.
Height int `json:"height" yaml:"height"`
// Rotated reports clockwise 90-degree placement during rendering.
Rotated bool `json:"rotated" yaml:"rotated"`
}
Placement describes final coordinates of one packed item.
type Source ¶
type Source struct {
// Image provides pixels for rendering.
// Bounds must match Placement width/height for the same ID.
Image image.Image `json:"-" yaml:"-"`
// ID must match Placement.ID from a planned layout.
ID string `json:"id" yaml:"id"`
}
Source binds an image payload to an item ID for rendering.
type Sprite ¶
type Sprite struct {
// Image is the source pixels used by Pack.
// It is excluded from json/yaml serialization.
Image image.Image `json:"-" yaml:"-"`
// ID is a unique stable identifier propagated into Placement.ID.
ID string `json:"id" yaml:"id"`
// Width overrides Image bounds when > 0.
// Use with care: mismatch with Image bounds causes render errors.
Width int `json:"width,omitempty" yaml:"width,omitempty"`
// Height overrides Image bounds when > 0.
// Use with care: mismatch with Image bounds causes render errors.
Height int `json:"height,omitempty" yaml:"height,omitempty"`
}
Sprite is a high-level input used by Pack.