-
-
Notifications
You must be signed in to change notification settings - Fork 274
Rapier context as a Component #545
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 18 commits
d4ff57e
3cb7676
a01395e
4e7c36c
4952ea5
7a4ba5e
24fd036
f900dac
d171fe4
8dd49ee
2b262ea
f849cd2
df3578e
ac16f38
941b52e
5669a8c
0b9ca86
f4643ef
f8b296a
0e46610
75c2195
ccd2be7
9142888
ba0cd76
6d10fe6
d0b07a0
2676c35
40be1f1
deb0a06
cf165bd
aeab8c9
07eefbb
4cccde1
cbfe138
5dc5b2d
d0961d0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -8,6 +8,16 @@ and new features. Please have a look at the | |||||||||
|
|
||||||||||
| - Update to rapier `0.21`. | ||||||||||
| - Update to nalgebra `0.33`. | ||||||||||
| - `RapierContext`, `RapierConfiguration` and `RenderToSimulationTime` are now a `Component` | ||||||||||
| - Rapier now supports multiple worlds, see example `multi_world3` for usage details. | ||||||||||
ThierryBerger marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| - Migration guide: | ||||||||||
| - `ResMut<mut RapierContext>` -> `DefaultRapierContextAccessMut` | ||||||||||
| - `Res<RapierContext>` -> `DefaultRapierContextAccess` | ||||||||||
|
||||||||||
| - `ResMut<mut RapierContext>` -> `DefaultRapierContextAccessMut` | |
| - `Res<RapierContext>` -> `DefaultRapierContextAccess` | |
| - `ResMut<mut RapierContext>` -> `WriteDefaultRapierContext` | |
| - `Res<RapierContext>` -> `ReadDefaultRapierContext` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TL;DR: ok :)
I tend to prefer suffixes to prefix, so when you're searching for a term, the alphabetical order comes better grouped.
That said, my initial naming does a bad job at putting Default first. For this reason, I might prefer a RapierContextDefaultRead ; but that would probably mean renaming DefaultRapierContext to RapierContextDefault, which might sound weird.
For the idiomatic way, I wanted to keep close to Res / ResMut, which is very idiomatic. I believe Read/Write is used for individual components, which is not exaclty the case here. I'm not sure I've seen it in SystemParam. But I'm not sure.
In any way, I don't feel too opinionated about that, so I'll just implement your suggestion 😅.
ThierryBerger marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| 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_default_world(RapierContextInitialization::NoAutomaticRapierContext), | ||
ThierryBerger marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| RapierDebugRenderPlugin::default(), | ||
| )) | ||
| .add_systems( | ||
| Startup, | ||
| ((create_worlds, setup_physics).chain(), setup_graphics), | ||
| ) | ||
| .add_systems(Update, move_platforms) | ||
| .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(), WorldId(i))); | ||
ThierryBerger marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| 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() | ||
| }); | ||
| } | ||
|
|
||
| #[derive(Component)] | ||
| pub struct WorldId(pub usize); | ||
|
|
||
| #[derive(Component)] | ||
| struct Platform { | ||
| starting_y: f32, | ||
| } | ||
|
|
||
| fn move_platforms(time: Res<Time>, mut query: Query<(&mut Transform, &Platform)>) { | ||
| for (mut transform, platform) in query.iter_mut() { | ||
| transform.translation.y = platform.starting_y + -time.elapsed_seconds().sin(); | ||
| } | ||
| } | ||
|
|
||
| /// Demonstrates how easy it is to move one entity to another world. | ||
| fn change_world( | ||
| query_context: Query<Entity, With<DefaultRapierContext>>, | ||
| mut query_links: Query<(Entity, &mut RapierContextEntityLink)>, | ||
| ) { | ||
| let default_context = query_context.single(); | ||
| for (e, mut link) in query_links.iter_mut() { | ||
| if link.0 == default_context { | ||
| continue; | ||
| } | ||
| link.0 = default_context; | ||
| println!("changing world of {} for world {}", e, link.0); | ||
| } | ||
ThierryBerger marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| pub fn setup_physics( | ||
| context: Query<(Entity, &WorldId), With<RapierContext>>, | ||
| mut commands: Commands, | ||
| ) { | ||
| for (context_entity, id) in context.iter() { | ||
| let id = id.0; | ||
|
|
||
| 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), | ||
| ][id % 3]; | ||
|
|
||
| /* | ||
| * Ground | ||
| */ | ||
| let ground_size = 5.1; | ||
| let ground_height = 0.1; | ||
|
|
||
| let starting_y = (id as f32) * -0.5 - ground_height; | ||
|
|
||
| let mut platforms = commands.spawn(( | ||
| TransformBundle::from(Transform::from_xyz(0.0, starting_y, 0.0)), | ||
| Collider::cuboid(ground_size, ground_height, ground_size), | ||
| ColliderDebugColor(color), | ||
| RapierContextEntityLink(context_entity), | ||
| )); | ||
| if id == 1 { | ||
| platforms.insert(Platform { starting_y }); | ||
| } | ||
|
|
||
| /* | ||
| * Create the cube | ||
| */ | ||
|
|
||
| commands.spawn(( | ||
| TransformBundle::from(Transform::from_xyz(0.0, 1.0 + id as f32 * 5.0, 0.0)), | ||
| RigidBody::Dynamic, | ||
| Collider::cuboid(0.5, 0.5, 0.5), | ||
| ColliderDebugColor(color), | ||
| RapierContextEntityLink(context_entity), | ||
| )); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.