unity_asset_decode/sprite/
types.rs

1//! Sprite type definitions
2//!
3//! This module defines all the data structures used for Unity Sprite processing.
4
5use serde::{Deserialize, Serialize};
6
7/// Sprite render data
8///
9/// Contains information about how a sprite is rendered, including texture coordinates
10/// and atlas information.
11#[derive(Debug, Clone, Default, Serialize, Deserialize)]
12pub struct SpriteRenderData {
13    pub texture_path_id: i64,
14    pub texture_rect_x: f32,
15    pub texture_rect_y: f32,
16    pub texture_rect_width: f32,
17    pub texture_rect_height: f32,
18    pub texture_rect_offset_x: f32,
19    pub texture_rect_offset_y: f32,
20    pub atlas_rect_offset_x: f32,
21    pub atlas_rect_offset_y: f32,
22    pub downscale_multiplier: f32,
23}
24
25/// Sprite settings
26///
27/// Contains packing and mesh generation settings for sprites.
28#[derive(Debug, Clone, Default, Serialize, Deserialize)]
29pub struct SpriteSettings {
30    pub packed: bool,
31    pub packing_mode: i32,
32    pub packing_rotation: i32,
33    pub mesh_type: i32,
34}
35
36/// Sprite rectangle information
37///
38/// Defines the rectangular area of a sprite within its texture.
39#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct SpriteRect {
41    pub x: f32,
42    pub y: f32,
43    pub width: f32,
44    pub height: f32,
45}
46
47impl Default for SpriteRect {
48    fn default() -> Self {
49        Self {
50            x: 0.0,
51            y: 0.0,
52            width: 0.0,
53            height: 0.0,
54        }
55    }
56}
57
58/// Sprite offset information
59///
60/// Defines the offset of a sprite from its original position.
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct SpriteOffset {
63    pub x: f32,
64    pub y: f32,
65}
66
67impl Default for SpriteOffset {
68    fn default() -> Self {
69        Self { x: 0.0, y: 0.0 }
70    }
71}
72
73/// Sprite pivot information
74///
75/// Defines the pivot point of a sprite (0,0 to 1,1 normalized coordinates).
76#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct SpritePivot {
78    pub x: f32,
79    pub y: f32,
80}
81
82impl Default for SpritePivot {
83    fn default() -> Self {
84        Self { x: 0.5, y: 0.5 } // Center pivot by default
85    }
86}
87
88/// Sprite border information (for 9-slice sprites)
89///
90/// Defines the border sizes for 9-slice sprite rendering.
91#[derive(Debug, Clone, Serialize, Deserialize)]
92pub struct SpriteBorder {
93    pub left: f32,
94    pub bottom: f32,
95    pub right: f32,
96    pub top: f32,
97}
98
99impl Default for SpriteBorder {
100    fn default() -> Self {
101        Self {
102            left: 0.0,
103            bottom: 0.0,
104            right: 0.0,
105            top: 0.0,
106        }
107    }
108}
109
110/// Comprehensive sprite information
111///
112/// Contains all the information needed to fully describe a sprite.
113#[derive(Debug, Clone, Serialize, Deserialize)]
114pub struct SpriteInfo {
115    pub name: String,
116    pub rect: SpriteRect,
117    pub offset: SpriteOffset,
118    pub pivot: SpritePivot,
119    pub border: SpriteBorder,
120    pub pixels_to_units: f32,
121    pub is_polygon: bool,
122    pub texture_path_id: i64,
123    pub is_atlas_sprite: bool,
124}
125
126impl Default for SpriteInfo {
127    fn default() -> Self {
128        Self {
129            name: String::new(),
130            rect: SpriteRect::default(),
131            offset: SpriteOffset::default(),
132            pivot: SpritePivot::default(),
133            border: SpriteBorder::default(),
134            pixels_to_units: 100.0,
135            is_polygon: false,
136            texture_path_id: 0,
137            is_atlas_sprite: false,
138        }
139    }
140}
141
142/// Sprite object representation
143///
144/// Main sprite structure containing all sprite data and metadata.
145#[derive(Debug, Clone, Serialize, Deserialize)]
146pub struct Sprite {
147    pub name: String,
148    pub rect_x: f32,
149    pub rect_y: f32,
150    pub rect_width: f32,
151    pub rect_height: f32,
152    pub offset_x: f32,
153    pub offset_y: f32,
154    pub border_x: f32,
155    pub border_y: f32,
156    pub border_z: f32,
157    pub border_w: f32,
158    pub pixels_to_units: f32,
159    pub pivot_x: f32,
160    pub pivot_y: f32,
161    pub extrude: u8,
162    pub is_polygon: bool,
163    pub render_data: SpriteRenderData,
164    pub settings: SpriteSettings,
165
166    // Atlas reference
167    pub atlas_tags: Vec<String>,
168    pub sprite_atlas_path_id: Option<i64>,
169}
170
171impl Default for Sprite {
172    fn default() -> Self {
173        Self {
174            name: String::new(),
175            rect_x: 0.0,
176            rect_y: 0.0,
177            rect_width: 0.0,
178            rect_height: 0.0,
179            offset_x: 0.0,
180            offset_y: 0.0,
181            border_x: 0.0,
182            border_y: 0.0,
183            border_z: 0.0,
184            border_w: 0.0,
185            pixels_to_units: 100.0,
186            pivot_x: 0.5,
187            pivot_y: 0.5,
188            extrude: 1,
189            is_polygon: false,
190            render_data: SpriteRenderData::default(),
191            settings: SpriteSettings::default(),
192            atlas_tags: Vec::new(),
193            sprite_atlas_path_id: None,
194        }
195    }
196}
197
198/// Sprite processing configuration
199#[derive(Debug, Clone)]
200pub struct SpriteConfig {
201    /// Whether to extract sprite images
202    pub extract_images: bool,
203    /// Whether to process atlas sprites
204    pub process_atlas: bool,
205    /// Maximum sprite size to process
206    pub max_sprite_size: Option<(u32, u32)>,
207    /// Whether to apply sprite transformations
208    pub apply_transformations: bool,
209}
210
211impl Default for SpriteConfig {
212    fn default() -> Self {
213        Self {
214            extract_images: true,
215            process_atlas: true,
216            max_sprite_size: None,
217            apply_transformations: true,
218        }
219    }
220}
221
222/// Sprite processing result
223#[derive(Debug, Clone)]
224pub struct SpriteResult {
225    pub sprite: Sprite,
226    pub image_data: Option<Vec<u8>>,
227    pub warnings: Vec<String>,
228    pub errors: Vec<String>,
229}
230
231impl SpriteResult {
232    pub fn new(sprite: Sprite) -> Self {
233        Self {
234            sprite,
235            image_data: None,
236            warnings: Vec::new(),
237            errors: Vec::new(),
238        }
239    }
240
241    pub fn with_image(mut self, image_data: Vec<u8>) -> Self {
242        self.image_data = Some(image_data);
243        self
244    }
245
246    pub fn add_warning(&mut self, warning: String) {
247        self.warnings.push(warning);
248    }
249
250    pub fn add_error(&mut self, error: String) {
251        self.errors.push(error);
252    }
253
254    pub fn has_warnings(&self) -> bool {
255        !self.warnings.is_empty()
256    }
257
258    pub fn has_errors(&self) -> bool {
259        !self.errors.is_empty()
260    }
261
262    pub fn has_image(&self) -> bool {
263        self.image_data.is_some()
264    }
265}
266
267/// Sprite atlas information
268#[derive(Debug, Clone, Serialize, Deserialize, Default)]
269pub struct SpriteAtlas {
270    pub name: String,
271    pub texture_path_id: i64,
272    pub sprites: Vec<SpriteInfo>,
273    pub packed_sprites: Vec<String>,
274}
275
276/// Helper functions for sprite types
277impl Sprite {
278    /// Get sprite rectangle as SpriteRect
279    pub fn get_rect(&self) -> SpriteRect {
280        SpriteRect {
281            x: self.rect_x,
282            y: self.rect_y,
283            width: self.rect_width,
284            height: self.rect_height,
285        }
286    }
287
288    /// Get sprite offset as SpriteOffset
289    pub fn get_offset(&self) -> SpriteOffset {
290        SpriteOffset {
291            x: self.offset_x,
292            y: self.offset_y,
293        }
294    }
295
296    /// Get sprite pivot as SpritePivot
297    pub fn get_pivot(&self) -> SpritePivot {
298        SpritePivot {
299            x: self.pivot_x,
300            y: self.pivot_y,
301        }
302    }
303
304    /// Get sprite border as SpriteBorder
305    pub fn get_border(&self) -> SpriteBorder {
306        SpriteBorder {
307            left: self.border_x,
308            bottom: self.border_y,
309            right: self.border_z,
310            top: self.border_w,
311        }
312    }
313
314    /// Check if sprite has border (is 9-slice)
315    pub fn has_border(&self) -> bool {
316        self.border_x > 0.0 || self.border_y > 0.0 || self.border_z > 0.0 || self.border_w > 0.0
317    }
318
319    /// Check if sprite is from an atlas
320    pub fn is_atlas_sprite(&self) -> bool {
321        self.sprite_atlas_path_id.is_some()
322    }
323
324    /// Get sprite area in pixels
325    pub fn get_area(&self) -> f32 {
326        self.rect_width * self.rect_height
327    }
328
329    /// Get sprite aspect ratio
330    pub fn get_aspect_ratio(&self) -> f32 {
331        if self.rect_height > 0.0 {
332            self.rect_width / self.rect_height
333        } else {
334            1.0
335        }
336    }
337}
338
339impl SpriteRect {
340    /// Check if rectangle contains a point
341    pub fn contains(&self, x: f32, y: f32) -> bool {
342        x >= self.x && x <= self.x + self.width && y >= self.y && y <= self.y + self.height
343    }
344
345    /// Get rectangle area
346    pub fn area(&self) -> f32 {
347        self.width * self.height
348    }
349
350    /// Get rectangle center point
351    pub fn center(&self) -> (f32, f32) {
352        (self.x + self.width / 2.0, self.y + self.height / 2.0)
353    }
354}