raidillon/game/src/main.rs
2025-12-15 23:08:32 +03:00

140 lines
4.9 KiB
Rust

use raidillon_app::prelude::*;
mod systems;
use glam::{Quat, Vec3};
use rapier3d::dynamics::{CoefficientCombineRule, RigidBodyType};
use rapier3d::prelude::ColliderBuilder;
use winit::event::{Event, WindowEvent};
use systems::debug_camera::FPSDebugCameraSystem;
use crate::systems::common::should_draw_menu;
use crate::systems::{
DisplaySettings, KeybindsSystem, KinematicCharacterController, MenuSystem, PhysicsSystem,
PhysicsDebugSystem,
};
const TEST_GLTF: &str = "checkered-sphere.glb";
const PLANE_GLTF: &str = "plane.glb";
const MAIN_SCENE_ID: &str = "main_scene";
#[derive(Default)]
struct UpdateAspectRatioSystem;
impl System for UpdateAspectRatioSystem {
fn handle_event(&mut self, res: &mut EngineResources, scene: &mut Scene) {
let pctx = res.get::<PlatformContext>().unwrap();
if let Event::WindowEvent { event: WindowEvent::Resized(sz), .. } =
pctx.current_event
{
scene.world
.query_mut::<&mut Camera>()
.into_iter()
.for_each(|(_, cam)| {
cam.aspect = sz.width as f32 / sz.height as f32;
});
}
}
}
#[derive(Default)]
struct MainSystem;
impl System for MainSystem {
fn load_world(&mut self, res: &mut EngineResources, scene: &mut Scene) {
let pctx = res.get::<PlatformContext>().expect("PlatformContext missing").clone();
let physics = scene.resources.get_mut::<Physics>().expect("Physics missing");
// 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)
.restitution(0.7)
.restitution_combine_rule(CoefficientCombineRule::Max)
.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),
));
}
scene.world.spawn((Camera {
eye: Vec3::new(0.0, 2.0, 3.0),
center: Vec3::ZERO,
up: Vec3::Y,
fovy: 60_f32.to_radians(),
aspect: pctx.frame_width / pctx.frame_height,
znear: 0.1,
zfar: 100.0},
CameraMode::default(),
));
}
fn frame_update(&mut self, res: &mut EngineResources, scene: &mut Scene) {
let (
pctx,
input,
) = res.get_many_mut::<(
PlatformContext,
InputState,
)>().unwrap();
let mut egui_queue = pctx.egui_queue.borrow_mut();
let time_ctx = pctx.time_ctx.clone();
let mut character_pos = Vec3::ZERO;
for (_ent, (tr, ch_component)) in scene.world.query::<(&Transform, &CharacterBodyComponent)>().iter() {
character_pos = tr.translation;
}
egui_queue.queue(move |egui_ctx| {
// disable text selection on all labels.
egui_ctx.style_mut(|style| {
style.interaction.selectable_labels = false;
});
egui::Window::new("Debug").show(egui_ctx, |ui| {
ui.label("Hello World!");
ui.label(format!("Frame Delta: {:.3}", time_ctx.frame_dt));
ui.label(format!("Fixed Delta: {:.3}", time_ctx.fixed_dt));
ui.label(format!("FPS: {:.3}", 1.0 / time_ctx.frame_dt));
ui.label(format!("Character POS: {character_pos:.3}"));
});
});
}
}
fn main() {
raidillon_app::App::new()
.add_system::<PhysicsSystem>()
.add_system::<PhysicsDebugSystem>()
.add_system::<KeybindsSystem>()
.add_system::<KinematicCharacterController>()
.add_system::<FPSDebugCameraSystem>()
.add_system::<MenuSystem>()
.add_system::<DisplaySettings>()
.add_system::<MainSystem>()
.add_system::<UpdateAspectRatioSystem>()
.add_scene(MAIN_SCENE_ID, Scene::new(MAIN_SCENE_ID.to_owned(), None))
.set_active_scene(MAIN_SCENE_ID)
.run("Raidillon".to_string(), 2560, 1080);
}