Skip to content
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

damn thats a lot of commits #1

Open
wants to merge 87 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
5d73dbb
Add possibility of setting gravity scale for specific entities
mmatvein Dec 14, 2023
6a2977c
Fix compiler warning
mmatvein Dec 14, 2023
d95e2b3
Make external force & gravity scale code more robust
mmatvein Dec 14, 2023
3396784
Set should_query_particle_system for b2RayCast<T> to always return fa…
mmatvein Dec 14, 2023
c098006
Add support for adding torque to a body
mmatvein Dec 16, 2023
382f0e9
Set friction properly for ffi::b2FixtureDef when extracting from b2Fi…
mmatvein Dec 16, 2023
0e2f1a6
Start adding filtering to ray casts
mmatvein Dec 19, 2023
b2a8555
Make filter usage for ray casts nicer
mmatvein Dec 19, 2023
53d9847
Add support for filtering ray casts based on fixture's filter categor…
mmatvein Dec 19, 2023
58d2917
Extract b2Filter into its own struct
mmatvein Dec 20, 2023
65f08fb
Tweak interface of b2Fixture to make it more consistent
mmatvein Dec 20, 2023
138c039
Implement collision_processing example
mmatvein Dec 21, 2023
6168f89
Add end_contact handling
mmatvein Dec 21, 2023
8f8586d
Add normal and contact points to b2Contact
mmatvein Dec 21, 2023
a1925e9
Add particle body contact events
mmatvein Dec 26, 2023
78d5784
Split contact related code into multiple files
mmatvein Dec 30, 2023
a0aa50c
Add particle body contacts into b2ParticleContacts component each frame
mmatvein Jan 1, 2024
2157b8d
Add support for destroying particles
mmatvein Jan 2, 2024
fcd0ae3
Make LiquidFunSet pub
mmatvein Jan 2, 2024
330120d
Add support for creating individual particles
mmatvein Jan 6, 2024
e5f9bad
Add support for chain shapes
mmatvein Jan 11, 2024
6b296c8
Point bevy_liquidfun to a newer version of libliquidfun-sys
mmatvein Jan 12, 2024
8e12b9f
Implement water gun with charging mechanics
mmatvein Jan 28, 2024
24ed793
Add PhysicsSchedule that runs the physics simulation inside its own s…
mmatvein Feb 4, 2024
fd4cf53
Clean up a bit of code in body creation
mmatvein Feb 7, 2024
7c3c556
Run physics systems only if world exists
mmatvein Feb 10, 2024
0600930
Improve safety of pointer operations in physics world
mmatvein Feb 10, 2024
0dfd90f
Add support for external impulses
mmatvein Feb 13, 2024
ab0abd5
Add ExternalForce/Impulse/Torque into b2BodyBundle
mmatvein Feb 13, 2024
c4c7cd0
Add support for getting contacts either through the b2Contacts resour…
mmatvein Feb 21, 2024
0a622a2
Set default particle iterations to 1
mmatvein Feb 23, 2024
c174263
Add support for max frame delta to avoid death spirals
mmatvein Feb 26, 2024
314f97c
Reinstate transform extrapolation based on how much time has been acc…
mmatvein Mar 12, 2024
fc406a3
Fix compilation issues in bevy_liquidfun examples
mmatvein Apr 9, 2024
619baf0
Update Bevy to 0.13.2
mmatvein Apr 11, 2024
5c34500
Fix all KeyCode references to Bevy 0.13 format
mmatvein Apr 11, 2024
63419aa
Fix all Input<> references to ButtonInput<>
mmatvein Apr 11, 2024
2175967
Fix missing ; in send_contact_events
mmatvein Apr 11, 2024
14876ca
Fix potential issue with particle body contacts
mmatvein Apr 12, 2024
d9ebe34
Remove lifetime requirement from b2World
mmatvein Apr 18, 2024
ab3107e
Make b2World a Resource instead of a NonSend
mmatvein Apr 18, 2024
4ccd789
Add Box2D chain example
mmatvein May 7, 2024
99f2cd0
Implement distance joint
mmatvein May 7, 2024
4308270
Make a bunch of box2d types Reflect
mmatvein May 8, 2024
0fa7d94
Add weld joint to bevy_liquidfun
thevile May 13, 2024
a716b59
Make PhysicsSchedule setup more robust
mmatvein May 14, 2024
afcface
Add weld joint
thevile May 14, 2024
b0f16c7
Fix warning in destroy_removed_bodies
mmatvein May 14, 2024
88b8f15
Add motor joint and relevant example
mmatvein May 15, 2024
2d7a71f
Refactor joint creation and syncing to happen through generic functions
mmatvein May 15, 2024
e5cde67
Register b2MotorJoint and b2WeldJoint types
mmatvein May 15, 2024
76544f7
Fix issue in joint/body destruction order
mmatvein May 15, 2024
5e05b01
Use virtual time in physics in order to be able to slow it down
thevile May 15, 2024
055450c
Improve ray cast filtering to support multiple types of filters in one
mmatvein May 16, 2024
acc60a4
Add rustfmt.toml
mmatvein May 17, 2024
67c7d7d
Reformat all code with new rustfmt.toml
mmatvein May 17, 2024
bf0a51e
Add sensor example
thevile May 20, 2024
5724917
Add sensor particle example
thevile May 21, 2024
a1f9925
Expose velocities buffer and add support of ParticleApplyForce
thevile May 21, 2024
73ab71d
Add support for b2ParticlesInContact to fixtures as well
thevile May 21, 2024
12c0d03
Fix compiler warnings
mmatvein May 22, 2024
e95865e
Add create_body and create_multi_fixture_body to Commands
mmatvein May 22, 2024
8f9f110
Rename b2Commands to b2BodyCommands
mmatvein May 22, 2024
8f335a3
Implement all bevy_liquidfun examples using new create_body API
mmatvein May 22, 2024
241c6dc
Rename create_body to spawn_body to match Commands.spawn naming
mmatvein May 22, 2024
04dccdc
Make b2Body internals visible in bevy-inspector-egui
mmatvein May 27, 2024
db82f0b
Make b2Fixture internals visible in bevy-inspector-egui
mmatvein May 27, 2024
1656e9f
Add reflect type_paths to all applicable bevy_liquidfun structs
mmatvein May 27, 2024
bf594f7
Improve serializability of physics world
mmatvein May 27, 2024
8b1b89b
Register DebugDrawFixtures type
mmatvein May 27, 2024
a9c8c85
Fix issue causing physics to be quite broken
mmatvein May 30, 2024
3717628
Bodies are now only synced from bevy to box2d if they've changed for …
mmatvein May 30, 2024
b551f66
Reformat all code
mmatvein Jun 5, 2024
01c6aa6
Add possibility to ignore sensors when ray casting
mmatvein Jun 7, 2024
6e412a5
Add PartialEq to b2BodyType
mmatvein Jun 11, 2024
bf39b1d
Add support to run physics in a specific SystemSet
mmatvein Jun 11, 2024
082bd0c
Set up more robust deletion of joints, fixtures and bodies no matter …
mmatvein Jun 17, 2024
48dd6d7
Fix shopkeeper
thevile Jun 20, 2024
ce67160
Fix silly issue causing body fixture list not to be up-to-date
mmatvein Jun 20, 2024
aac9502
Stop printing warning message when fixture to be destroyed was on the…
mmatvein Jun 20, 2024
8761c26
Update to Bevy 0.14
mmatvein Aug 2, 2024
8bbd87c
Format all code
mmatvein Aug 2, 2024
ca7362c
Add support for applying a transform onto a b2Shape to transform all …
mmatvein Aug 6, 2024
ab5762f
Change b2Body <-> b2Fixture linkup to be done based on entity hierarchy
mmatvein Aug 9, 2024
b97926c
Simplify structure of b2Fixture by getting rid of b2FixtureDef
mmatvein Aug 9, 2024
dcf6150
Increment bevy_liquidfun libliquidfun-sys version to 0.4.0
mmatvein Aug 14, 2024
13c0da6
Update bevy_liquidfun README
mmatvein Aug 14, 2024
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
12 changes: 9 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,14 @@ keywords = ["liquidfun", "box2d", "physics", "bevy"]
[dependencies]
autocxx = "0.26.0"
bitflags = "2.4.1"
bevy = "0.12"
libliquidfun-sys = "0.2.0"
bevy = "0.14.0"
libliquidfun-sys = "0.4.0"

