12 const std::string &anim_name,
14 std::size_t tile_offset,
15 const Rgba32 &extrinsic_transparency,
16 bool is_cross_tileset)
18 if (animation.
frames().empty()) {
19 panic(
"animation must have at least one frame");
25 const auto &tiles = representative_frame.
tiles();
27 for (std::size_t i = 0; i < tiles.size(); ++i) {
43 if (lookup_map_.contains(key)) {
51 const std::size_t absolute_index = tile_offset + i;
53 lookup_map_[key] = KeyframeTileInfo{
63 total_tiles_ += tiles.size();
65 if (is_cross_tileset && animation_registrations_.contains(anim_name)) {
66 panic(
"cross-tileset animation '" + anim_name +
"' has the same name as an already-registered animation");
68 animation_registrations_.try_emplace(anim_name, AnimRegistration{tile_offset, tiles.size()});
71std::optional<AnimTileMatch>
74 KeyframeKey lookup_key{
static_cast<const PixelTile<Rgba32> &
>(tile), extrinsic_transparency};
76 const auto it = lookup_map_.find(lookup_key);
77 if (it == lookup_map_.end()) {
81 const KeyframeTileInfo &info = it->second;
87 bool effective_h_flip = info.h_flip != tile.
h_flip();
88 bool effective_v_flip = info.v_flip != tile.
v_flip();
93 info.keyframe_tile_idx,
96 info.is_cross_tileset,
102 const auto it = animation_registrations_.find(anim_name);
103 if (it == animation_registrations_.end()) {
106 return it->second.tile_offset;
111 const auto it = animation_registrations_.find(anim_name);
112 if (it == animation_registrations_.end()) {
115 return it->second.tile_count;
120 return std::ranges::any_of(animation_registrations_ | std::views::values, [tile_index](
const auto ®) {
121 return tile_index >= reg.tile_offset && tile_index < reg.tile_offset + reg.tile_count;
128 animation_registrations_.clear();
Represents a single frame of an animation, containing tiles and a frame name.
const std::vector< PixelTile< PixelType > > & tiles() const
void clear()
Clears all registered animations.
std::optional< std::size_t > tile_count_for(const std::string &anim_name) const
Returns the tile count for a registered animation.
bool is_in_animation_range(std::size_t tile_index) const
Checks whether a tile index falls within any registered animation range.
void register_animation(const std::string &anim_name, const Animation< Rgba32 > &animation, std::size_t tile_offset, const Rgba32 &extrinsic_transparency, bool is_cross_tileset=false)
Registers an animation's keyframe tiles for matching.
std::optional< AnimTileMatch > find_match(const CanonicalPixelTile< Rgba32 > &tile, const Rgba32 &extrinsic_transparency) const
Attempts to match a tile against registered animation keyframes.
std::optional< std::size_t > tile_offset_for(const std::string &anim_name) const
Returns the tile offset for a registered animation.
A complete tileset animation with name, configuration, and frame data.
bool has_key_frame() const
Checks if this animation has a key frame set.
const AnimFrame< PixelType > & key_frame() const
Returns the key frame of this animation.
const std::map< std::string, AnimFrame< PixelType > > & frames() const
A PixelTile representation that stores the canonical (lexicographically minimal) orientation among al...
bool h_flip() const
Returns the horizontal flip flag.
bool v_flip() const
Returns the vertical flip flag.
An 8x8 tile backed by literal-array-based per-pixel storage of an arbitrary pixel type.
bool is_transparent() const
Checks if this entire PixelTile is transparent (intrinsic transparency only).
Represents a 32-bit RGBA color.
void panic(const StringViewSourceLoc &s)
Unconditionally terminates the program with a panic message.
@ canonical
Export tiles in canonical form without applying flip transformations.
Result of matching a tile against animation keyframes.
std::string anim_name
Name of the animation this keyframe belongs to.