use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct SpriteRenderData {
pub texture_path_id: i64,
pub texture_rect_x: f32,
pub texture_rect_y: f32,
pub texture_rect_width: f32,
pub texture_rect_height: f32,
pub texture_rect_offset_x: f32,
pub texture_rect_offset_y: f32,
pub atlas_rect_offset_x: f32,
pub atlas_rect_offset_y: f32,
pub downscale_multiplier: f32,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct SpriteSettings {
pub packed: bool,
pub packing_mode: i32,
pub packing_rotation: i32,
pub mesh_type: i32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpriteRect {
pub x: f32,
pub y: f32,
pub width: f32,
pub height: f32,
}
impl Default for SpriteRect {
fn default() -> Self {
Self {
x: 0.0,
y: 0.0,
width: 0.0,
height: 0.0,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpriteOffset {
pub x: f32,
pub y: f32,
}
impl Default for SpriteOffset {
fn default() -> Self {
Self { x: 0.0, y: 0.0 }
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpritePivot {
pub x: f32,
pub y: f32,
}
impl Default for SpritePivot {
fn default() -> Self {
Self { x: 0.5, y: 0.5 } }
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpriteBorder {
pub left: f32,
pub bottom: f32,
pub right: f32,
pub top: f32,
}
impl Default for SpriteBorder {
fn default() -> Self {
Self {
left: 0.0,
bottom: 0.0,
right: 0.0,
top: 0.0,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpriteInfo {
pub name: String,
pub rect: SpriteRect,
pub offset: SpriteOffset,
pub pivot: SpritePivot,
pub border: SpriteBorder,
pub pixels_to_units: f32,
pub is_polygon: bool,
pub texture_path_id: i64,
pub is_atlas_sprite: bool,
}
impl Default for SpriteInfo {
fn default() -> Self {
Self {
name: String::new(),
rect: SpriteRect::default(),
offset: SpriteOffset::default(),
pivot: SpritePivot::default(),
border: SpriteBorder::default(),
pixels_to_units: 100.0,
is_polygon: false,
texture_path_id: 0,
is_atlas_sprite: false,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Sprite {
pub name: String,
pub rect_x: f32,
pub rect_y: f32,
pub rect_width: f32,
pub rect_height: f32,
pub offset_x: f32,
pub offset_y: f32,
pub border_x: f32,
pub border_y: f32,
pub border_z: f32,
pub border_w: f32,
pub pixels_to_units: f32,
pub pivot_x: f32,
pub pivot_y: f32,
pub extrude: u8,
pub is_polygon: bool,
pub render_data: SpriteRenderData,
pub settings: SpriteSettings,
pub atlas_tags: Vec<String>,
pub sprite_atlas_path_id: Option<i64>,
}
impl Default for Sprite {
fn default() -> Self {
Self {
name: String::new(),
rect_x: 0.0,
rect_y: 0.0,
rect_width: 0.0,
rect_height: 0.0,
offset_x: 0.0,
offset_y: 0.0,
border_x: 0.0,
border_y: 0.0,
border_z: 0.0,
border_w: 0.0,
pixels_to_units: 100.0,
pivot_x: 0.5,
pivot_y: 0.5,
extrude: 1,
is_polygon: false,
render_data: SpriteRenderData::default(),
settings: SpriteSettings::default(),
atlas_tags: Vec::new(),
sprite_atlas_path_id: None,
}
}
}
#[derive(Debug, Clone)]
pub struct SpriteConfig {
pub extract_images: bool,
pub process_atlas: bool,
pub max_sprite_size: Option<(u32, u32)>,
pub apply_transformations: bool,
}
impl Default for SpriteConfig {
fn default() -> Self {
Self {
extract_images: true,
process_atlas: true,
max_sprite_size: None,
apply_transformations: true,
}
}
}
#[derive(Debug, Clone)]
pub struct SpriteResult {
pub sprite: Sprite,
pub image_data: Option<Vec<u8>>,
pub warnings: Vec<String>,
pub errors: Vec<String>,
}
impl SpriteResult {
pub fn new(sprite: Sprite) -> Self {
Self {
sprite,
image_data: None,
warnings: Vec::new(),
errors: Vec::new(),
}
}
pub fn with_image(mut self, image_data: Vec<u8>) -> Self {
self.image_data = Some(image_data);
self
}
pub fn add_warning(&mut self, warning: String) {
self.warnings.push(warning);
}
pub fn add_error(&mut self, error: String) {
self.errors.push(error);
}
pub fn has_warnings(&self) -> bool {
!self.warnings.is_empty()
}
pub fn has_errors(&self) -> bool {
!self.errors.is_empty()
}
pub fn has_image(&self) -> bool {
self.image_data.is_some()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SpriteAtlas {
pub name: String,
pub texture_path_id: i64,
pub sprites: Vec<SpriteInfo>,
pub packed_sprites: Vec<String>,
}
impl Sprite {
pub fn get_rect(&self) -> SpriteRect {
SpriteRect {
x: self.rect_x,
y: self.rect_y,
width: self.rect_width,
height: self.rect_height,
}
}
pub fn get_offset(&self) -> SpriteOffset {
SpriteOffset {
x: self.offset_x,
y: self.offset_y,
}
}
pub fn get_pivot(&self) -> SpritePivot {
SpritePivot {
x: self.pivot_x,
y: self.pivot_y,
}
}
pub fn get_border(&self) -> SpriteBorder {
SpriteBorder {
left: self.border_x,
bottom: self.border_y,
right: self.border_z,
top: self.border_w,
}
}
pub fn has_border(&self) -> bool {
self.border_x > 0.0 || self.border_y > 0.0 || self.border_z > 0.0 || self.border_w > 0.0
}
pub fn is_atlas_sprite(&self) -> bool {
self.sprite_atlas_path_id.is_some()
}
pub fn get_area(&self) -> f32 {
self.rect_width * self.rect_height
}
pub fn get_aspect_ratio(&self) -> f32 {
if self.rect_height > 0.0 {
self.rect_width / self.rect_height
} else {
1.0
}
}
}
impl SpriteRect {
pub fn contains(&self, x: f32, y: f32) -> bool {
x >= self.x && x <= self.x + self.width && y >= self.y && y <= self.y + self.height
}
pub fn area(&self) -> f32 {
self.width * self.height
}
pub fn center(&self) -> (f32, f32) {
(self.x + self.width / 2.0, self.y + self.height / 2.0)
}
}