bevy-inspector-egui = { version = "0.25.0", optional = true }

[dev-dependencies]
rand = "0.8"
rand = "0.8"

[features]
bevy-inspector-egui = ["dep:bevy-inspector-egui"]

6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ A Bevy friendly wrapper of Box2D and LiquidFun.
This crate wraps [libliquidfun-sys](https://github.com/mmatvein/libliquidfun-sys) to integrate Box2D and LiquidFun with the [Bevy game engine](https://github.com/bevyengine/bevy).

### Remarks
- The library is not fully featured yet. It has been developed with 'Example Driven Development' so far, which means that the examples showcase _everything_ available at this moment.
- Feedback on the APIs, usability & overall code quality is very welcome. I am not very accustomed to Rust and it's a learning process.
- Pull Requests are welcome, but this crate is so early in development that it is important for me to have full and thorough understanding of all the bits that go into it.
- The library is not fully featured yet. It has been developed with the needs of our game in mind, so the implemented features reflect what we've needed. Early on "Example Driven Development" was used, by porting over regular Box2D examples.
- Feedback on the APIs, usability & overall code quality is very welcome.
- Pull Requests are welcome, but this crate is very much a work in progress alongside our game, so we need full ownership of what goes into the codebase.

### Acknowledgements
This crate is made possible by excellent prior work by others. Huge thanks go to:
Expand Down
109 changes: 109 additions & 0 deletions examples/chain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
extern crate bevy;
extern crate bevy_liquidfun;

use bevy::prelude::*;
use bevy_liquidfun::{
collision::b2Shape,
dynamics::{
b2BodyCommands, b2BodyDef, b2BodyType::Dynamic, b2Fixture, b2RevoluteJointDef, b2World, CreateRevoluteJoint
},
plugins::{LiquidFunDebugDrawPlugin, LiquidFunPlugin},
utils::DebugDrawFixtures,
};

fn main() {
App::new()
.add_plugins((
DefaultPlugins,
LiquidFunPlugin::default(),
LiquidFunDebugDrawPlugin,
))
.add_systems(Startup, setup_camera)
.add_systems(Startup, (setup_physics_world, setup_physics_bodies).chain())
.run();
}

fn setup_camera(mut commands: Commands) {
commands.spawn(Camera2dBundle {
projection: OrthographicProjection {
scale: 0.05,
far: 1000.,
near: -1000.,
..OrthographicProjection::default()
},
transform: Transform::from_translation(Vec3::new(0., 10., 0.)),
..Camera2dBundle::default()
});
}

fn setup_physics_world(world: &mut World) {
let gravity = Vec2::new(0., -9.81);
let b2_world = b2World::new(gravity);
world.insert_resource(b2_world);
}

fn setup_physics_bodies(mut commands: Commands) {
let ground_fixture = b2Fixture::new(
b2Shape::EdgeTwoSided {
v1: Vec2::new(-40., 0.),
v2: Vec2::new(40., 0.),
},
0.0,
);
let ground_entity = commands
.spawn_body(&b2BodyDef::default(), ground_fixture)
.insert(DebugDrawFixtures::default_static())
.id();

let box_shape = b2Shape::create_box(0.6, 0.125);
let box_fixture = b2Fixture {
shape: box_shape,
density: 20.0,
friction: 0.2,
..default()
};
const Y: f32 = 25.0;

let mut body_entities = vec![Entity::PLACEHOLDER; 30];
for i in 0..30 {
let body_def = b2BodyDef {
body_type: Dynamic,
position: Vec2::new(0.5 + i as f32, Y),
..default()
};

body_entities[i] = commands
.spawn_body(&body_def, box_fixture.clone())
.insert(DebugDrawFixtures {
draw_up_vector: false,
draw_right_vector: false,
..DebugDrawFixtures::default_dynamic()
})
.id();
}

let joint_def = b2RevoluteJointDef {
local_anchor_a: Vec2::new(0.5, 0.),
local_anchor_b: Vec2::new(-0.5, 0.),
..default()
};

for body_pair in body_entities.windows(2) {
let (body_a, body_b) = (body_pair[0], body_pair[1]);
commands
.spawn_empty()
.add(CreateRevoluteJoint::new(body_a, body_b, false, &joint_def));
}

let joint_def = b2RevoluteJointDef {
local_anchor_a: Vec2::new(0., Y),
..joint_def
};

commands.spawn_empty().add(CreateRevoluteJoint::new(
ground_entity,
body_entities[0],
true,
&joint_def,
));
}
44 changes: 18 additions & 26 deletions examples/circle_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ extern crate bevy;
extern crate bevy_liquidfun;

use bevy::prelude::*;

use bevy_liquidfun::dynamics::{b2BodyBundle, b2Fixture, b2FixtureDef};
use bevy_liquidfun::plugins::{LiquidFunDebugDrawPlugin, LiquidFunPlugin};
use bevy_liquidfun::utils::DebugDrawFixtures;
use bevy_liquidfun::{
collision::b2Shape,
dynamics::{b2BodyDef, b2BodyType::Dynamic, b2World},
dynamics::{b2BodyCommands, b2BodyDef, b2BodyType::Dynamic, b2Fixture, b2World},
plugins::{LiquidFunDebugDrawPlugin, LiquidFunPlugin},
utils::DebugDrawFixtures,
};

fn main() {
App::new()
.add_plugins((
Expand Down Expand Up @@ -44,42 +43,35 @@ fn setup_camera(mut commands: Commands) {
fn setup_physics_world(world: &mut World) {
let gravity = Vec2::new(0., -9.81);
let b2_world = b2World::new(gravity);
world.insert_non_send_resource(b2_world);
world.insert_resource(b2_world);
}

fn setup_physics_bodies(mut commands: Commands) {
{
let ground_entity = commands.spawn(b2BodyBundle::default()).id();

let shape = b2Shape::EdgeTwoSided {
v1: Vec2::new(-40., 0.),
v2: Vec2::new(40., 0.),
};
let fixture_def = b2FixtureDef::new(shape, 0.);
commands.spawn((
b2Fixture::new(ground_entity, &fixture_def),
DebugDrawFixtures::default_static(),
));
let fixture = b2Fixture::new(
b2Shape::EdgeTwoSided {
v1: Vec2::new(-40., 0.),
v2: Vec2::new(40., 0.),
},
0.,
);
commands
.spawn_body(&b2BodyDef::default(), fixture)
.insert(DebugDrawFixtures::default_static());
}

let circle_shape = b2Shape::Circle {
radius: 1.,
position: Vec2::ZERO,
};
let fixture_def = b2FixtureDef::new(circle_shape, 1.);
for i in 0..10 {
let body_def = b2BodyDef {
body_type: Dynamic,
position: Vec2::new(0., 4. + 3. * i as f32),
..default()
};
let mut body_bundle = b2BodyBundle::new(&body_def);
body_bundle.body.linear_velocity = Vec2::new(0., -50.);
let body_entity = commands.spawn(body_bundle).id();

commands.spawn((
b2Fixture::new(body_entity, &fixture_def),
DebugDrawFixtures::default_dynamic(),
));
commands
.spawn_body(&body_def, b2Fixture::new(circle_shape.clone(), 1.))
.insert(DebugDrawFixtures::default_dynamic());
}
}
167 changes: 167 additions & 0 deletions examples/collision_processing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
extern crate bevy;
extern crate bevy_liquidfun;
extern crate rand;

use std::ops::RangeInclusive;

use bevy::prelude::*;
use bevy_liquidfun::{
collision::b2Shape,
dynamics::{
b2BeginContactEvent, b2Body, b2BodyCommands, b2BodyDef, b2BodyType::Dynamic, b2Fixture, b2World
},
plugins::{LiquidFunDebugDrawPlugin, LiquidFunPlugin},
schedule::{PhysicsSchedule, PhysicsUpdateStep},
utils::DebugDrawFixtures,
};
use rand::prelude::*;

fn main() {
App::new()
.add_plugins((
DefaultPlugins,
LiquidFunPlugin::default(),
LiquidFunDebugDrawPlugin,
))
.add_systems(Startup, setup_camera)
.add_systems(
Startup,
(setup_physics_world, setup_bodies.after(setup_physics_world)),
)
.add_systems(
PhysicsSchedule,
process_collisions.in_set(PhysicsUpdateStep::UserCode),
)
.run();
}

fn setup_camera(mut commands: Commands) {
commands.spawn(Camera2dBundle {
projection: OrthographicProjection {
scale: 0.07,
far: 1000.,
near: -1000.,
..OrthographicProjection::default()
},
transform: Transform::from_translation(Vec3::new(0., 10., 0.)),
..Camera2dBundle::default()
});
}

fn setup_physics_world(mut commands: Commands) {
let gravity = Vec2::new(0., -9.81);
let b2_world = b2World::new(gravity);
commands.insert_resource(b2_world);
}

fn setup_bodies(mut commands: Commands) {
{
let fixture = b2Fixture::new(
b2Shape::EdgeTwoSided {
v1: Vec2::new(-50., 0.),
v2: Vec2::new(50., 0.),
},
0.,
);
commands
.spawn_body(&b2BodyDef::default(), fixture)
.insert(DebugDrawFixtures::default_static());
}

let x_range = -5.0..=5.0;
let y_range = 2.0..=35.0;
let mut rng = thread_rng();

// small triangle
{
let shape = b2Shape::Polygon {
vertices: vec![Vec2::new(-1., 0.), Vec2::new(1., 0.), Vec2::new(0., 2.)],
};
create_body_in_random_position(&mut commands, shape, &x_range, &y_range, &mut rng);
}

// large triangle
{
let shape = b2Shape::Polygon {
vertices: vec![Vec2::new(-2., 0.), Vec2::new(2., 0.), Vec2::new(0., 4.)],
};
create_body_in_random_position(&mut commands, shape, &x_range, &y_range, &mut rng);
}

// small box
{
let shape = b2Shape::create_box(1., 0.5);
create_body_in_random_position(&mut commands, shape, &x_range, &y_range, &mut rng);
}

// large box
{
let shape = b2Shape::create_box(2., 1.);
create_body_in_random_position(&mut commands, shape, &x_range, &y_range, &mut rng);
}

// small circle
{
let shape = b2Shape::Circle {
radius: 1.,
position: Vec2::ZERO,
};
create_body_in_random_position(&mut commands, shape, &x_range, &y_range, &mut rng);
}

// large circle
{
let shape = b2Shape::Circle {
radius: 2.,
position: Vec2::ZERO,
};

create_body_in_random_position(&mut commands, shape, &x_range, &y_range, &mut rng);
}
}

fn create_body_in_random_position(
commands: &mut Commands,
shape: b2Shape,
x_range: &RangeInclusive<f32>,
y_range: &RangeInclusive<f32>,
rng: &mut ThreadRng,
) {
commands
.spawn_body(
&b2BodyDef {
body_type: Dynamic,
position: Vec2::new(
rng.gen_range(x_range.clone()),
rng.gen_range(y_range.clone()),
),
..default()
},
b2Fixture::new(shape, 1.0),
)
.insert(DebugDrawFixtures::default_dynamic());
}

fn process_collisions(
mut commands: Commands,
bodies: Query<&b2Body>,
mut event_reader: EventReader<b2BeginContactEvent>,
) {
for contact_event in event_reader.read() {
let contact = contact_event.0;
let body_a = bodies.get(contact.body_a);
let body_b = bodies.get(contact.body_b);
if body_a.is_err() || body_b.is_err() {
continue;
}

let (body_a, body_b) = (body_a.unwrap(), body_b.unwrap());
if body_a.mass() != 0.0 && body_b.mass() != 0.0 {
if body_a.mass() > body_b.mass() {
commands.entity(contact.body_b).despawn_recursive();
} else {
commands.entity(contact.body_a).despawn_recursive();
}
}
}
}
Loading