use crate::physics::{
ColliderHandleComponent, EventQueue, JointBuilderComponent,
JointHandleComponent, RapierConfiguration, RigidBodyHandleComponent,
};
use bevy::ecs::Mut;
use bevy::prelude::*;
use rapier::dynamics::{IntegrationParameters, JointSet, RigidBodyBuilder, RigidBodySet};
use rapier::geometry::{BroadPhase, ColliderBuilder, ColliderSet, NarrowPhase};
use rapier::pipeline::PhysicsPipeline;
pub fn create_body_and_collider_system(
mut commands: Commands,
mut bodies: ResMut<RigidBodySet>,
mut colliders: ResMut<ColliderSet>,
entity: Entity,
body_builder: &RigidBodyBuilder,
collider_builder: &ColliderBuilder,
) {
let handle = bodies.insert(body_builder.build());
commands.insert_one(entity, RigidBodyHandleComponent::from(handle));
commands.remove_one::<RigidBodyBuilder>(entity);
let handle = colliders.insert(collider_builder.build(), handle, &mut bodies);
commands.insert_one(entity, ColliderHandleComponent::from(handle));
commands.remove_one::<ColliderBuilder>(entity);
}
pub fn create_joints_system(
mut commands: Commands,
mut bodies: ResMut<RigidBodySet>,
mut joints: ResMut<JointSet>,
mut query: Query<(Entity, &JointBuilderComponent)>,
query_bodyhandle: Query<&RigidBodyHandleComponent>,
) {
for (entity, joint) in &mut query.iter() {
let body1 = query_bodyhandle.get::<RigidBodyHandleComponent>(joint.entity1);
let body2 = query_bodyhandle.get::<RigidBodyHandleComponent>(joint.entity2);
if let (Ok(body1), Ok(body2)) = (body1, body2) {
let handle = joints.insert(&mut bodies, body1.handle(), body2.handle(), joint.params);
commands.insert_one(
entity,
JointHandleComponent::new(handle, joint.entity1, joint.entity2),
);
commands.remove_one::<JointBuilderComponent>(entity);
}
}
}
pub fn step_world_system(
configuration: Res<RapierConfiguration>,
integration_parameters: Res<IntegrationParameters>,
mut pipeline: ResMut<PhysicsPipeline>,
mut broad_phase: ResMut<BroadPhase>,
mut narrow_phase: ResMut<NarrowPhase>,
mut bodies: ResMut<RigidBodySet>,
mut colliders: ResMut<ColliderSet>,
mut joints: ResMut<JointSet>,
events: Res<EventQueue>,
) {
if events.auto_clear {
events.clear();
}
if configuration.active {
pipeline.step(
&configuration.gravity,
&integration_parameters,
&mut broad_phase,
&mut narrow_phase,
&mut bodies,
&mut colliders,
&mut joints,
&*events,
);
}
}
pub fn sync_transform_system(
bodies: ResMut<RigidBodySet>,
configuration: Res<RapierConfiguration>,
rigid_body: &RigidBodyHandleComponent,
mut transform: Mut<Transform>,
) {
if let Some(rb) = bodies.get(rigid_body.handle()) {
let pos = rb.position;
#[cfg(feature = "dim2")]
{
let rot = na::UnitQuaternion::new(na::Vector3::z() * pos.rotation.angle());
*transform.translation_mut().x_mut() = pos.translation.vector.x * configuration.scale;
*transform.translation_mut().y_mut() = pos.translation.vector.y * configuration.scale;
transform.set_rotation(Quat::from_xyzw(rot.i, rot.j, rot.k, rot.w));
}
#[cfg(feature = "dim3")]
{
transform.set_translation(
Vec3::new(
pos.translation.vector.x,
pos.translation.vector.y,
pos.translation.vector.z,
) * configuration.scale,
);
transform.set_rotation(Quat::from_xyzw(
pos.rotation.i,
pos.rotation.j,
pos.rotation.k,
pos.rotation.w,
));
}
}
}