lyra-engine/examples/many-lights/src/main.rs

189 lines
7.3 KiB
Rust

use lyra_engine::{assets::{gltf::Gltf, ResourceManager}, ecs::query::{Res, ResMut, View}, game::Game, input::{Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput}, math::{self, Quat, Transform, Vec3}, render::light::{directional::DirectionalLight, PointLight}, scene::{CameraComponent, FreeFlyCamera, FreeFlyCameraPlugin, ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN}, DeltaTime};
use rand::Rng;
use tracing::info;
const MAX_POINT_LIGHT_RANGE: f32 = 1.0;
const MIN_POINT_LIGHT_RANGE: f32 = 0.5;
const POINT_LIGHT_MAX_INTENSITY: f32 = 1.0;
const POINT_LIGHT_MIN_INTENSITY: f32 = 0.3;
const POINT_LIGHT_CUBE_SCALE: f32 = 0.2;
const POINT_LIGHT_NUM: u32 = 500;
const POINT_LIGHT_MAX_X: f32 = 9.0;
const POINT_LIGHT_MIN_X: f32 = -9.0;
const POINT_LIGHT_MAX_Y: f32 = 3.0;
const POINT_LIGHT_MIN_Y: f32 = 0.5;
const POINT_LIGHT_MAX_Z: f32 = 4.0;
const POINT_LIGHT_MIN_Z: f32 = -5.0;
#[async_std::main]
async fn main() {
let action_handler_plugin = |game: &mut Game| {
let action_handler = ActionHandler::builder()
.add_layout(LayoutId::from(0))
.add_action(ACTLBL_MOVE_FORWARD_BACKWARD, Action::new(ActionKind::Axis))
.add_action(ACTLBL_MOVE_LEFT_RIGHT, Action::new(ActionKind::Axis))
.add_action(ACTLBL_MOVE_UP_DOWN, Action::new(ActionKind::Axis))
.add_action(ACTLBL_LOOK_LEFT_RIGHT, Action::new(ActionKind::Axis))
.add_action(ACTLBL_LOOK_UP_DOWN, Action::new(ActionKind::Axis))
.add_action(ACTLBL_LOOK_ROLL, Action::new(ActionKind::Axis))
.add_action("Debug", Action::new(ActionKind::Button))
.add_mapping(ActionMapping::builder(LayoutId::from(0), ActionMappingId::from(0))
.bind(ACTLBL_MOVE_FORWARD_BACKWARD, &[
ActionSource::Keyboard(KeyCode::W).into_binding_modifier(1.0),
ActionSource::Keyboard(KeyCode::S).into_binding_modifier(-1.0)
])
.bind(ACTLBL_MOVE_LEFT_RIGHT, &[
ActionSource::Keyboard(KeyCode::A).into_binding_modifier(-1.0),
ActionSource::Keyboard(KeyCode::D).into_binding_modifier(1.0)
])
.bind(ACTLBL_MOVE_UP_DOWN, &[
ActionSource::Keyboard(KeyCode::C).into_binding_modifier(1.0),
ActionSource::Keyboard(KeyCode::Z).into_binding_modifier(-1.0)
])
.bind(ACTLBL_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),
])
.bind(ACTLBL_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),
])
.bind(ACTLBL_LOOK_ROLL, &[
ActionSource::Keyboard(KeyCode::E).into_binding_modifier(-1.0),
ActionSource::Keyboard(KeyCode::Q).into_binding_modifier(1.0),
])
.bind("Debug", &[
ActionSource::Keyboard(KeyCode::B).into_binding(),
])
.finish()
).finish();
let world = game.world_mut();
world.add_resource(action_handler);
game.with_plugin(InputActionPlugin);
};
Game::initialize().await
.with_plugin(lyra_engine::DefaultPlugins)
.with_plugin(setup_scene_plugin)
.with_plugin(action_handler_plugin)
.with_plugin(camera_debug_plugin)
.with_plugin(FreeFlyCameraPlugin)
.run().await;
}
fn setup_scene_plugin(game: &mut Game) {
let fps_counter = |mut counter: ResMut<fps_counter::FPSCounter>, delta: Res<DeltaTime>| -> anyhow::Result<()> {
let tick = counter.tick();
info!("FPS: {}, frame time: {}", tick, **delta);
Ok(())
};
game.with_system("fps_counter", fps_counter, &[]);
let world = game.world_mut();
world.add_resource(fps_counter::FPSCounter::new());
let resman = world.get_resource_mut::<ResourceManager>();
let cube_gltf = resman.request::<Gltf>("../assets/texture-sep/texture-sep.gltf").unwrap();
cube_gltf.wait_recurse_dependencies_load();
let cube_mesh = &cube_gltf.data_ref()
.unwrap().meshes[0];
let sponza_model = resman.request::<Gltf>("../assets/sponza/Sponza.gltf").unwrap();
drop(resman);
sponza_model.wait_recurse_dependencies_load();
let sponza_scene = &sponza_model.data_ref()
.unwrap().scenes[0];
world.spawn((
sponza_scene.clone(),
Transform::from_xyz(0.0, 0.0, 0.0),
));
{
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 {
enabled: true,
color: Vec3::ONE,
intensity: 0.15
//..Default::default()
},
light_tran,
));
}
let x_range = POINT_LIGHT_MIN_X..POINT_LIGHT_MAX_X;
let y_range = POINT_LIGHT_MIN_Y..POINT_LIGHT_MAX_Y;
let z_range = POINT_LIGHT_MIN_Z..POINT_LIGHT_MAX_Z;
let mut rand = rand::thread_rng();
let mut rand_vec3 = || -> Vec3 {
let x = rand.gen_range(x_range.clone());
let y = rand.gen_range(y_range.clone());
let z = rand.gen_range(z_range.clone());
Vec3::new(x, y, z)
};
let mut rand = rand::thread_rng();
for _ in 0..POINT_LIGHT_NUM {
let range = rand.gen_range(MIN_POINT_LIGHT_RANGE..MAX_POINT_LIGHT_RANGE);
let intensity = rand.gen_range(POINT_LIGHT_MIN_INTENSITY..POINT_LIGHT_MAX_INTENSITY);
let color = rand_vec3().normalize();
world.spawn((
PointLight {
enabled: true,
color,
intensity,
range,
..Default::default()
},
Transform::new(
rand_vec3(),
Quat::IDENTITY,
Vec3::new(POINT_LIGHT_CUBE_SCALE, POINT_LIGHT_CUBE_SCALE, POINT_LIGHT_CUBE_SCALE),
),
cube_mesh.clone(),
));
}
let mut camera = CameraComponent::new_3d();
// these values were taken by manually positioning the camera in the scene.
camera.transform = Transform::new(
Vec3::new(-10.0, 0.94, -0.28),
Quat::from_xyzw(0.03375484, -0.7116095, 0.0342693, 0.70092666),
Vec3::ONE
);
world.spawn(( camera, FreeFlyCamera::default() ));
}
fn camera_debug_plugin(game: &mut Game) {
let sys = |handler: Res<ActionHandler>, view: View<&mut CameraComponent>| -> anyhow::Result<()> {
if handler.was_action_just_pressed("Debug") {
for mut cam in view.into_iter() {
cam.debug = !cam.debug;
}
}
Ok(())
};
game.with_system("camera_debug_trigger", sys, &[]);
}