From aa340d580659f6ce8b702706490a0c7fac33a892 Mon Sep 17 00:00:00 2001 From: Evan Pratten Date: Mon, 21 Mar 2022 09:10:02 -0400 Subject: [PATCH] auto-gen spritesheets --- Cargo.toml | 1 + automation/anim_stitcher/Cargo.toml | 17 +++++ automation/anim_stitcher/src/generator.rs | 66 ++++++++++++++++++ automation/anim_stitcher/src/lib.rs | 3 + game/auto_stitch/README.md | 9 +++ .../auto_stitch/chr_testFox}/preview-01.jpg | Bin .../auto_stitch/chr_testFox}/preview-02.jpg | Bin .../auto_stitch/chr_testFox}/preview-03.jpg | Bin .../auto_stitch/chr_testFox}/preview-04.jpg | Bin .../auto_stitch/chr_testFox}/preview-05.jpg | Bin .../auto_stitch/chr_testFox}/preview-06.jpg | Bin .../auto_stitch/chr_testFox}/preview-07.jpg | Bin .../auto_stitch/chr_testFox}/preview-08.jpg | Bin .../auto_stitch/chr_testFox}/preview-09.jpg | Bin .../auto_stitch/chr_testFox}/preview-10.jpg | Bin .../auto_stitch/chr_testFox}/preview-11.jpg | Bin .../auto_stitch/chr_testFox}/preview-12.jpg | Bin .../auto_stitch/chr_testFox}/preview-13.jpg | Bin .../auto_stitch/chr_testFox}/preview-14.jpg | Bin .../auto_stitch/chr_testFox}/preview-15.jpg | Bin .../auto_stitch/chr_testFox}/preview-16.jpg | Bin .../auto_stitch/chr_testFox}/preview-17.jpg | Bin .../auto_stitch/chr_testFox}/preview-18.jpg | Bin game/dist/.gitignore | 1 + game/game_logic/Cargo.toml | 12 +++- game/game_logic/build.rs | 26 +++++++ 26 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 automation/anim_stitcher/Cargo.toml create mode 100644 automation/anim_stitcher/src/generator.rs create mode 100644 automation/anim_stitcher/src/lib.rs create mode 100644 game/auto_stitch/README.md rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-01.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-02.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-03.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-04.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-05.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-06.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-07.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-08.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-09.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-10.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-11.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-12.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-13.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-14.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-15.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-16.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-17.jpg (100%) rename {assets/demilurii/test => game/auto_stitch/chr_testFox}/preview-18.jpg (100%) create mode 100644 game/dist/.gitignore create mode 100644 game/game_logic/build.rs diff --git a/Cargo.toml b/Cargo.toml index bf862527..7b5fdf22 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ members = ["./game/game_logic", "./game/desktop_wrapper"] exclude = [ "./third_party/raylib-rs/raylib", "./third_party/raylib-rs/raylib-sys", + "./automation/anim_stitcher" ] [profile.release] diff --git a/automation/anim_stitcher/Cargo.toml b/automation/anim_stitcher/Cargo.toml new file mode 100644 index 00000000..4dfb9c31 --- /dev/null +++ b/automation/anim_stitcher/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "anim_stitcher" +publish = false +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[dependencies] +serde = { version = "1.0.126", features = ["derive"] } +serde_json = "1.0.64" +build-helper = { version = "0.1.1", optional = true } +image = { version = "0.24.1", optional = true } +regex = { version = "1.5.5", optional = true } + +[features] +default = [] +generator = ["build-helper", "image", "regex"] diff --git a/automation/anim_stitcher/src/generator.rs b/automation/anim_stitcher/src/generator.rs new file mode 100644 index 00000000..d0352931 --- /dev/null +++ b/automation/anim_stitcher/src/generator.rs @@ -0,0 +1,66 @@ +use std::path::{Path, PathBuf}; + +use image::{GenericImage, ImageResult}; +use regex::Regex; + +const SPRITE_TYPE_RE: &str = r"^([a-z]+)_"; + +fn sprite_name_to_output_dir(sprite_name: &str) -> PathBuf { + // Determine the sprite type + let sprite_type: String = Regex::new(SPRITE_TYPE_RE) + .unwrap() + .captures(sprite_name) + .unwrap() + .get(1) + .unwrap() + .as_str() + .to_string() + .into(); + + // Build the output directory + Path::new("../dist/gen/anm/") + .join(sprite_type) + .join(sprite_name) +} + +pub fn stitch_sprites(sprite_name: &str, ordered_image_files: Vec) -> ImageResult<()> { + build_helper::warning!( + "Generating sprite `{}` from {} images", + sprite_name, + ordered_image_files.len() + ); + + // Collect all images into a vec of actual image data + let mut images = Vec::new(); + for image_file in ordered_image_files { + let image_data = image::open(image_file.as_path()).unwrap(); + images.push(image_data); + } + + // Calculate the final width and height of the sprite + let img_width_out: u32 = images.iter().map(|im| im.width()).sum(); + let img_height_out: u32 = images.iter().map(|im| im.height()).max().unwrap_or(0); + + // Initialize an image buffer with the appropriate size. + let mut imgbuf = image::ImageBuffer::new(img_width_out, img_height_out); + let mut accumulated_width = 0; + + // Copy each input image at the correct location in the output image. + for img in images { + imgbuf.copy_from(&img, accumulated_width, 0).unwrap(); + accumulated_width += img.width(); + } + + // Get the output directory + let output_dir = sprite_name_to_output_dir(sprite_name); + + // Create the output directory if it doesn't exist + if !output_dir.exists() { + std::fs::create_dir_all(output_dir.as_path()).unwrap(); + } + + // Write the output image to disk. + imgbuf.save(output_dir.join(format!("{}.png", sprite_name)))?; + + Ok(()) +} diff --git a/automation/anim_stitcher/src/lib.rs b/automation/anim_stitcher/src/lib.rs new file mode 100644 index 00000000..b852cb30 --- /dev/null +++ b/automation/anim_stitcher/src/lib.rs @@ -0,0 +1,3 @@ + +#[cfg(feature = "generator")] +pub mod generator; \ No newline at end of file diff --git a/game/auto_stitch/README.md b/game/auto_stitch/README.md new file mode 100644 index 00000000..81903a25 --- /dev/null +++ b/game/auto_stitch/README.md @@ -0,0 +1,9 @@ +# The Auto-Stitch directory + +This is a bit of a *magic* directory. Anything put in here will automatically be turned into a spritesheet at compile time. + +## File organization + +In this directory, framesets are expected to be stored in subdirectories. The names of these are important as they will translate into the names of the spritesheets. + +For example, if you put a set of frames in `auto_stitch/chr_testFox`, you will get a spritesheet generated to `dist/gen/anm/chr/chr_testFox.png`. diff --git a/assets/demilurii/test/preview-01.jpg b/game/auto_stitch/chr_testFox/preview-01.jpg similarity index 100% rename from assets/demilurii/test/preview-01.jpg rename to game/auto_stitch/chr_testFox/preview-01.jpg diff --git a/assets/demilurii/test/preview-02.jpg b/game/auto_stitch/chr_testFox/preview-02.jpg similarity index 100% rename from assets/demilurii/test/preview-02.jpg rename to game/auto_stitch/chr_testFox/preview-02.jpg diff --git a/assets/demilurii/test/preview-03.jpg b/game/auto_stitch/chr_testFox/preview-03.jpg similarity index 100% rename from assets/demilurii/test/preview-03.jpg rename to game/auto_stitch/chr_testFox/preview-03.jpg diff --git a/assets/demilurii/test/preview-04.jpg b/game/auto_stitch/chr_testFox/preview-04.jpg similarity index 100% rename from assets/demilurii/test/preview-04.jpg rename to game/auto_stitch/chr_testFox/preview-04.jpg diff --git a/assets/demilurii/test/preview-05.jpg b/game/auto_stitch/chr_testFox/preview-05.jpg similarity index 100% rename from assets/demilurii/test/preview-05.jpg rename to game/auto_stitch/chr_testFox/preview-05.jpg diff --git a/assets/demilurii/test/preview-06.jpg b/game/auto_stitch/chr_testFox/preview-06.jpg similarity index 100% rename from assets/demilurii/test/preview-06.jpg rename to game/auto_stitch/chr_testFox/preview-06.jpg diff --git a/assets/demilurii/test/preview-07.jpg b/game/auto_stitch/chr_testFox/preview-07.jpg similarity index 100% rename from assets/demilurii/test/preview-07.jpg rename to game/auto_stitch/chr_testFox/preview-07.jpg diff --git a/assets/demilurii/test/preview-08.jpg b/game/auto_stitch/chr_testFox/preview-08.jpg similarity index 100% rename from assets/demilurii/test/preview-08.jpg rename to game/auto_stitch/chr_testFox/preview-08.jpg diff --git a/assets/demilurii/test/preview-09.jpg b/game/auto_stitch/chr_testFox/preview-09.jpg similarity index 100% rename from assets/demilurii/test/preview-09.jpg rename to game/auto_stitch/chr_testFox/preview-09.jpg diff --git a/assets/demilurii/test/preview-10.jpg b/game/auto_stitch/chr_testFox/preview-10.jpg similarity index 100% rename from assets/demilurii/test/preview-10.jpg rename to game/auto_stitch/chr_testFox/preview-10.jpg diff --git a/assets/demilurii/test/preview-11.jpg b/game/auto_stitch/chr_testFox/preview-11.jpg similarity index 100% rename from assets/demilurii/test/preview-11.jpg rename to game/auto_stitch/chr_testFox/preview-11.jpg diff --git a/assets/demilurii/test/preview-12.jpg b/game/auto_stitch/chr_testFox/preview-12.jpg similarity index 100% rename from assets/demilurii/test/preview-12.jpg rename to game/auto_stitch/chr_testFox/preview-12.jpg diff --git a/assets/demilurii/test/preview-13.jpg b/game/auto_stitch/chr_testFox/preview-13.jpg similarity index 100% rename from assets/demilurii/test/preview-13.jpg rename to game/auto_stitch/chr_testFox/preview-13.jpg diff --git a/assets/demilurii/test/preview-14.jpg b/game/auto_stitch/chr_testFox/preview-14.jpg similarity index 100% rename from assets/demilurii/test/preview-14.jpg rename to game/auto_stitch/chr_testFox/preview-14.jpg diff --git a/assets/demilurii/test/preview-15.jpg b/game/auto_stitch/chr_testFox/preview-15.jpg similarity index 100% rename from assets/demilurii/test/preview-15.jpg rename to game/auto_stitch/chr_testFox/preview-15.jpg diff --git a/assets/demilurii/test/preview-16.jpg b/game/auto_stitch/chr_testFox/preview-16.jpg similarity index 100% rename from assets/demilurii/test/preview-16.jpg rename to game/auto_stitch/chr_testFox/preview-16.jpg diff --git a/assets/demilurii/test/preview-17.jpg b/game/auto_stitch/chr_testFox/preview-17.jpg similarity index 100% rename from assets/demilurii/test/preview-17.jpg rename to game/auto_stitch/chr_testFox/preview-17.jpg diff --git a/assets/demilurii/test/preview-18.jpg b/game/auto_stitch/chr_testFox/preview-18.jpg similarity index 100% rename from assets/demilurii/test/preview-18.jpg rename to game/auto_stitch/chr_testFox/preview-18.jpg diff --git a/game/dist/.gitignore b/game/dist/.gitignore new file mode 100644 index 00000000..549fe731 --- /dev/null +++ b/game/dist/.gitignore @@ -0,0 +1 @@ +/gen/* \ No newline at end of file diff --git a/game/game_logic/Cargo.toml b/game/game_logic/Cargo.toml index 491b31c5..2a432b32 100644 --- a/game/game_logic/Cargo.toml +++ b/game/game_logic/Cargo.toml @@ -3,20 +3,26 @@ name = "game_logic" publish = false version = "0.1.0" edition = "2021" +build = "build.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] raylib = { version = "3.7", path = "../../third_party/raylib-rs/raylib" } sad_machine = { version = "1.0", path = "../../third_party/sm" } -tokio = { version = "1.17.0", featurs = ["fs"] } +tokio = { version = "1.17.0", features = ["fs"] } log = "0.4.14" profiling = "1.0.5" serde = { version = "1.0.136", features = ["derive"] } serde_json = "1.0.79" directories = "4.0.1" -chrono = { verison = "0.4.19", features = ["serde"] } +chrono = { version = "0.4.19", features = ["serde"] } discord-sdk = "0.3.0" rust-embed = { version = "6.2.0", features = ["compression"] } thiserror = "1.0.30" # nalgebra = { version = "0.30.1", features = ["serde"] } -approx = "0.5.1" \ No newline at end of file +approx = "0.5.1" + +[build-dependencies.anim_stitcher] +version = "*" +features = ["generator"] +path = "../../automation/anim_stitcher" diff --git a/game/game_logic/build.rs b/game/game_logic/build.rs new file mode 100644 index 00000000..67d595c9 --- /dev/null +++ b/game/game_logic/build.rs @@ -0,0 +1,26 @@ +//! This script contains code that generates more code. +//! +//! The idea being that we can have assets auto-pack and optimize themselves at build time. + +fn main() { + // We want to re-build if the assets change + println!("cargo:rerun-if-changed=../auto_stitch"); + + // Search for all direct children of the auto_stitch directory + for entry in std::fs::read_dir("../auto_stitch").unwrap() { + let entry = entry.unwrap(); + let path = entry.path(); + + // Get all children of the current entry + if let Ok(children) = std::fs::read_dir(&path) { + let children_paths = children.map(|e| e.unwrap().path()).collect::>(); + + // Process into a sprite + anim_stitcher::generator::stitch_sprites( + path.file_name().unwrap().to_str().unwrap(), + children_paths, + ) + .unwrap(); + } + } +}