i think 2.0 icons are kinda working
This commit is contained in:
parent
0f7ecba1ab
commit
4657c177b0
7 changed files with 522 additions and 34 deletions
331
Cargo.lock
generated
331
Cargo.lock
generated
|
@ -2,12 +2,27 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ab_glyph_rasterizer"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046"
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
|
@ -56,6 +71,15 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "conv"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299"
|
||||
dependencies = [
|
||||
"custom_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
|
@ -104,6 +128,12 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "custom_derive"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9"
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.8"
|
||||
|
@ -165,8 +195,32 @@ name = "gd-icon-renderer"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"image",
|
||||
"imageproc",
|
||||
"maplit",
|
||||
"plist",
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -213,6 +267,24 @@ dependencies = [
|
|||
"tiff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "imageproc"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aee993351d466301a29655d628bfc6f5a35a0d062b6160ca0808f425805fd7"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"conv",
|
||||
"image",
|
||||
"itertools",
|
||||
"nalgebra",
|
||||
"num",
|
||||
"rand 0.7.3",
|
||||
"rand_distr",
|
||||
"rayon",
|
||||
"rusttype",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
|
@ -223,6 +295,15 @@ dependencies = [
|
|||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
|
@ -244,6 +325,12 @@ version = "0.5.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.148"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
|
||||
|
||||
[[package]]
|
||||
name = "line-wrap"
|
||||
version = "0.1.1"
|
||||
|
@ -269,6 +356,16 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
||||
|
||||
[[package]]
|
||||
name = "matrixmultiply"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"rawpointer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.3"
|
||||
|
@ -294,6 +391,55 @@ dependencies = [
|
|||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nalgebra"
|
||||
version = "0.30.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb2d0de08694bed883320212c18ee3008576bfe8c306f4c3c4a58b4876998be"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"matrixmultiply",
|
||||
"num-complex",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"simba",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
|
@ -304,6 +450,17 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.1"
|
||||
|
@ -311,6 +468,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
@ -324,6 +482,21 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "owned_ttf_parser"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05e6affeb1632d6ff6a23d2cd40ffed138e82f1532571a26f527c8a284bb2fbb"
|
||||
dependencies = [
|
||||
"ttf-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
||||
|
||||
[[package]]
|
||||
name = "plist"
|
||||
version = "1.5.0"
|
||||
|
@ -351,6 +524,12 @@ dependencies = [
|
|||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.67"
|
||||
|
@ -387,6 +566,92 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
"libc",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand_core 0.5.1",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom 0.2.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_distr"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
|
||||
dependencies = [
|
||||
"rand 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rawpointer"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.8.0"
|
||||
|
@ -407,6 +672,25 @@ dependencies = [
|
|||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rusttype"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ff8374aa04134254b7995b63ad3dc41c7f7236f69528b28553da7d72efaa967"
|
||||
dependencies = [
|
||||
"ab_glyph_rasterizer",
|
||||
"owned_ttf_parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "safe_arch"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "safemem"
|
||||
version = "0.3.3"
|
||||
|
@ -439,6 +723,19 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simba"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f3fd720c48c53cace224ae62bef1bbff363a70c68c4802a78b5cc6159618176"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"num-complex",
|
||||
"num-traits",
|
||||
"paste",
|
||||
"wide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.7"
|
||||
|
@ -510,18 +807,52 @@ dependencies = [
|
|||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
|
||||
|
||||
[[package]]
|
||||
name = "wide"
|
||||
version = "0.7.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa469ffa65ef7e0ba0f164183697b89b854253fd31aeb92358b7b6155177d62f"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"safe_arch",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zune-inflate"
|
||||
version = "0.2.54"
|
||||
|
|
|
@ -5,5 +5,7 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
image = "0.24.7"
|
||||
imageproc = "0.23.0"
|
||||
maplit = "1.0.2"
|
||||
plist = "1.5.0"
|
||||
rand = "0.8.5"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# gd-icon-renderer
|
||||
|
||||
rust geometryd ash icon redner!!
|
||||
rust geometryd ash icon redner!! shout out to [gd-icon-renderer](https://github.com/oatmealine/gd-icon-renderer) oat
|
||||
|
||||
## usage
|
||||
|
||||
|
@ -8,7 +8,7 @@ Provide your `GJ_GameSheet02-uhd`, `GJ_GameSheetGlow-uhd`, `Robot_AnimDesc2`, an
|
|||
|
||||
## todo
|
||||
|
||||
- maybe use custom plist parser
|
||||
- spider + robot support
|
||||
- make `get_sprite_from_loaded` and `get_sprite` merged into `get_sprite`. i think this needs traits or something
|
||||
- use custom plist parser. current one takes like 5 seconds to parse an animation file
|
||||
- change zany anim to argument
|
||||
- trim empty alpha space (robtop didnt make the bounds correctly :sob:)
|
||||
- i think theres some slight shifting in the transform to do with rotation. investigate plz. really big on spider 16 for some reason????
|
|
@ -128,6 +128,72 @@ pub fn load_spritesheet(path: &str) -> LoadedSpritesheet {
|
|||
}
|
||||
}
|
||||
|
||||
// Represents the metadata of an animation frame's sprite
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AnimationSprite {
|
||||
pub texture: String,
|
||||
pub position: (f32, f32),
|
||||
pub scale: (f32, f32),
|
||||
pub rotation: f64,
|
||||
pub flipped: (bool, bool),
|
||||
pub z: i32
|
||||
}
|
||||
|
||||
impl AnimationSprite {
|
||||
fn initialize(obj: plist::Value) -> AnimationSprite {
|
||||
let hash = obj.as_dictionary().expect("object must be a dict");
|
||||
|
||||
let hash_keys = vec!["texture", "position", "scale", "rotation", "flipped", "zValue"];
|
||||
|
||||
let isolated: Vec<(&&str, Option<&plist::Value>)> = hash_keys
|
||||
.iter()
|
||||
.map(|s| (s, hash.get(s)))
|
||||
.collect();
|
||||
|
||||
let missing: Vec<&(&&str, Option<&plist::Value>)> = isolated
|
||||
.iter()
|
||||
.filter(|&&(_, value)| value.is_none())
|
||||
.collect();
|
||||
|
||||
if !missing.is_empty() {
|
||||
let missing_entries: Vec<&str> = missing.iter().map(|(&key, _)| key).collect();
|
||||
panic!("missing entries: {:?}", missing_entries);
|
||||
}
|
||||
|
||||
let isolated_hash: HashMap<String, plist::Value> = isolated
|
||||
.iter()
|
||||
.map(|&(key, value)| (key.to_string(), value.expect("value is none after checking").clone()))
|
||||
.collect();
|
||||
|
||||
return AnimationSprite {
|
||||
texture: isolated_hash.get("texture").expect("missing texture").as_string().expect("texture is not a string").to_string(),
|
||||
position: parse_vec_f32(isolated_hash.get("position").expect("missing position").as_string().expect("position is not a string")),
|
||||
scale: parse_vec_f32(isolated_hash.get("scale").expect("missing scale").as_string().expect("scale is not a string")),
|
||||
rotation: isolated_hash.get("rotation").expect("missing rotation").as_string().expect("rotation is not a string").parse::<f64>().expect("couldnt parse rotation as f64"),
|
||||
flipped: {
|
||||
let flipped_numbers = parse_vec(isolated_hash.get("flipped").expect("missing flipped").as_string().expect("flipped is not a string"));
|
||||
(flipped_numbers.0 > 0, flipped_numbers.1 > 0)
|
||||
},
|
||||
z: isolated_hash.get("zValue").expect("missing zValue").as_string().expect("zValue is not a string").parse::<i32>().expect("couldnt parse zValue as i32")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type Animations = HashMap<String, Vec<AnimationSprite>>;
|
||||
|
||||
pub fn load_animations(path: &str) -> Animations {
|
||||
let loaded_plist: plist::Value = plist::from_file(path).expect("could not load plist");
|
||||
let animations = loaded_plist.as_dictionary().expect("object must be a dict").get("animationContainer").expect("key `animationContainer` doesnt exist").as_dictionary().expect("`animationContainer` must be a dict");
|
||||
let mut parsed_animations: Animations = HashMap::new();
|
||||
for (k, v) in animations.iter() {
|
||||
parsed_animations.insert(k.clone(), vec![] as Vec<AnimationSprite>);
|
||||
parsed_animations.get_mut(k.as_str()).expect("this should exist..")
|
||||
.extend(v.as_dictionary().expect("animation must be a dict")
|
||||
.iter().map(|(_, v)| AnimationSprite::initialize(v.clone())));
|
||||
}
|
||||
return parsed_animations;
|
||||
}
|
||||
|
||||
// Trims out a sprite from an image according to a .plist spritesheet.
|
||||
pub fn get_sprite(spritesheet: Spritesheet, img: DynamicImage, key: String) -> Option<(DynamicImage, Sprite)> {
|
||||
let sprite = spritesheet.sprites.get(&key);
|
||||
|
@ -155,7 +221,7 @@ pub fn get_sprite(spritesheet: Spritesheet, img: DynamicImage, key: String) -> O
|
|||
return Some((canvas, sprite.clone()));
|
||||
}
|
||||
|
||||
panic!("The sprite should have been found in the spritesheet or not found at all")
|
||||
unreachable!("The sprite should have been found in the spritesheet or not found at all")
|
||||
}
|
||||
|
||||
pub fn get_sprite_from_loaded(spritesheet: LoadedSpritesheet, key: String) -> Option<(DynamicImage, Sprite)> {
|
||||
|
|
|
@ -49,8 +49,8 @@ pub const COLORS: &'static [[f32; 3]] = &[
|
|||
|
||||
// `zany` = uses 2.0 gamemode render system w/ multiple moving parts
|
||||
pub struct Gamemode {
|
||||
prefix: String,
|
||||
zany: bool
|
||||
pub prefix: String,
|
||||
pub zany: bool
|
||||
}
|
||||
|
||||
pub static GAMEMODES: LazyLock<HashMap<&str, Gamemode>> = LazyLock::new(|| { hashmap! {
|
||||
|
@ -59,7 +59,6 @@ pub static GAMEMODES: LazyLock<HashMap<&str, Gamemode>> = LazyLock::new(|| { has
|
|||
"ball" => Gamemode { prefix: "player_ball_".to_string(), zany: false },
|
||||
"ufo" => Gamemode { prefix: "bird_".to_string(), zany: false },
|
||||
"wave" => Gamemode { prefix: "dart_".to_string(), zany: false },
|
||||
// unimplemented
|
||||
// "robot" => Gamemode { prefix: "robot_".to_string(), zany: true },
|
||||
// "spider" => Gamemode { prefix: "spider_".to_string(), zany: true },
|
||||
"robot" => Gamemode { prefix: "robot_".to_string(), zany: true },
|
||||
"spider" => Gamemode { prefix: "spider_".to_string(), zany: true }
|
||||
}});
|
||||
|
|
19
src/lib.rs
19
src/lib.rs
|
@ -11,26 +11,21 @@ mod tests {
|
|||
use renderer::*;
|
||||
use assets::*;
|
||||
|
||||
// not actually used, just for benchmarking
|
||||
use std::time::Instant;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let game_sheet_02 = load_spritesheet("assets/GJ_GameSheet02-uhd.plist");
|
||||
let game_sheet_glow = load_spritesheet("assets/GJ_GameSheetGlow-uhd.plist");
|
||||
let robot_sheet = load_animations("assets/Robot_AnimDesc2.plist");
|
||||
let spider_sheet = load_animations("assets/Spider_AnimDesc2.plist");
|
||||
|
||||
let start = Instant::now();
|
||||
let rendered_img = render_normal(
|
||||
"ship_18".to_string(),
|
||||
[0.0/255.0, 0.0/255.0, 0.0/255.0],
|
||||
[0.0/255.0, 0.0/255.0, 0.0/255.0],
|
||||
true,
|
||||
game_sheet_02,
|
||||
game_sheet_glow,
|
||||
);
|
||||
let rendered_icon = render_icon("ship", 44, [0.0, 0.0, 0.0], [255.0/255.0, 125.0/255.0, 125.0/255.0], true, game_sheet_02, game_sheet_glow, robot_sheet, spider_sheet);
|
||||
let end = start.elapsed();
|
||||
|
||||
rendered_img.save("rendered_icon.png").expect("saving image failed");
|
||||
let end = Instant::now();
|
||||
println!("Time elapsed: {:?}", end.duration_since(start));
|
||||
println!("time taken to render: {:?}", end);
|
||||
|
||||
rendered_icon.save("rendered_icon.png").expect("saving image failed");
|
||||
}
|
||||
}
|
||||
|
|
117
src/renderer.rs
117
src/renderer.rs
|
@ -1,13 +1,14 @@
|
|||
use image::*;
|
||||
use image::{DynamicImage, imageops};
|
||||
use imageproc::geometric_transformations::{rotate_about_center, Interpolation};
|
||||
|
||||
use std::cmp;
|
||||
|
||||
use crate::assets;
|
||||
use crate::assets::LoadedSpritesheet;
|
||||
use crate::assets::{LoadedSpritesheet, Animations, Sprite};
|
||||
|
||||
// Internal function to easily transform an image
|
||||
fn transform(image: &DynamicImage, color: Option<[f32; 3]>, scale: Option<(f32, f32)>, rotation: Option<i32>) -> DynamicImage {
|
||||
fn transform(image: &DynamicImage, color: Option<[f32; 3]>, scale: Option<(f32, f32)>, rotation: Option<f32>) -> DynamicImage {
|
||||
let mut transformed_image = image.clone();
|
||||
|
||||
if let Some(color) = color {
|
||||
|
@ -44,22 +45,39 @@ fn transform(image: &DynamicImage, color: Option<[f32; 3]>, scale: Option<(f32,
|
|||
}
|
||||
|
||||
if let Some(rotation) = rotation {
|
||||
match rotation {
|
||||
0 => (),
|
||||
90 => transformed_image = transformed_image.rotate90(),
|
||||
180 => transformed_image = transformed_image.rotate180(),
|
||||
270 => transformed_image = transformed_image.rotate270(),
|
||||
_ => panic!("rotation must be 0, 90, 180, or 270"),
|
||||
// lets not rotate if we dont need to
|
||||
if rotation == 0.0 {
|
||||
return transformed_image;
|
||||
}
|
||||
|
||||
let radians = rotation.to_radians();
|
||||
|
||||
let (width, height) = transformed_image.dimensions();
|
||||
|
||||
let trig_width = (width as f32 * radians.cos() + height as f32 * radians.sin())
|
||||
.abs()
|
||||
.ceil() as u32;
|
||||
let trig_height = (width as f32 * radians.sin() + height as f32 * radians.cos())
|
||||
.abs()
|
||||
.ceil() as u32;
|
||||
|
||||
let transform_x = ((trig_width as f32 / 2.0) - (width as f32 / 2.0)).ceil() as u32;
|
||||
let transform_y = ((trig_height as f32 / 2.0) - (height as f32 / 2.0)).ceil() as u32;
|
||||
|
||||
let mut canvas = ImageBuffer::new(cmp::max(trig_width, width), cmp::max(trig_height, height));
|
||||
canvas.copy_from(&transformed_image, transform_x, transform_y).expect("couldnt copy from img");
|
||||
canvas = rotate_about_center(&canvas, radians, Interpolation::Bilinear, Rgba([0, 0, 0, 0]));
|
||||
|
||||
transformed_image = DynamicImage::ImageRgba8(canvas);
|
||||
}
|
||||
|
||||
return transformed_image;
|
||||
}
|
||||
|
||||
// Mainly for internal use; given an array of images, their sizes and colors, tints and composits them into a single image
|
||||
pub fn render_layered(images: Vec<DynamicImage>, positions: Vec<Option<(f32, f32)>>, colors: Vec<[f32; 3]>, scales: Vec<Option<(f32, f32)>>, rotations: Vec<Option<i32>>) -> DynamicImage {
|
||||
pub fn render_layered(images: Vec<DynamicImage>, positions: Vec<Option<(f32, f32)>>, colors: Vec<Option<[f32; 3]>>, scales: Vec<Option<(f32, f32)>>, rotations: Vec<Option<f32>>) -> DynamicImage {
|
||||
let transformed: Vec<DynamicImage> = images.iter().enumerate().map(|(i, img)| {
|
||||
transform(img, Some(colors[i]), scales[i], rotations[i])
|
||||
transform(img, colors[i], scales[i], rotations[i])
|
||||
}).collect();
|
||||
let sizes: Vec<(i64, i64)> = transformed.iter().map(|img| {
|
||||
(img.width() as i64, img.height() as i64)
|
||||
|
@ -139,9 +157,86 @@ pub fn render_normal(basename: String, col1: [f32; 3], col2: [f32; 3], glow: boo
|
|||
.collect(),
|
||||
colors.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, color)| layers[i].clone().map(|_| color.unwrap()))
|
||||
.filter_map(|(i, color)| layers[i].clone().map(|_| color.to_owned()))
|
||||
.collect(),
|
||||
vec![None, None, None, None, None],
|
||||
vec![None, None, None, None, None]
|
||||
);
|
||||
}
|
||||
|
||||
fn flip(scale: (f32, f32), flipped: (bool, bool)) -> (f32, f32) {
|
||||
(scale.0 * (if flipped.0 { -1 } else { 1 }) as f32, scale.1 * (if flipped.1 { -1 } else { 1 }) as f32)
|
||||
}
|
||||
|
||||
// Renders out a robot/spider icon. You may be looking for `render_icon`.
|
||||
pub fn render_zany(basename: String, col1: [f32; 3], col2: [f32; 3], glow: bool, game_sheet_02: LoadedSpritesheet, _game_sheet_glow: LoadedSpritesheet, animations: Animations) -> DynamicImage {
|
||||
let glow_col = if is_black(col2) { if is_black(col1) { [1.0, 1.0, 1.0] } else { col1 } } else { col2 };
|
||||
let glow = glow || (is_black(col1) && is_black(col2));
|
||||
|
||||
let mut anim = animations.get("Robot_idle_001.png").unwrap_or_else(|| animations.get("Spider_idle_001.png").expect("no animations found")).clone();
|
||||
anim.sort_by_key(|spr| spr.z);
|
||||
|
||||
let mut layers = anim
|
||||
.iter()
|
||||
.map(|a| {
|
||||
let texture_name = a.texture.clone().replace("spider_01", &basename).replace("robot_01", &basename);
|
||||
let mut names = vec![
|
||||
texture_name.replace("_001.png", "_2_001.png"),
|
||||
texture_name.replace("_001.png", "_3_001.png"),
|
||||
texture_name.clone(),
|
||||
texture_name.replace("_001.png", "_extra_001.png")
|
||||
];
|
||||
let mut colors = vec![
|
||||
Some(col2),
|
||||
None,
|
||||
Some(col1),
|
||||
None
|
||||
];
|
||||
|
||||
if glow {
|
||||
names.push(texture_name.replace("_001.png", "_glow_001.png"));
|
||||
colors.push(Some(glow_col));
|
||||
}
|
||||
|
||||
names.iter().enumerate().map(|(i, v)|
|
||||
(
|
||||
assets::get_sprite_from_loaded(game_sheet_02.to_owned().clone(), v.clone()),
|
||||
a.position,
|
||||
flip(a.scale, a.flipped),
|
||||
a.rotation,
|
||||
glow && i == names.len() - 1,
|
||||
colors[i]
|
||||
)
|
||||
).collect::<Vec<(Option<(DynamicImage, Sprite)>, (f32, f32), (f32, f32), f64, bool, Option<[f32; 3]>)>>()
|
||||
})
|
||||
.flatten()
|
||||
.collect::<Vec<(Option<(DynamicImage, Sprite)>, (f32, f32), (f32, f32), f64, bool, Option<[f32; 3]>)>>();
|
||||
|
||||
// put glow b4 everything else
|
||||
layers.sort_by_key(|t| if t.4 { 0 } else { 1 });
|
||||
|
||||
let layers_r = layers.iter()
|
||||
.filter(|v| v.0.is_some())
|
||||
.filter_map(|(opt_sprite, pos, scale, rot, glow, color)| opt_sprite.clone().map(|sprite| ((sprite.0, sprite.1), *pos, *scale, *rot, *glow, *color)))
|
||||
.collect::<Vec<((DynamicImage, Sprite), (f32, f32), (f32, f32), f64, bool, Option<[f32; 3]>)>>();
|
||||
|
||||
return render_layered(
|
||||
layers_r.iter().map(|t| t.0.0.clone()).collect(),
|
||||
layers_r.iter().map(|t| Some((t.0.1.offset.0 + t.1.0 * 4.0, t.0.1.offset.1 * -1.0 + t.1.1 * -4.0))).collect(),
|
||||
layers_r.iter().map(|t| t.5).collect(),
|
||||
layers_r.iter().map(|t| Some(t.2)).collect(),
|
||||
layers_r.iter().map(|t| Some(t.3 as f32)).collect()
|
||||
)
|
||||
}
|
||||
|
||||
// The main entrypoint for icon rendering; this should be all you need to render out an icon.
|
||||
// `gamemode` must be one of `cube`, `ship`, `ball`, `ufo`, `wave`, `robot`, or `spider`
|
||||
pub fn render_icon(gamemode_str: &str, icon: i32, col1: [f32; 3], col2: [f32; 3], glow: bool, game_sheet_02: LoadedSpritesheet, game_sheet_glow: LoadedSpritesheet, robot_animations: Animations, spider_animations: Animations) -> DynamicImage {
|
||||
let gamemode = crate::constants::GAMEMODES.get(gamemode_str).expect("invalid gamemode");
|
||||
|
||||
if gamemode.zany {
|
||||
return render_zany(format!("{}{:02}", gamemode.prefix, icon), col1, col2, glow, game_sheet_02, game_sheet_glow, if gamemode_str == "robot" { robot_animations } else { spider_animations })
|
||||
} else {
|
||||
return render_normal(format!("{}{:02}", gamemode.prefix, icon), col1, col2, glow, game_sheet_02, game_sheet_glow)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue