Repository: bevyengine/bevy
File: crates/bevy_sprite_render/src/tilemap_chunk/tile_orientation.rs (Rust)

Code before:
#[derive(Debug, Clone, Copy, Reflect, Default, PartialEq, Eq, Hash)]
#[reflect(Default, Clone, PartialEq, Hash)]
#[repr(u8)]
pub enum TileOrientation {
    #[default]
    Default = 0b000,
    Rotate90 = 0b101,
    Rotate180 = 0b110,
    Rotate270 = 0b011,
    MirrorX = 0b100,
    MirrorXRotate90 = 0b111,
    MirrorXRotate180 = 0b010,
    MirrorXRotate270 = 0b001,
}

impl TileOrientation {
    /// This bit is set in the enum value if the tile is mirrored in the x axis
    const MIRROR_X_BIT: u8 = 0b100;

    /// This bit is set in the enum value if the tile is mirrored in the y axis
    const MIRROR_Y_BIT: u8 = 0b010;

    /// This bit is set in the enum value if the tile has the x and y axes swapped
    const SWAP_XY_BIT: u8 = 0b001;

    /// Create a [`TileOrientation`] based on whether each component mirror/swap is applied
    pub fn from_bools(mirror_x: bool, mirror_y: bool, swap_xy: bool) -> TileOrientation {
        match (mirror_x, mirror_y, swap_xy) {
            (false, false, false) => TileOrientation::Default,
            (true, false, true) => TileOrientation::Rotate90,
            (true, true, false) => TileOrientation::Rotate180,
            (false, true, true) => TileOrientation::Rotate270,
            (true, false, false) => TileOrientation::MirrorX,
            (true, true, true) => TileOrientation::MirrorXRotate90,
            (false, true, false) => TileOrientation::MirrorXRotate180,
            (false, false, true) => TileOrientation::MirrorXRotate270,
        }
    }

    /// True if the tile is mirrored in the x axis
    pub fn mirror_x(&self) -> bool {
        (*self as u8) & Self::MIRROR_X_BIT != 0
    }

    /// True if the tile is mirrored in the y axis
    pub fn mirror_y(&self) -> bool {
        (*self as u8) & Self::MIRROR_Y_BIT != 0
    }

    /// True if the tile has the x and y axes swapped
    pub fn swap_xy(&self) -> bool {

Review comment (suggestion):
It might be good to clarify the ordering of the mirrors vs the swap somewhere since
(x, y) -[swaps]-> (y, x) -[mirror x]-> (-y, x) is not equal to (x, y) -[mirror x]-> (-x, y) -[swaps]-> (y, -x)

from the impl of `apply_to_ivec2` i assume the swap is applied and then the mirror, in which case (x, y) -> (-y, x) is what `Rotate90` represents, but then that means `Rotate90` is a CCW rotation, which is contradictory to the doc comment if i'm understanding correctly

Code after:
/// The order in which the mirroring is performed matters - the tile is first mirrored
/// horizontally (if specified), then vertically, then finally diagonally, in the UV
/// coordinate system.
///
/// Note that different coordinate systems are used for UV mapping and Bevy world
/// coordinates (e.g. in UV maps, the y component increases towards the bottom of
/// the tile, in Bevy it increases towards the top). This means that the ordering
/// in which the mirroring is applied differs in different coordinate systems.
///
/// The ordering of the enum starts from the default orientation (no rotation or mirroring),
/// then we have successive 90 degree counter-clockwise rotations. Then we have a tile
/// mirrored horizontally, and then the results of successive 90 degree counter-clockwise
/// rotations of the mirrored tile.
///
/// The enum values can be easily converted to the format used for tile indices in [Tiled](https://www.mapeditor.org/) maps,
/// where bits 31, 30 and 29 correspond to bits 2, 1 and 0 of this enum's values.
/// So for a given enum value, we can just use `value << 29` to produce the bits required
/// in a Tiled index.
#[derive(Debug, Clone, Copy, Reflect, Default, PartialEq, Eq, Hash)]
#[reflect(Default, Clone, PartialEq, Hash)]
#[repr(u8)]
pub enum TileOrientation {
    #[default]
    Default = 0b000,
    Rotate90 = 0b011,
    Rotate180 = 0b110,
    Rotate270 = 0b101,
    MirrorH = 0b100,
    MirrorHRotate90 = 0b001,
    MirrorHRotate180 = 0b010,
    MirrorHRotate270 = 0b111,
}

impl TileOrientation {
    /// This bit is set in the enum value if the tile is mirrored horizontally
    const MIRROR_H_BIT: u8 = 0b100;

    /// This bit is set in the enum value if the tile is mirrored vertically
    const MIRROR_V_BIT: u8 = 0b010;

    /// This bit is set in the enum value if the tile is mirrored diagonally
    const MIRROR_D_BIT: u8 = 0b001;

    /// Create a [`TileOrientation`] based on whether each mirror is applied
    pub fn from_bools(mirror_h: bool, mirror_v: bool, mirror_d: bool) -> TileOrientation {
        match (mirror_h, mirror_v, mirror_d) {
            (false, false, false) => TileOrientation::Default,
            (false, true, true) => TileOrientation::Rotate90,
            (true, true, false) => TileOrientation::Rotate180,
            (true, false, true) => TileOrientation::Rotate270,
            (true, false, false) => TileOrientation::MirrorH,