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:
reo 2025-10-19 17:40:51 +03:00
parent d280a0b9a5
commit 8b5a6167eb
13 changed files with 697 additions and 43 deletions

View file

@ -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>();