I’m working on a simple particle physics engine using QuadTree’s.
The QuadTree stores the position of the particle and the entity. The engine has a collide
function with the signature:
pub fn collide(a: &mut Mut<Particle>, b: &mut Mut<Particle>)
where a
and b
are expected to be different particles.
I have the QuadTree created and I can query it with a bounding area but once I have all the queried, (Vec2, Entity)
pairs, I can’t access the other particle due to not being able to borrow mutable values more than once.
Minimal example:
fn update_physics(
engines: Query<&Engine>,
windows: Query<&Window, With<PrimaryWindow>>
mut particles: Query<(&mut Particle, Entity)>
) {
let engine = engines.single();
let window = windows.single();
let extents = window_extents(window); // custom function to get half widths of window
// bounding box for quadtree
let mut bb = AABB::new(Vec2::ZERO, extents);
// quadtree with max capacity of 1
let qt = QuadTree::new(bb, 1);
// Create quadtree
for (particle, entity) in particles.iter() {
qt.insert(particle.pos, entity);
}
// Collision handling
for (mut particle, entity) in particles.iter_mut() {
let query_range = BoundingCircle::new(particle.pos, particle.rad * 2.0);
let mut others: Vec<(Vec2, Entity)> = Vec::new();
qt.query_circle(&query_range, &mut others);
for (_, other_entity) in others.iter() {
if entity.index() != other_entity.index() {
// I CAN'T DO THIS!! nested query of particles
if let Ok((other_particle, _)) = particles.get_mut(other_entity.clone()) {
engine.collide(&mut particle, &mut other_particle);
}
}
}
}
}
I don’t want to use iter_combinations_mut
for the precise reason that it will force me to do an O(n^2) operation.
I understand my QuadTree is probably very inefficient, etc. I’d appreciate if you don’t get too focused on the optimizations, I’m trying to learn how these things work on my own. Optimizations related to this issue will be appreciated, maybe storing the entity is not the right way to do it, as you can probably deduce, I’m very new to Bevy and Rust in general.