bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
35.2k stars 3.47k forks source link

Collecting into a vec leads to better performance for `iter_combinations_mut` #14699

Open alice-i-cecile opened 1 month ago

alice-i-cecile commented 1 month ago

Yes this is definitely faster, especially as the immediate performance boost was apparent even without a release build which was required before!

The updated collision check system is: -

fn handle_verlet_collisions(
    mut query: Query<(&mut Transform, &VerletProperties)>,
) {
    let mut entities = query.iter_mut().collect::<Vec<(Mut<Transform>, &VerletProperties)>>();
    for i in 1..entities.len() {
        let (a, b) = entities.split_at_mut(i);
        let (ref mut tr1, pr1) = a.last_mut().unwrap();
        for (ref mut tr2, pr2) in b.iter_mut() {
            let mut norm = tr2.translation - tr1.translation;
            let dist = norm.length();
            if dist < pr1.radius + pr2.radius {
                let overlap = (pr1.radius + pr2.radius) - dist;
                norm = norm.normalize();
                if !pr1.pinned {
                    tr1.translation.x -= norm.x * overlap * 0.5f32;
                    tr1.translation.y -= norm.y * overlap * 0.5f32;
                }
                if !pr2.pinned {
                    tr2.translation.x += norm.x * overlap * 0.5f32;
                    tr2.translation.y += norm.y * overlap * 0.5f32;
                }
            }
        }
    }
}

I wonder if something similar could be done to iter_combinations_mut in cases where K == 2?

Originally posted by @polaris64 in https://github.com/bevyengine/bevy/discussions/14685#discussioncomment-10296740

alice-i-cecile commented 1 month ago

FYI @re0312