lyra-engine/examples/testbed/src/main.rs

288 lines
10 KiB
Rust

use std::ptr::NonNull;
use lyra_engine::{math::{self, Vec3}, math::Transform, input::{KeyCode, ActionHandler, Action, ActionKind, LayoutId, ActionMapping, ActionSource, ActionMappingId, InputActionPlugin, MouseInput, MouseAxis}, game::Game, render::{window::{CursorGrabMode, WindowOptions}, light::{PointLight, directional::DirectionalLight, SpotLight}}, change_tracker::Ct, ecs::{system::{Criteria, CriteriaSchedule, BatchedSystem, IntoSystem}, world::World, Component}, DeltaTime, scene::{TransformComponent, ModelComponent, CameraComponent}};
use lyra_engine::assets::{ResourceManager, Model};
mod free_fly_camera;
use free_fly_camera::{FreeFlyCameraPlugin, FreeFlyCamera};
struct FixedTimestep {
max_tps: u32,
fixed_time: f32,
accumulator: f32,
}
#[allow(dead_code)]
impl FixedTimestep {
pub fn new(max_tps: u32) -> Self {
Self {
max_tps,
fixed_time: Self::calc_fixed_time(max_tps),
accumulator: 0.0,
}
}
fn calc_fixed_time(max_tps: u32) -> f32 {
1.0 / max_tps as f32
}
fn set_tps(&mut self, tps: u32) {
self.max_tps = tps;
self.fixed_time = Self::calc_fixed_time(tps);
}
fn tps(&self) -> u32 {
self.max_tps
}
fn fixed_time(&self) -> f32 {
self.fixed_time
}
}
impl Criteria for FixedTimestep {
fn can_run(&mut self, mut world: NonNull<World>, check_count: u32) -> CriteriaSchedule {
let world = unsafe { world.as_mut() };
if check_count == 0 {
let delta_time = world.get_resource::<DeltaTime>();
self.accumulator += **delta_time;
}
if self.accumulator >= self.fixed_time {
self.accumulator -= self.fixed_time;
return CriteriaSchedule::YesAndLoop;
}
CriteriaSchedule::No
}
}
#[derive(Clone)]
struct TpsAccumulator(f32);
#[derive(Component)]
struct CubeFlag;
#[async_std::main]
async fn main() {
let setup_sys = |world: &mut World| -> anyhow::Result<()> {
{
let mut window_options = world.get_resource_mut::<Ct<WindowOptions>>();
window_options.cursor_grab = CursorGrabMode::Confined;
window_options.cursor_visible = false;
}
let mut resman = world.get_resource_mut::<ResourceManager>();
//let diffuse_texture = resman.request::<Texture>("assets/happy-tree.png").unwrap();
let antique_camera_model = resman.request::<Model>("assets/AntiqueCamera.glb").unwrap();
//let cube_model = resman.request::<Model>("assets/cube-texture-bin.glb").unwrap();
let cube_model = resman.request::<Model>("assets/texture-sep/texture-sep.gltf").unwrap();
let crate_model = resman.request::<Model>("assets/crate/crate.gltf").unwrap();
drop(resman);
world.spawn((
ModelComponent(antique_camera_model),
TransformComponent::from(Transform::from_xyz(0.0, -5.0, -10.0)),
));
{
let cube_tran = Transform::from_xyz(-3.5, 0.0, -8.0);
//cube_tran.rotate_y(math::Angle::Degrees(180.0));
world.spawn((
TransformComponent::from(cube_tran),
ModelComponent(crate_model.clone()),
CubeFlag,
));
}
{
let mut light_tran = Transform::from_xyz(1.5, 2.5, 0.0);
light_tran.scale = Vec3::new(0.5, 0.5, 0.5);
light_tran.rotate_x(math::Angle::Degrees(-45.0));
light_tran.rotate_y(math::Angle::Degrees(25.0));
world.spawn((
DirectionalLight {
color: Vec3::new(1.0, 1.0, 1.0),
ambient: 0.3,
diffuse: 1.0,
specular: 1.3,
},
TransformComponent::from(light_tran),
ModelComponent(cube_model.clone()),
));
}
{
let mut light_tran = Transform::from_xyz(-3.5, 0.2, -4.5);
light_tran.scale = Vec3::new(0.5, 0.5, 0.5);
world.spawn((
SpotLight {
color: Vec3::new(1.0, 0.2, 0.2),
cutoff: math::Angle::Degrees(12.5),
outer_cutoff: math::Angle::Degrees(17.5),
constant: 1.0,
linear: 0.007,
quadratic: 0.0002,
ambient: 0.0,
diffuse: 7.0,
specular: 1.0,
},
TransformComponent::from(light_tran),
ModelComponent(cube_model.clone()),
));
}
/* {
let mut light_tran = Transform::from_xyz(-5.0, 2.5, -9.5);
light_tran.scale = Vec3::new(0.5, 0.5, 0.5);
world.spawn((
PointLight {
color: Vec3::new(1.0, 1.0, 1.0),
intensity: 1.0,
constant: 1.0,
linear: 0.045,
quadratic: 0.0075,
ambient: 0.1,
diffuse: 1.0,
specular: 1.3,
},
TransformComponent::from(light_tran),
ModelComponent(cube_model.clone()),
));
} */
{
let mut light_tran = Transform::from_xyz(2.0, 2.5, -9.5);
light_tran.scale = Vec3::new(0.5, 0.5, 0.5);
world.spawn((
PointLight {
color: Vec3::new(0.0, 0.0, 1.0),
intensity: 3.3,
constant: 1.0,
linear: 0.09,
quadratic: 0.032,
ambient: 0.2,
diffuse: 1.0,
specular: 1.3,
},
TransformComponent::from(light_tran),
ModelComponent(cube_model),
));
}
let mut camera = CameraComponent::new_3d();
camera.transform.translation += math::Vec3::new(0.0, 0.0, 5.5);
world.spawn(( camera, FreeFlyCamera::default() ));
Ok(())
};
#[allow(unused_variables)]
let fps_system = |world: &mut World| -> anyhow::Result<()> {
let mut counter = world.get_resource_mut::<fps_counter::FPSCounter>();
let fps = counter.tick();
println!("FPS: {fps}");
Ok(())
};
let fps_plugin = move |game: &mut Game| {
let world = game.world();
world.add_resource(fps_counter::FPSCounter::new());
};
let spin_system = |world: &mut World| -> anyhow::Result<()> {
const SPEED: f32 = 4.0;
let delta_time = **world.get_resource::<DeltaTime>();
for (mut transform, _) in world.view_iter::<(&mut TransformComponent, &CubeFlag)>() {
let t = &mut transform.transform;
t.rotate_y(math::Angle::Degrees(SPEED * delta_time));
}
for (mut transform, _s) in world.view_iter::<(&mut TransformComponent, &mut SpotLight)>() {
let t = &mut transform.transform;
t.rotate_x(math::Angle::Degrees(SPEED * delta_time));
}
Ok(())
};
let jiggle_plugin = move |game: &mut Game| {
game.world().add_resource(TpsAccumulator(0.0));
let mut sys = BatchedSystem::new();
sys.with_criteria(FixedTimestep::new(45));
sys.with_system(spin_system.into_system());
//sys.with_system(fps_system);
game.with_system("fixed", sys, &[]);
fps_plugin(game);
};
let action_handler_plugin = |game: &mut Game| {
let action_handler = ActionHandler::new()
.add_layout(LayoutId::from(0))
.add_action("forward_backward", Action::new(ActionKind::Axis))
.add_action("left_right", Action::new(ActionKind::Axis))
.add_action("up_down", Action::new(ActionKind::Axis))
.add_action("look_left_right", Action::new(ActionKind::Axis))
.add_action("look_up_down", Action::new(ActionKind::Axis))
.add_action("look_rotate", Action::new(ActionKind::Axis))
.add_mapping(ActionMapping::new(LayoutId::from(0), ActionMappingId::from(0))
.bind("forward_backward", &[
ActionSource::Keyboard(KeyCode::W).into_binding_modifier(1.0),
ActionSource::Keyboard(KeyCode::S).into_binding_modifier(-1.0)
])
.bind("left_right", &[
ActionSource::Keyboard(KeyCode::A).into_binding_modifier(-1.0),
ActionSource::Keyboard(KeyCode::D).into_binding_modifier(1.0)
])
.bind("up_down", &[
ActionSource::Keyboard(KeyCode::C).into_binding_modifier(1.0),
ActionSource::Keyboard(KeyCode::Z).into_binding_modifier(-1.0)
])
.bind("look_left_right", &[
ActionSource::Mouse(MouseInput::Axis(MouseAxis::X)).into_binding(),
ActionSource::Keyboard(KeyCode::Left).into_binding_modifier(-1.0),
ActionSource::Keyboard(KeyCode::Right).into_binding_modifier(1.0),
//ActionSource::Gamepad(GamepadFormat::DualAxis, GamepadInput::Axis(GamepadAxis::RThumbstickX)).into_binding(),
])
.bind("look_up_down", &[
ActionSource::Mouse(MouseInput::Axis(MouseAxis::Y)).into_binding(),
ActionSource::Keyboard(KeyCode::Up).into_binding_modifier(-1.0),
ActionSource::Keyboard(KeyCode::Down).into_binding_modifier(1.0),
//ActionSource::Gamepad(GamepadFormat::DualAxis, GamepadInput::Axis(GamepadAxis::RThumbstickY)).into_binding(),
])
.bind("look_rotate", &[
ActionSource::Keyboard(KeyCode::E).into_binding_modifier(-1.0),
ActionSource::Keyboard(KeyCode::Q).into_binding_modifier(1.0),
])
.finish()
);
game.world().add_resource(action_handler);
game.with_plugin(InputActionPlugin);
};
Game::initialize().await
.with_plugin(lyra_engine::DefaultPlugins)
.with_startup_system(setup_sys.into_system())
.with_plugin(action_handler_plugin)
//.with_plugin(fps_plugin)
.with_plugin(jiggle_plugin)
.with_plugin(FreeFlyCameraPlugin)
.run().await;
}