You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
3.9 KiB

use std::time::Instant;
use cgmath::{Euler, Quaternion};
use legion::world::SubWorld;
use legion::IntoQuery;
use legion::*;
use nalgebra::Quaternion as naQuaternion;
use rapier3d::dynamics::{IntegrationParameters, JointSet, RigidBodySet};
use rapier3d::geometry::{BroadPhase, ColliderSet, NarrowPhase};
use rapier3d::pipeline::{PhysicsPipeline, ChannelEventCollector};
use crate::camera::{Camera, CameraController};
use crate::components::{Collider, LoopState, Mesh, Physics, Position};
use imgui::FontSource;
use crate::physics::state::PhysicsState;
#[system]
#[write_component(Collider)]
#[write_component(Physics)]
#[write_component(Mesh)]
pub fn run_physics(
world: &mut SubWorld,
#[resource] physics_state: &mut PhysicsState,
#[resource] physics_pipeline: &mut PhysicsPipeline,
) {
// Make sure all the entities we care about are added to the system
let mut query = <(&mut Collider, &mut Physics, &mut Mesh)>::query();
for (collider, physics, mesh) in query.iter_mut(world) {
let rigid_body_handle = match physics.rigid_body_handle {
None => {
let handle = physics_state.bodies.insert(physics.rigid_body.clone());
physics.rigid_body_handle = Some(handle);
physics.rigid_body_handle.unwrap()
}
Some(handle) => handle,
};
if collider.collider_handle == None {
let handle = physics_state.colliders.insert(
collider.collider.clone(),
rigid_body_handle,
&mut physics_state.bodies,
);
collider.collider_handle = Some(handle);
}
}
let (contact_send, contact_recv) = crossbeam::channel::unbounded();
let (intersection_send, intersection_recv) = crossbeam::channel::unbounded();
let event_handler = ChannelEventCollector::new(intersection_send, contact_send);
// run the physics step
physics_pipeline.step(
&physics_state.gravity,
&physics_state.integration_parameters,
&mut physics_state.broad_phase,
&mut physics_state.narrow_phase,
&mut physics_state.bodies,
&mut physics_state.colliders,
&mut physics_state.joints,
None,
None,
&event_handler,
);
while let Ok(intersection_event) = intersection_recv.try_recv() {
println!("{:?}", intersection_event)
}
while let Ok(contact_event) = contact_recv.try_recv() {
println!("{:?}", contact_event)
}
}
#[system]
#[write_component(Camera)]
#[write_component(CameraController)]
pub fn update_camera(world: &mut SubWorld, #[resource] loop_state: &mut LoopState) {
let mut query = <(&mut Camera, &mut CameraController)>::query();
for (mut camera, controller) in query.iter_mut(world) {
controller.update_camera(&mut camera, loop_state.step_size)
}
}
#[system]
#[write_component(Collider)]
#[write_component(Physics)]
#[write_component(Mesh)]
#[write_component(Position)]
pub fn update_models(
world: &mut SubWorld,
#[resource] physics_state: &mut PhysicsState,
#[resource] physics_pipeline: &mut PhysicsPipeline,
) {
// Make sure all the entities we care about are added to the system
let mut query = <(&mut Collider, &mut Physics, &mut Mesh, &mut Position)>::query();
for (collider, physics, mesh, position) in query.iter_mut(world) {
let pos = physics_state
.bodies
.get(physics.rigid_body_handle.unwrap())
.unwrap()
.position();
position.x = pos.translation.x;
position.y = pos.translation.y;
position.z = pos.translation.z;
let q = Quaternion::new(
pos.rotation.w,
pos.rotation.i,
pos.rotation.j,
pos.rotation.k,
);
let rotation = Euler::from(q);
position.rot.x = rotation.x.into();
position.rot.y = rotation.y.into();
position.rot.z = rotation.z.into();
}
}