Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ codegen-units = 1
#parry2d = { path = "../parry/crates/parry2d" }
#parry3d = { path = "../parry/crates/parry3d" }
#rapier2d = { path = "../rapier/crates/rapier2d" }
#rapier3d = { path = "../rapier/crates/rapier3d" }
rapier3d = { path = "../rapier/crates/rapier3d" }

#nalgebra = { git = "https://github.com/dimforge/nalgebra", branch = "dev" }
#parry2d = { git = "https://github.com/dimforge/parry", branch = "master" }
Expand Down
2 changes: 1 addition & 1 deletion bevy_rapier3d/examples/multi_world3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn main() {
.add_plugins((
DefaultPlugins,
RapierPhysicsPlugin::<NoUserData>::default()
.with_default_world(RapierContextInitialization::NoAutomaticRapierContext),
.with_custom_initialization(RapierContextInitialization::NoAutomaticRapierContext),
RapierDebugRenderPlugin::default(),
))
.add_systems(
Expand Down
99 changes: 99 additions & 0 deletions bevy_rapier3d/examples/multi_world_interpolated3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use bevy::{input::common_conditions::input_just_pressed, prelude::*};
use bevy_rapier3d::prelude::*;

const N_WORLDS: usize = 2;

fn main() {
App::new()
.insert_resource(ClearColor(Color::srgb(
0xF9 as f32 / 255.0,
0xF9 as f32 / 255.0,
0xFF as f32 / 255.0,
)))
.add_plugins((
DefaultPlugins,
RapierPhysicsPlugin::<NoUserData>::default()
.with_custom_initialization(RapierContextInitialization::NoAutomaticRapierContext),
RapierDebugRenderPlugin::default(),
))
.insert_resource(TimestepMode::Interpolated {
dt: 1.0 / 60.0,
time_scale: 1.0,
substeps: 2,
})
.add_systems(
Startup,
((create_worlds, setup_physics).chain(), setup_graphics),
)
.add_systems(
Update,
change_world, //.run_if(input_just_pressed(KeyCode::KeyC)),
)
.run();
}

fn create_worlds(mut commands: Commands) {
for i in 0..N_WORLDS {
let mut world = commands.spawn(RapierContext::default());
if i == 0 {
world.insert(DefaultRapierContext);
}
}
}

fn setup_graphics(mut commands: Commands) {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(0.0, 3.0, -10.0)
.looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y),
..Default::default()
});
}

fn change_world(
query_context: Query<Entity, With<DefaultRapierContext>>,
q_other_ctx: Query<Entity, (With<RapierContext>, Without<DefaultRapierContext>)>,
mut query_links: Query<&mut RapierContextEntityLink>,
) {
let default_context = query_context.single();
for mut link in query_links.iter_mut() {
if link.0 == default_context {
link.0 = q_other_ctx.single();
continue;
}
link.0 = default_context;
}
}

pub fn setup_physics(mut commands: Commands) {
/*
* Create the cube
*/

let color = [
Hsla::hsl(220.0, 1.0, 0.3),
Hsla::hsl(180.0, 1.0, 0.3),
Hsla::hsl(260.0, 1.0, 0.7),
][0 % 3];

commands.spawn((
TransformBundle::from(Transform::from_xyz(0.0, 0.0, 0.0)),
RigidBody::Dynamic,
Collider::cuboid(0.5, 0.5, 0.5),
ColliderDebugColor(color),
ActiveEvents::all(),
));

/*
* Ground
*/
let color = Hsla::hsl(260.0, 1.0, 0.7);
let ground_size = 5.1;
let ground_height = 0.1;
let starting_y = -0.5 - ground_height;

commands.spawn((
TransformBundle::from(Transform::from_xyz(0.0, starting_y, 0.0)),
Collider::cuboid(ground_size, ground_height, ground_size),
ColliderDebugColor(color),
));
}
15 changes: 11 additions & 4 deletions src/pipeline/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,18 @@ pub(crate) struct EventQueue<'a> {

