module Resource.Image.Atlas ( Atlas(..) , fromTileSize , fromImageSize ) where import RIO import Geomancy (UVec2, Vec2, uvec2, withUVec2, vec2) -- | Regular grid atlas data Atlas = Atlas { sizeTiles :: UVec2 , sizePx :: UVec2 , tileSizePx :: UVec2 , marginPx :: UVec2 , uvScale :: Vec2 } deriving (Eq, Show, Generic) fromTileSize :: UVec2 -> UVec2 -> UVec2 -> Atlas fromTileSize sizeTiles tileSizePx marginPx = Atlas{..} where sizePx = sizeTiles * tileSizePx + (sizeTiles - 1) * marginPx uvScale = fromU tileSizePx / fromU sizePx fromImageSize :: UVec2 -> UVec2 -> UVec2 -> Either UVec2 Atlas fromImageSize sizePx tileSizePx marginPx = if leftovers == totalMargins then Right Atlas{..} else Left leftovers where totalMargins = (sizeTiles - 1) * marginPx (sizeTiles, leftovers) = withUVec2 sizePx \aw ah -> withUVec2 tileSizePx \tw th -> let (w, wRem) = aw `divMod` tw (h, hRem) = ah `divMod` th in ( uvec2 w h , uvec2 wRem hRem ) uvScale = fromU tileSizePx / fromU sizePx fromU :: UVec2 -> Vec2 fromU u = withUVec2 u \x y -> vec2 (fromIntegral x) (fromIntegral y)