mindustry logic execution, map- and schematic- parsing and rendering
make blend() faster
| -rw-r--r-- | mindus/Cargo.toml | 1 | ||||
| -rw-r--r-- | mindus/src/data/dynamic.rs | 7 | ||||
| -rw-r--r-- | mindus/src/data/schematic.rs | 3 | ||||
| -rw-r--r-- | mindus/src/utils/image/holder.rs | 2 | ||||
| -rw-r--r-- | mindus/src/utils/image/mod.rs | 47 |
5 files changed, 34 insertions, 26 deletions
diff --git a/mindus/Cargo.toml b/mindus/Cargo.toml index b10ae99..9c77e79 100644 --- a/mindus/Cargo.toml +++ b/mindus/Cargo.toml @@ -26,6 +26,7 @@ blurslice = { version = "0.1" } enum_dispatch = "0.3" phf = { version = "0.11", features = ["macros"] } fimg = { version = "0.4.15", default-features = false } +umath = "0.0.1" [features] bin = ["fimg/save"] diff --git a/mindus/src/data/dynamic.rs b/mindus/src/data/dynamic.rs index b328f8a..05652ba 100644 --- a/mindus/src/data/dynamic.rs +++ b/mindus/src/data/dynamic.rs @@ -141,10 +141,9 @@ impl Serializable for DynData { let Ok(len) = usize::try_from(len) else { return Err(ReadError::BoolArrayLen(len)); }; - let mut result = vec![]; - result.reserve(len); - for _ in 0..len { - result.push(buff.read_bool()?); + let mut result = vec![false; len]; + for item in result.iter_mut() { + *item = buff.read_bool()?; } Ok(DynData::from(result)) } diff --git a/mindus/src/data/schematic.rs b/mindus/src/data/schematic.rs index 48e388f..78da2bb 100644 --- a/mindus/src/data/schematic.rs +++ b/mindus/src/data/schematic.rs @@ -496,8 +496,7 @@ impl Serializable for Schematic { if num_table < 0 { return Err(ReadError::TableSize(num_table)); } - let mut block_table = Vec::new(); - block_table.reserve(num_table as usize); + let mut block_table = Vec::with_capacity(num_table as usize); for _ in 0..num_table { let name = buff.read_utf()?; match BLOCK_REGISTRY.get(name) { diff --git a/mindus/src/utils/image/holder.rs b/mindus/src/utils/image/holder.rs index 2a8d03b..2e18724 100644 --- a/mindus/src/utils/image/holder.rs +++ b/mindus/src/utils/image/holder.rs @@ -21,7 +21,7 @@ impl<const CHANNELS: usize> ImageHolder<CHANNELS> { pub fn borrow(&self) -> Image<&[u8], CHANNELS> { match self { Self::Own(x) => x.as_ref(), - Self::Borrow(x) => x.clone(), + Self::Borrow(x) => *x, } } diff --git a/mindus/src/utils/image/mod.rs b/mindus/src/utils/image/mod.rs index a9aa76e..f82c2b1 100644 --- a/mindus/src/utils/image/mod.rs +++ b/mindus/src/utils/image/mod.rs @@ -62,7 +62,7 @@ impl ImageUtils for Image<&mut [u8], 4> { self } } - +use umath::FFloat; pub fn blend(bg: &mut [u8; 4], fg: [u8; 4]) { if fg[3] == 0 { return; @@ -71,22 +71,31 @@ pub fn blend(bg: &mut [u8; 4], fg: [u8; 4]) { *bg = fg; return; } - let bg_a = bg[3] as f32 / 255.0; - let fg_a = fg[3] as f32 / 255.0; - let a = bg_a + fg_a - bg_a * fg_a; - if a == 0.0 { - return; - }; - *bg = [ - (255.0 - * ((((fg[0] as f32 / 255.0) * fg_a) + ((bg[0] as f32 / 255.0) * bg_a) * (1.0 - fg_a)) - / a)) as u8, - (255.0 - * ((((fg[1] as f32 / 255.0) * fg_a) + ((bg[1] as f32 / 255.0) * bg_a) * (1.0 - fg_a)) - / a)) as u8, - (255.0 - * ((((fg[2] as f32 / 255.0) * fg_a) + ((bg[2] as f32 / 255.0) * bg_a) * (1.0 - fg_a)) - / a)) as u8, - (255.0 * a) as u8, - ] + #[allow(clippy::multiple_unsafe_ops_per_block)] + // SAFETY: no u8 can possibly become INF / NAN + unsafe { + let max = FFloat::new(255.0); + let bg_a = FFloat::new(bg[3] as f32) / max; + let fg_a = FFloat::new(fg[3] as f32) / max; + let a = bg_a + fg_a - bg_a * fg_a; + if a == 0.0 { + return; + }; + // could turn it into array::map + *bg = [ + *(max + * ((((FFloat::new(fg[0] as f32) / max) * fg_a) + + ((FFloat::new(bg[0] as f32) / max) * bg_a) * (FFloat::new(1.0) - fg_a)) + / a)) as u8, + *(max + * ((((FFloat::new(fg[1] as f32) / max) * fg_a) + + ((FFloat::new(bg[1] as f32) / max) * bg_a) * (FFloat::new(1.0) - fg_a)) + / a)) as u8, + *(max + * ((((FFloat::new(fg[2] as f32) / max) * fg_a) + + ((FFloat::new(bg[2] as f32) / max) * bg_a) * (FFloat::new(1.0) - fg_a)) + / a)) as u8, + *(max * a) as u8, + ] + } } |