impl<'a> EventQueue<'a> {
fn collider2entity(&self, colliders: &ColliderSet, handle: ColliderHandle) -> Entity {
let handle_index = handle.into_raw_parts().0;
colliders
.get(handle)
.map(|co| Entity::from_bits(co.user_data as u64))
.or_else(|| self.deleted_colliders.get(&handle).copied())
.expect("Internal error: entity not found for collision event.")
.get_unknown_gen(handle_index)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a possible fix: bypassing generational check. I'm not sure generation is very important for mapping colliders to entities 🤔 ; for a collider to change entity, we'd need either very cursed code, as from my understanding it would recreate a new collider within rapier (so another index).

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If my assumption is correct, we could simplify this mapping to map to index only rather than index + generation 💭 .

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems completely incorrect ; generation is updated when we remove an entry, so it's needed to be sure we're targeting the correct entity.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internal error: entity not found for collision event with collider handle: ColliderHandle(Index { index: 0, generation: 0 }). is interesting:

There shouldn't be a generation 0 ; not after the first step 🤔 (maybe even not ever?) ; it seems to mean the arena grew unexpectedly

.map(|co| Entity::from_bits(co.0.user_data as u64))
.or_else(|| self.deleted_colliders.iter().find_map(|co| if co.0.into_raw_parts().0 == handle_index {
Some(*co.1)
}else {None}))
.unwrap_or_else(|| {
println!("{:#?}", colliders);
dbg!(&self.deleted_colliders);
panic!("Internal error: entity not found for collision event with collider handle: {handle:?}.")
})
}
}

Expand Down
12 changes: 5 additions & 7 deletions src/plugin/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,8 @@ where
self
}

/// Specifies a default world initialization strategy.
///
/// The default is to initialize a [`RapierContext`] with a length unit of 1.
pub fn with_default_world(
/// Specifies an initialization strategy when the [`App`] starts.
pub fn with_custom_initialization(
mut self,
default_world_initialization: RapierContextInitialization,
) -> Self {
Expand Down Expand Up @@ -110,6 +108,7 @@ where
systems::on_add_entity_with_parent,
systems::on_change_world,
systems::sync_removals,
apply_deferred,
#[cfg(all(feature = "dim3", feature = "async-collider"))]
systems::init_async_scene_colliders,
#[cfg(all(feature = "dim3", feature = "async-collider"))]
Expand Down Expand Up @@ -206,16 +205,15 @@ where
.register_type::<RapierConfiguration>()
.register_type::<SimulationToRenderTime>()
.register_type::<DefaultRapierContext>()
.register_type::<RapierContextInitialization>()
.register_type::<ColliderDebugColor>();
.register_type::<RapierContextInitialization>();

app.insert_resource(Events::<CollisionEvent>::default())
.insert_resource(Events::<ContactForceEvent>::default())
.insert_resource(Events::<MassModifiedEvent>::default());
let default_world_init = app.world().get_resource::<RapierContextInitialization>();
if let Some(world_init) = default_world_init {
warn!("RapierPhysicsPlugin added but a `RapierContextInitialization` resource was already existing.\
This might overwrite previous configuration made via `RapierPhysicsPlugin::with_default_world`\
This will overwrite previous configuration made via `RapierPhysicsPlugin::with_custom_initialization`\
or `RapierPhysicsPlugin::with_length_unit`.
The following resource will be used: {:?}", world_init);
} else {
Expand Down
1 change: 1 addition & 0 deletions src/plugin/systems/collider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ pub fn init_colliders(
let Some(context_entity) = context_entity else {
continue;
};
println!("init collider {entity} for world {context_entity}");

let config = config.get(context_entity).unwrap_or_else(|_| {
panic!("Failed to retrieve `RapierConfiguration` on entity {context_entity}.")
Expand Down
6 changes: 5 additions & 1 deletion src/plugin/systems/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use bevy::prelude::*;
/// for scene queries.
pub fn step_simulation<Hooks>(
mut context: Query<(
Entity,
&mut RapierContext,
&RapierConfiguration,
&mut SimulationToRenderTime,
Expand All @@ -44,10 +45,12 @@ pub fn step_simulation<Hooks>(
{
let hooks_adapter = BevyPhysicsHooksAdapter::new(hooks.into_inner());

for (mut context, config, mut sim_to_render_time) in context.iter_mut() {
for (entity, mut context, config, mut sim_to_render_time) in context.iter_mut() {
let context = &mut *context;

if config.physics_pipeline_active {
println!("step {entity}");
//println!("step {:?}", context.colliders);
context.step_simulation(
config.gravity,
*timestep_mode,
Expand All @@ -57,6 +60,7 @@ pub fn step_simulation<Hooks>(
&mut sim_to_render_time,
Some(&mut interpolation_query),
);
println!("clear");
context.deleted_colliders.clear();
} else {
context.propagate_modified_body_positions_to_colliders();
Expand Down
Loading