Physics Support
- NEW CRATE: raidillon_physics. - Added new models to be able to test the physics support. - Added a new system "PhysicsSystem" to apply physics calculations to the ECS world. - NEW COMPONENT: RigidBodyComponent
This commit is contained in:
parent
4b97bd98d2
commit
db1b427e2a
13 changed files with 697 additions and 43 deletions
|
|
@ -13,6 +13,8 @@ raidillon_platform = { path = "../platform" }
|
|||
raidillon_assets = { path = "../asset" }
|
||||
raidillon_ecs = { path = "../ecs" }
|
||||
raidillon_engine = { path = "../engine" }
|
||||
raidillon_physics = { path = "../physics" }
|
||||
raidillon_glium = { path = "../glium_platform", optional = true }
|
||||
glam = "0.30.5"
|
||||
winit = "0.30.12"
|
||||
rapier3d = "0.30.1"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
mod systems;
|
||||
use std::fmt::format;
|
||||
use glam::{Quat, Vec3};
|
||||
use rapier3d::dynamics::RigidBodyType;
|
||||
use rapier3d::prelude::ColliderBuilder;
|
||||
use raidillon_engine::{Engine, system::System, EngineResources};
|
||||
use raidillon_engine::system::SystemContext;
|
||||
use raidillon_platform::{Platform, Camera, PlatformContext};
|
||||
use raidillon_assets::model_path;
|
||||
use raidillon_core::engine::EngineTrait;
|
||||
use raidillon_ecs::components::ModelHandle;
|
||||
use raidillon_ecs::components::{ModelHandle, RigidBodyComponent};
|
||||
use raidillon_ecs::Transform;
|
||||
use raidillon_core::scene::Scene;
|
||||
#[cfg(feature = "glium")]
|
||||
|
|
@ -15,9 +18,11 @@ use winit::event::DeviceEvent::MouseMotion;
|
|||
use winit::keyboard::{KeyCode, PhysicalKey};
|
||||
use raidillon_core::DebugUIBuffer;
|
||||
use raidillon_engine::systems::fps_camera::FPSDebugCameraSystem;
|
||||
use raidillon_physics::Physics;
|
||||
use crate::systems::PhysicsSystem;
|
||||
|
||||
const TEST_GLTF: &str = "pink-monkey.gltf";
|
||||
|
||||
const TEST_GLTF: &str = "sphere.glb";
|
||||
const PLANE_GLTF: &str = "plane.glb";
|
||||
const MAIN_SCENE_ID: &str = "main_scene";
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
@ -40,28 +45,45 @@ impl System for UpdateAspectRatioSystem {
|
|||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct RenderingTestSystem {
|
||||
rotation_speed: std::rc::Rc<std::cell::RefCell<f32>>,
|
||||
}
|
||||
struct RenderingTestSystem;
|
||||
|
||||
impl System for RenderingTestSystem {
|
||||
fn load_world(&mut self, res: &mut EngineResources, scene: &mut Scene) {
|
||||
let pctx = res.get::<PlatformContext>().unwrap();
|
||||
let pctx = res.get::<PlatformContext>().expect("PlatformContext missing").clone();
|
||||
let physics = res.get_mut::<Physics>().expect("Physics missing");
|
||||
|
||||
self.rotation_speed = std::rc::Rc::new(std::cell::RefCell::new(5.0));
|
||||
|
||||
let mut am = pctx.asset_manager.borrow_mut();
|
||||
|
||||
am.load_gltf(TEST_GLTF, &model_path(TEST_GLTF));
|
||||
|
||||
scene.world.spawn((
|
||||
Transform {
|
||||
translation: Vec3::new(0.0, 0.0, 0.0),
|
||||
rotation: Quat::IDENTITY,
|
||||
scale: Vec3::new(1.0, 1.0, 1.0),
|
||||
},
|
||||
ModelHandle(TEST_GLTF),
|
||||
));
|
||||
// Spawn Sphere
|
||||
{
|
||||
let tr = Transform {
|
||||
translation: Vec3::new(0.0, 5.0, 0.0),
|
||||
rotation: Quat::IDENTITY,
|
||||
scale: Vec3::new(1.0, 1.0, 1.0),
|
||||
};
|
||||
let collider = ColliderBuilder::ball(1.0).build();
|
||||
let rb_handle = physics.add_rigid_body(RigidBodyType::Dynamic, tr, collider);
|
||||
pctx.asset_manager.borrow_mut().load_gltf(TEST_GLTF, &model_path(TEST_GLTF));
|
||||
scene.world.spawn((
|
||||
tr,
|
||||
ModelHandle(TEST_GLTF),
|
||||
RigidBodyComponent(rb_handle),
|
||||
));
|
||||
}
|
||||
// Spawn Plane
|
||||
{
|
||||
let tr = Transform {
|
||||
translation: Vec3::new(0.0, 0.0, 0.0),
|
||||
rotation: Quat::IDENTITY,
|
||||
scale: Vec3::new(10.0, 1.0, 10.0),
|
||||
};
|
||||
let collider = ColliderBuilder::cuboid(10.0, 0.01, 10.0).build();
|
||||
let rb_handle = physics.add_rigid_body(RigidBodyType::Fixed, tr, collider);
|
||||
pctx.asset_manager.borrow_mut().load_gltf(PLANE_GLTF, &model_path(PLANE_GLTF));
|
||||
scene.world.spawn((
|
||||
tr,
|
||||
ModelHandle(PLANE_GLTF),
|
||||
RigidBodyComponent(rb_handle),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
fn frame_update(&mut self, res: &mut EngineResources, scene: &mut Scene) {
|
||||
|
|
@ -72,22 +94,13 @@ impl System for RenderingTestSystem {
|
|||
dbg_ui.text(format!("Frame Delta: {}", pctx.time_ctx.frame_dt));
|
||||
dbg_ui.text(format!("Fixed Delta: {}", pctx.time_ctx.fixed_dt));
|
||||
dbg_ui.text(format!("FPS: {}", 1.0 / pctx.time_ctx.frame_dt));
|
||||
dbg_ui.slider_f32("Rotation Speed", -10.0, 10.0, self.rotation_speed.clone());
|
||||
}
|
||||
|
||||
fn fixed_update(&mut self, res: &mut EngineResources, scene: &mut Scene) {
|
||||
let pctx = res.get::<PlatformContext>().unwrap();
|
||||
|
||||
scene.world.query_mut::<(&mut Transform, &ModelHandle)>().into_iter().for_each(|(_, (t, _))| {
|
||||
t.rotation *= Quat::from_rotation_y(*self.rotation_speed.borrow() * pctx.time_ctx.fixed_dt);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut engine = Engine::new();
|
||||
// Define systems
|
||||
engine.system_manager.add::<PhysicsSystem>();
|
||||
engine.system_manager.add::<FPSDebugCameraSystem>();
|
||||
engine.system_manager.add::<RenderingTestSystem>();
|
||||
engine.system_manager.add::<UpdateAspectRatioSystem>();
|
||||
|
|
|
|||
3
game/src/systems/mod.rs
Normal file
3
game/src/systems/mod.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
mod physics;
|
||||
|
||||
pub use physics::PhysicsSystem;
|
||||
34
game/src/systems/physics.rs
Normal file
34
game/src/systems/physics.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
use raidillon_core::scene::Scene;
|
||||
use raidillon_ecs::components::RigidBodyComponent;
|
||||
use raidillon_ecs::Transform;
|
||||
use raidillon_engine::EngineResources;
|
||||
use raidillon_engine::system::System;
|
||||
use raidillon_physics::Physics;
|
||||
use raidillon_platform::PlatformContext;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PhysicsSystem;
|
||||
|
||||
impl System for PhysicsSystem {
|
||||
fn load_world(&mut self, res: &mut EngineResources, scene: &mut Scene) {
|
||||
let p = Physics::default();
|
||||
res.insert(p);
|
||||
}
|
||||
|
||||
fn fixed_update(&mut self, res: &mut EngineResources, scene: &mut Scene) {
|
||||
let pctx = res.get::<PlatformContext>().expect("PlatformContext missing").clone();
|
||||
let physics = res.get_mut::<Physics>().expect("Physics missing");
|
||||
physics.step(pctx.time_ctx.fixed_dt);
|
||||
|
||||
let mut query = scene.world.query::<(&mut Transform, &RigidBodyComponent)>();
|
||||
for (_ent, (tr, rb_component)) in query.iter() {
|
||||
if let Some(body) = physics.get_rigid_body(rb_component.0) {
|
||||
let pos = body.position();
|
||||
let translation = Physics::rapier_translation_to_glam(&pos.translation.vector);
|
||||
let rotation = Physics::rapier_rotation_to_glam(&pos.rotation);
|
||||
tr.translation = translation;
|
||||
tr.rotation = rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue