unity_asset_binary/sprite/
mod.rs1pub mod parser;
37pub mod processor;
38pub mod types;
39
40pub use parser::SpriteParser;
42pub use processor::{SpriteProcessor, SpriteStats};
43pub use types::{
44 Sprite,
46 SpriteAtlas,
47 SpriteBorder,
48 SpriteConfig,
50 SpriteInfo,
51 SpriteOffset,
52 SpritePivot,
53 SpriteRect,
54 SpriteRenderData,
55 SpriteResult,
56 SpriteSettings,
57};
58
59pub struct SpriteManager {
64 processor: SpriteProcessor,
65}
66
67impl SpriteManager {
68 pub fn new(version: crate::unity_version::UnityVersion) -> Self {
70 Self {
71 processor: SpriteProcessor::new(version),
72 }
73 }
74
75 pub fn with_config(version: crate::unity_version::UnityVersion, config: SpriteConfig) -> Self {
77 Self {
78 processor: SpriteProcessor::with_config(version, config),
79 }
80 }
81
82 pub fn process_sprite(
84 &self,
85 object: &crate::object::UnityObject,
86 ) -> crate::error::Result<SpriteResult> {
87 self.processor.parse_sprite(object)
88 }
89
90 pub fn process_sprite_with_texture(
92 &self,
93 sprite_object: &crate::object::UnityObject,
94 texture: &crate::texture::Texture2D,
95 ) -> crate::error::Result<SpriteResult> {
96 self.processor
97 .process_sprite_with_texture(sprite_object, texture)
98 }
99
100 pub fn process_sprite_atlas(
102 &self,
103 sprites: &[&crate::object::UnityObject],
104 ) -> crate::error::Result<SpriteAtlas> {
105 self.processor.process_sprite_atlas(sprites)
106 }
107
108 pub fn get_statistics(&self, sprites: &[&Sprite]) -> SpriteStats {
110 self.processor.get_sprite_stats(sprites)
111 }
112
113 pub fn validate_sprite(&self, sprite: &Sprite) -> crate::error::Result<()> {
115 self.processor.validate_sprite(sprite)
116 }
117
118 pub fn get_supported_features(&self) -> Vec<&'static str> {
120 self.processor.get_supported_features()
121 }
122
123 pub fn is_feature_supported(&self, feature: &str) -> bool {
125 self.processor.is_feature_supported(feature)
126 }
127
128 pub fn config(&self) -> &SpriteConfig {
130 self.processor.config()
131 }
132
133 pub fn set_config(&mut self, config: SpriteConfig) {
135 self.processor.set_config(config);
136 }
137
138 pub fn version(&self) -> &crate::unity_version::UnityVersion {
140 self.processor.version()
141 }
142
143 pub fn set_version(&mut self, version: crate::unity_version::UnityVersion) {
145 self.processor.set_version(version);
146 }
147}
148
149impl Default for SpriteManager {
150 fn default() -> Self {
151 Self::new(crate::unity_version::UnityVersion::default())
152 }
153}
154
155pub fn create_manager(version: crate::unity_version::UnityVersion) -> SpriteManager {
158 SpriteManager::new(version)
159}
160
161pub fn create_performance_manager(version: crate::unity_version::UnityVersion) -> SpriteManager {
163 let config = SpriteConfig {
164 extract_images: false,
165 process_atlas: false,
166 max_sprite_size: Some((1024, 1024)),
167 apply_transformations: false,
168 };
169 SpriteManager::with_config(version, config)
170}
171
172pub fn create_full_manager(version: crate::unity_version::UnityVersion) -> SpriteManager {
174 let config = SpriteConfig {
175 extract_images: true,
176 process_atlas: true,
177 max_sprite_size: None,
178 apply_transformations: true,
179 };
180 SpriteManager::with_config(version, config)
181}
182
183pub fn parse_sprite(
185 object: &crate::object::UnityObject,
186 version: &crate::unity_version::UnityVersion,
187) -> crate::error::Result<Sprite> {
188 let parser = SpriteParser::new(version.clone());
189 let result = parser.parse_from_unity_object(object)?;
190 Ok(result.sprite)
191}
192
193pub fn extract_sprite_image(
195 sprite: &Sprite,
196 texture: &crate::texture::Texture2D,
197 version: &crate::unity_version::UnityVersion,
198) -> crate::error::Result<Vec<u8>> {
199 let processor = SpriteProcessor::new(version.clone());
200 processor.extract_sprite_image(sprite, texture)
201}
202
203pub fn validate_sprite(sprite: &Sprite) -> crate::error::Result<()> {
205 let processor = SpriteProcessor::default();
206 processor.validate_sprite(sprite)
207}
208
209pub fn get_sprite_area(sprite: &Sprite) -> f32 {
211 sprite.get_area()
212}
213
214pub fn is_nine_slice_sprite(sprite: &Sprite) -> bool {
216 sprite.has_border()
217}
218
219pub fn is_atlas_sprite(sprite: &Sprite) -> bool {
221 sprite.is_atlas_sprite()
222}
223
224pub fn get_sprite_aspect_ratio(sprite: &Sprite) -> f32 {
226 sprite.get_aspect_ratio()
227}
228
229pub fn is_sprite_feature_supported(
231 version: &crate::unity_version::UnityVersion,
232 feature: &str,
233) -> bool {
234 match feature {
235 "basic_sprite" | "rect" | "pivot" => true,
236 "border" | "pixels_to_units" => version.major >= 5,
237 "polygon_sprites" | "sprite_atlas" => version.major >= 2017,
238 "sprite_mesh" | "sprite_physics" => version.major >= 2018,
239 _ => false,
240 }
241}
242
243pub fn get_recommended_config(version: &crate::unity_version::UnityVersion) -> SpriteConfig {
245 if version.major >= 2018 {
246 SpriteConfig {
248 extract_images: true,
249 process_atlas: true,
250 max_sprite_size: None,
251 apply_transformations: true,
252 }
253 } else if version.major >= 2017 {
254 SpriteConfig {
256 extract_images: true,
257 process_atlas: true,
258 max_sprite_size: Some((2048, 2048)),
259 apply_transformations: true,
260 }
261 } else if version.major >= 5 {
262 SpriteConfig {
264 extract_images: true,
265 process_atlas: false,
266 max_sprite_size: Some((1024, 1024)),
267 apply_transformations: false,
268 }
269 } else {
270 SpriteConfig {
272 extract_images: false,
273 process_atlas: false,
274 max_sprite_size: Some((512, 512)),
275 apply_transformations: false,
276 }
277 }
278}
279
280#[derive(Debug, Clone)]
282pub struct ProcessingOptions {
283 pub parallel_processing: bool,
284 pub cache_results: bool,
285 pub validate_sprites: bool,
286 pub generate_thumbnails: bool,
287}
288
289impl Default for ProcessingOptions {
290 fn default() -> Self {
291 Self {
292 parallel_processing: false,
293 cache_results: true,
294 validate_sprites: true,
295 generate_thumbnails: false,
296 }
297 }
298}
299
300#[cfg(test)]
301mod tests {
302 use super::*;
303
304 #[test]
305 fn test_manager_creation() {
306 let version = crate::unity_version::UnityVersion::default();
307 let manager = create_manager(version);
308 assert!(manager.get_supported_features().contains(&"basic_sprite"));
309 }
310
311 #[test]
312 fn test_performance_manager() {
313 let version = crate::unity_version::UnityVersion::default();
314 let manager = create_performance_manager(version);
315 assert!(!manager.config().extract_images);
316 assert!(!manager.config().process_atlas);
317 }
318
319 #[test]
320 fn test_full_manager() {
321 let version = crate::unity_version::UnityVersion::default();
322 let manager = create_full_manager(version);
323 assert!(manager.config().extract_images);
324 assert!(manager.config().process_atlas);
325 }
326
327 #[test]
328 fn test_feature_support() {
329 let version_2020 =
330 crate::unity_version::UnityVersion::parse_version("2020.3.12f1").unwrap();
331 assert!(is_sprite_feature_supported(&version_2020, "basic_sprite"));
332 assert!(is_sprite_feature_supported(
333 &version_2020,
334 "polygon_sprites"
335 ));
336 assert!(is_sprite_feature_supported(&version_2020, "sprite_mesh"));
337
338 let version_2017 =
339 crate::unity_version::UnityVersion::parse_version("2017.4.40f1").unwrap();
340 assert!(is_sprite_feature_supported(&version_2017, "sprite_atlas"));
341 assert!(!is_sprite_feature_supported(&version_2017, "sprite_mesh"));
342 }
343
344 #[test]
345 fn test_recommended_config() {
346 let version_2020 =
347 crate::unity_version::UnityVersion::parse_version("2020.3.12f1").unwrap();
348 let config = get_recommended_config(&version_2020);
349 assert!(config.extract_images);
350 assert!(config.process_atlas);
351 assert!(config.apply_transformations);
352
353 let version_5 = crate::unity_version::UnityVersion::parse_version("5.6.7f1").unwrap();
354 let config = get_recommended_config(&version_5);
355 assert!(config.extract_images);
356 assert!(!config.process_atlas);
357 }
358}