Skip to content

Commit

Permalink
Make it possible to update colliders
Browse files Browse the repository at this point in the history
  • Loading branch information
alec-deason committed Mar 19, 2021
1 parent 999c81d commit ce1c3eb
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 2 deletions.
27 changes: 26 additions & 1 deletion bevy_rapier2d/examples/despawn2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ pub struct DespawnResource {
pub entities: Vec<Entity>,
}

#[derive(Default)]
pub struct ResizeResource {
pub entities: Vec<Entity>,
}

fn main() {
App::build()
.add_resource(ClearColor(Color::rgb(
Expand All @@ -26,6 +31,7 @@ fn main() {
)))
.add_resource(Msaa::default())
.add_resource(DespawnResource::default())
.add_resource(ResizeResource::default())
.add_plugins(DefaultPlugins)
.add_plugin(bevy_winit::WinitPlugin::default())
.add_plugin(bevy_wgpu::WgpuPlugin::default())
Expand All @@ -36,6 +42,7 @@ fn main() {
.add_startup_system(setup_physics.system())
.add_startup_system(enable_physics_profiling.system())
.add_system(despawn.system())
.add_system(resize.system())
.run();
}

Expand All @@ -57,7 +64,11 @@ fn setup_graphics(commands: &mut Commands, mut configuration: ResMut<RapierConfi
});
}

pub fn setup_physics(commands: &mut Commands, mut despawn: ResMut<DespawnResource>) {
pub fn setup_physics(
commands: &mut Commands,
mut despawn: ResMut<DespawnResource>,
mut resize: ResMut<ResizeResource>,
) {
/*
* Ground
*/
Expand Down Expand Up @@ -107,6 +118,9 @@ pub fn setup_physics(commands: &mut Commands, mut despawn: ResMut<DespawnResourc
let body = RigidBodyBuilder::new_dynamic().translation(x, y);
let collider = ColliderBuilder::cuboid(rad, rad).density(1.0);
commands.spawn((body, collider));
if (i + j * num) % 100 == 0 {
resize.entities.push(commands.current_entity().unwrap());
}
}
}
}
Expand All @@ -120,3 +134,14 @@ pub fn despawn(commands: &mut Commands, time: Res<Time>, mut despawn: ResMut<Des
despawn.entities.clear();
}
}

pub fn resize(commands: &mut Commands, time: Res<Time>, mut resize: ResMut<ResizeResource>) {
if time.seconds_since_startup() > 6.0 {
for entity in &resize.entities {
println!("Resizing a block");
let collider = ColliderBuilder::cuboid(4.0, 4.0).density(1.0);
commands.insert_one(*entity, collider);
}
resize.entities.clear();
}
}
1 change: 1 addition & 0 deletions src/physics/plugins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ impl Plugin for RapierPhysicsPlugin {
stage::PRE_UPDATE,
physics::create_body_and_collider_system.system(),
)
.add_system_to_stage(stage::PRE_UPDATE, physics::update_collider_system.system())
.add_system_to_stage(stage::PRE_UPDATE, physics::create_joints_system.system())
.add_system_to_stage(stage::UPDATE, physics::step_world_system.system())
.add_stage_before(
Expand Down
39 changes: 39 additions & 0 deletions src/physics/systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,45 @@ pub fn create_body_and_collider_system(
}
}

/// System responsible for replacing colliders on existing bodies when a new
/// builder is added.
///
/// NOTE: This only adds new colliders, the old collider is actually removed
/// by `destroy_body_and_collider_system`
pub fn update_collider_system(
commands: &mut Commands,
mut bodies: ResMut<RigidBodySet>,
mut colliders: ResMut<ColliderSet>,
mut entity_maps: ResMut<EntityMaps>,
with_body_query: Query<
(Entity, &RigidBodyHandleComponent, &ColliderBuilder),
With<ColliderHandleComponent>,
>,
without_body_query: Query<
(Entity, &Parent, &ColliderBuilder),
(
Without<RigidBodyHandleComponent>,
With<ColliderHandleComponent>,
),
>,
) {
for (entity, body_handle, collider_builder) in with_body_query.iter() {
let handle = colliders.insert(collider_builder.build(), body_handle.handle(), &mut bodies);
commands.insert_one(entity, ColliderHandleComponent::from(handle));
commands.remove_one::<ColliderBuilder>(entity);
entity_maps.colliders.insert(entity, handle);
}

for (entity, parent, collider_builder) in without_body_query.iter() {
if let Some(body_handle) = entity_maps.bodies.get(&parent.0) {
let handle = colliders.insert(collider_builder.build(), *body_handle, &mut bodies);
commands.insert_one(entity, ColliderHandleComponent::from(handle));
commands.remove_one::<ColliderBuilder>(entity);
entity_maps.colliders.insert(entity, handle);
}
}
}

#[test]
fn test_create_body_and_collider_system() {
use bevy::ecs::Schedule;
Expand Down
2 changes: 1 addition & 1 deletion src/render/systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub fn create_collider_renders_system(
colliders: ResMut<ColliderSet>,
query: Query<
(Entity, &ColliderHandleComponent, Option<&RapierRenderColor>),
Without<Handle<Mesh>>,
Or<(Without<Handle<Mesh>>, Changed<ColliderHandleComponent>)>,
>,
) {
let ground_color = Color::rgb(
Expand Down

0 comments on commit ce1c3eb

Please sign in to comment.