diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2022-10-02 12:29:47 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-02 12:29:47 -0500 |
| commit | c9b4dccd7eaeed68ce96cf5167916417d0baa6a7 (patch) | |
| tree | 0b381ee72a1486ccb22fe22158b5d7d3edaf3f99 /azalea-physics/src/collision/mergers.rs | |
| parent | aa78491ee09ec0c6879e6edde349ca67cf809daf (diff) | |
| download | azalea-drasl-c9b4dccd7eaeed68ce96cf5167916417d0baa6a7.tar.xz | |
All block shapes & collisions (#22)
* start adding shapes
* add more collision stuff
* DiscreteCubeMerger
* more mergers
* start adding BitSetDiscreteVoxelShape::join
* i love rust :smiley: :smiley: :smiley:
* r
* IT COMPILES????
* fix warning
* fix error
* fix more clippy issues
* add box_shape
* more shape stuff
* make DiscreteVoxelShape an enum
* Update shape.rs
* also make VoxelShape an enum
* implement BitSet::clear
* add more missing things
* it compiles
W
* start block shape codegen
* optimize shape codegen
* make az-block/blocks.rs look better (broken)
* almost new block macro
* make the codegen not generate 'type'
* try to fix
* work more on the blocks macro
* wait it compiles
* fix clippy issues
* shapes codegen works
* well it's almost working
* simplify some shape codegen
* enum type names are correct
* W it compiles
* cargo check no longer warns
* fix some clippy issues
* start making it so the shape impl is on BlockStates
* insane code
* new impl compiles
* fix wrong find_bits + TESTS PASS!
* add a test for slab collision
* fix clippy issues
* ok rust
* fix error that happens when on stairs
* add test for top slabs
* start adding join_is_not_empty
* add more to join_is_not_empty
* top slabs still don't work!!
* x..=0 doesn't work in rust :smiley: :smiley: :smiley: :smiley: :smiley: :smiley: :smiley: :smiley: :smiley: :smiley: :smiley: :smiley: :smiley: :smiley:
* remove comment since i added more useful names
* remove some printlns
* fix walls in some configurations erroring
* fix some warnings
* change comment to \`\`\`ignore instead of \`\`\`no_run
* players are .6 wide not .8
* fix clippy's complaints
* i missed one clippy warning
Diffstat (limited to 'azalea-physics/src/collision/mergers.rs')
| -rw-r--r-- | azalea-physics/src/collision/mergers.rs | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/azalea-physics/src/collision/mergers.rs b/azalea-physics/src/collision/mergers.rs new file mode 100644 index 00000000..483cb55f --- /dev/null +++ b/azalea-physics/src/collision/mergers.rs @@ -0,0 +1,239 @@ +use std::{cmp::Ordering, convert::TryInto}; + +use super::CubePointRange; +use azalea_core::{gcd, lcm, EPSILON}; + +#[derive(Debug)] +pub enum IndexMerger { + Identical { + coords: Vec<f64>, + }, + DiscreteCube { + result: CubePointRange, + first_div: u32, + second_div: u32, + }, + NonOverlapping { + lower: Vec<f64>, + upper: Vec<f64>, + swap: bool, + }, + Indirect { + result: Vec<f64>, + first_indices: Vec<isize>, + second_indices: Vec<isize>, + result_length: usize, + }, +} + +impl IndexMerger { + pub fn get_list(&self) -> Vec<f64> { + match self { + IndexMerger::Identical { coords } => coords.clone(), + IndexMerger::DiscreteCube { result, .. } => result.iter(), + IndexMerger::NonOverlapping { lower, upper, .. } => (0..self.size()) + .map(|i| { + if i < lower.len() { + lower[i] + } else { + upper[i - lower.len()] + } + }) + .collect(), + IndexMerger::Indirect { + result, + result_length, + .. + } => { + if *result_length <= 1 { + vec![] + } else { + result[..*result_length].to_vec() + } + } + } + } + pub fn for_merged_indexes(&self, mut consumer: impl IndexConsumer) -> bool { + match self { + IndexMerger::Identical { coords } => { + for coord in 0..(coords.len() - 1) { + if !consumer(coord as i32, coord as i32, coord as i32) { + return false; + } + } + true + } + IndexMerger::DiscreteCube { + result, + first_div, + second_div, + } => { + for var3 in 0..(result.size() - 1) { + if !consumer( + (var3 / second_div).try_into().unwrap(), + (var3 / first_div).try_into().unwrap(), + var3.try_into().unwrap(), + ) { + return false; + } + } + true + } + IndexMerger::NonOverlapping { lower, upper, swap } => { + if *swap { + for_non_swapped_indexes(lower, upper, move |var1x, var2, var3| { + consumer(var2, var1x, var3) + }) + } else { + for_non_swapped_indexes(lower, upper, consumer) + } + } + IndexMerger::Indirect { + first_indices, + second_indices, + result_length, + .. + } => { + let var2 = result_length - 1; + + for var3 in 0..var2 { + if !consumer( + first_indices[var3].try_into().unwrap(), + second_indices[var3].try_into().unwrap(), + var3.try_into().unwrap(), + ) { + return false; + } + } + + true + } + } + } + pub fn size(&self) -> usize { + match self { + IndexMerger::Identical { coords } => coords.len(), + IndexMerger::DiscreteCube { result, .. } => result.size().try_into().unwrap(), + IndexMerger::NonOverlapping { lower, upper, .. } => lower.len() + upper.len(), + IndexMerger::Indirect { result_length, .. } => *result_length, + } + } + + pub fn new_discrete_cube(a: u32, b: u32) -> Self { + let result = CubePointRange { + parts: (u32::try_from(lcm(a, b)).expect("lcm should be able to fit in a u32")) + .try_into() + .expect("lcm should not be 0"), + }; + let gcd = gcd(a, b); + let first_div = a / gcd; + let second_div = b / gcd; + Self::DiscreteCube { + result, + first_div, + second_div, + } + } + + pub fn new_indirect(var1: &Vec<f64>, var2: &Vec<f64>, var3: bool, var4: bool) -> Self { + let mut var5 = f64::NAN; + let var7 = var1.len(); + let var8 = var2.len(); + let var9 = var7 + var8; + let mut result = vec![0.0; var9]; + let mut first_indices: Vec<isize> = vec![0; var9]; + let mut second_indices: Vec<isize> = vec![0; var9]; + let var10 = !var3; + let var11 = !var4; + let mut var12 = 0; + let mut var13 = 0; + let mut var14 = 0; + + loop { + let mut var17: bool; + loop { + let var15 = var13 >= var7; + let var16 = var14 >= var8; + if var15 && var16 { + let result_length = std::cmp::max(1, var12); + return Self::Indirect { + result, + first_indices, + second_indices, + result_length, + }; + } + + var17 = !var15 && (var16 || var1[var13] < var2[var14] + EPSILON); + if var17 { + var13 += 1; + if !var10 || var14 != 0 && !var16 { + break; + } + } else { + var14 += 1; + if !var11 || var13 != 0 && !var15 { + break; + } + } + } + + let var18: isize = (var13 as isize) - 1; + let var19: isize = (var14 as isize) - 1; + let var20 = if var17 { + var1[TryInto::<usize>::try_into(var18).unwrap()] + } else { + var2[TryInto::<usize>::try_into(var19).unwrap()] + }; + match var5.partial_cmp(&(var20 - EPSILON)) { + None | Some(Ordering::Less) => { + result[var12] = var20; + first_indices[var12] = var18; + second_indices[var12] = var19; + var12 += 1; + var5 = var20; + } + _ => { + first_indices[var12 - 1] = var18; + second_indices[var12 - 1] = var19; + } + } + } + } +} + +pub trait IndexConsumer = FnMut(i32, i32, i32) -> bool; + +fn for_non_swapped_indexes( + lower: &Vec<f64>, + upper: &Vec<f64>, + mut consumer: impl IndexConsumer, +) -> bool { + let var2 = lower.len(); + for var3 in 0..var2 { + if !consumer(var3.try_into().unwrap(), -1, var3.try_into().unwrap()) { + return false; + } + } + let var3 = upper.len() - 1; + for var4 in 0..var3 { + if !consumer( + (var2 - 1).try_into().unwrap(), + var4.try_into().unwrap(), + (var2 + var4).try_into().unwrap(), + ) { + return false; + } + } + true +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_indirect_index_merger() { + IndexMerger::new_indirect(&vec![0.0, 1.0], &vec![0.0, 0.5, 1.0], true, true); + } +} |
