#![allow(dead_code)]
use crate::Dimensions;
use crate::Instance;
use crate::Point;
use crate::Rect;
use crate::Scaling;
use crate::SpriteBatch;
use crate::SpriteSheet;
use crate::Translation;
use std::rc::Rc;
pub(crate) struct SpriteMap {
batch: SpriteBatch,
dimensions: SpriteMapDimensions,
default_dst_dim: Dimensions,
border_trim_factor: [f32; 2],
}
impl SpriteMap {
pub fn new<D, DD>(
sheet: Rc<SpriteSheet>,
dimensions: D,
default_dst_dim: DD,
border_trim_factor: [f32; 2],
) -> Self
where
D: Into<SpriteMapDimensions>,
DD: Into<Dimensions>,
{
assert!(0.0 <= border_trim_factor[0] && border_trim_factor[0] <= 1.0);
assert!(0.0 <= border_trim_factor[1] && border_trim_factor[1] <= 1.0);
let batch = SpriteBatch::new(sheet);
Self {
batch,
dimensions: dimensions.into(),
default_dst_dim: default_dst_dim.into(),
border_trim_factor,
}
}
pub fn nrows(&self) -> u32 {
self.dimensions.nrows()
}
pub fn ncols(&self) -> u32 {
self.dimensions.ncols()
}
pub fn cell_index(&self, row_col: [u32; 2]) -> u32 {
self.dimensions.cell_index(row_col)
}
pub fn cell_coord(&self, cell_index: u32) -> [u32; 2] {
self.dimensions.cell_coord(cell_index)
}
pub fn set_cell(&mut self, instance_index: usize, cell_index: u32) {
let src_rect = self.rect_for_cell(cell_index);
self.batch.get_mut(instance_index).set_src(src_rect);
}
pub fn get_mut(&mut self, instance_index: usize) -> &mut Instance {
self.batch.get_mut(instance_index)
}
pub fn get(&self, instance_index: usize) -> &Instance {
self.batch.get(instance_index)
}
pub fn add<P: Into<Point>>(&mut self, center: P, cell_index: u32) {
let center = center.into();
let src_rect = self.rect_for_cell(cell_index);
let dst_rect = self.dst_rect(center);
self.batch.add(
Instance::builder()
.src(src_rect)
.dest(dst_rect)
.rotate(0.0)
.build(),
);
}
pub fn rect_for_cell(&self, cell_index: u32) -> Rect {
self.dimensions
.rect_for_cell(cell_index, self.border_trim_factor)
}
fn dst_rect(&self, center: Point) -> Rect {
let half_dim = self.default_dst_dim / 2.0;
[center - half_dim, center + half_dim].into()
}
pub fn move_to<P: Into<Point>>(&mut self, instance_index: usize, new_center: P) {
let new_dst_rect = self.dst_rect(new_center.into());
self.batch.get_mut(instance_index).set_dest(new_dst_rect);
}
pub fn batch(&self) -> &SpriteBatch {
&self.batch
}
pub fn translation(&self) -> Translation {
self.batch.translation()
}
pub fn set_translation(&mut self, translation: Translation) {
self.batch.set_translation(translation)
}
pub fn scale(&self) -> Scaling {
self.batch.scale()
}
pub fn set_scale(&mut self, scale: Scaling) {
self.batch.set_scale(scale)
}
pub fn cell_width(&self) -> f32 {
self.dimensions.cell_width()
}
pub fn cell_height(&self) -> f32 {
self.dimensions.cell_height()
}
}
pub struct SpriteMapDimensions {
nrows: u32,
ncols: u32,
}
impl SpriteMapDimensions {
pub fn nrows(&self) -> u32 {
self.nrows
}
pub fn ncols(&self) -> u32 {
self.ncols
}
fn rect_for_cell(&self, cell_index: u32, border_trim_factor: [f32; 2]) -> Rect {
let [trim_factor_x, trim_factor_y] = border_trim_factor;
let [row, col] = self.cell_coord(cell_index);
let cell_width = self.cell_width();
let cell_height = self.cell_height();
let ul_x = cell_width * (col as f32 + trim_factor_x / 2.0);
let ul_y = cell_height * (row as f32 + trim_factor_y / 2.0);
let lr_x = ul_x + cell_width * (1.0 - trim_factor_x);
let lr_y = ul_y + cell_height * (1.0 - trim_factor_y);
[ul_x, ul_y, lr_x, lr_y].into()
}
pub fn cell_index(&self, row_col: [u32; 2]) -> u32 {
let [row, col] = row_col;
row * self.ncols + col
}
pub fn cell_coord(&self, cell_index: u32) -> [u32; 2] {
let row = cell_index / self.ncols;
let col = cell_index % self.ncols;
[row, col]
}
fn cell_width(&self) -> f32 {
1.0 / self.ncols as f32
}
fn cell_height(&self) -> f32 {
1.0 / self.nrows as f32
}
}
impl From<[u32; 2]> for SpriteMapDimensions {
fn from(dim: [u32; 2]) -> SpriteMapDimensions {
SpriteMapDimensions {
nrows: dim[0],
ncols: dim[1],
}
}
}