diff --git a/crates/lyra-game/src/render/camera.rs b/crates/lyra-game/src/render/camera.rs index ad76a81..6e5ff98 100755 --- a/crates/lyra-game/src/render/camera.rs +++ b/crates/lyra-game/src/render/camera.rs @@ -1,87 +1,7 @@ -use glam::{Mat4, Vec2}; +use glam::Vec2; use lyra_math::Transform; -use lyra_reflect::Reflect; -use crate::math::Angle; - -#[derive(Debug, Clone, Copy, PartialEq, Reflect)] -pub struct OrthographicProjection { - pub scale: f32, - pub znear: f32, - pub zfar: f32, -} - -impl Default for OrthographicProjection { - fn default() -> Self { - Self { - scale: 1.0, - znear: 0.0, - zfar: 1000.0, - } - } -} - -impl OrthographicProjection { - pub fn to_mat(&self, viewport_size: Vec2) -> Mat4 { - let origin_x = viewport_size.x as f32 * 0.5; - let origin_y = viewport_size.y as f32 * 0.5; - - glam::Mat4::orthographic_rh( - self.scale * -origin_x, - self.scale * viewport_size.x as f32 - origin_x, - self.scale * -origin_y, - self.scale * viewport_size.y as f32 - origin_y, - -1000.0, - 1000.0, - ) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Reflect)] -pub struct PerspectiveProjection { - pub fov: Angle, - pub znear: f32, - pub zfar: f32, -} - -impl Default for PerspectiveProjection { - fn default() -> Self { - Self { - fov: Angle::Degrees(45.0), - znear: 0.0, - zfar: 100.0, - } - } -} - -impl PerspectiveProjection { - pub fn to_mat(&self, viewport_size: Vec2) -> Mat4 { - let aspect = viewport_size.x / viewport_size.y; - glam::Mat4::perspective_rh( - self.fov.to_radians(), - aspect, - self.znear, - self.zfar, - ) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Reflect)] -pub enum CameraProjectionMode { - /// 3d camera projection - Perspective(PerspectiveProjection), - /// 2d camera projection - Orthographic(OrthographicProjection), -} - -impl CameraProjectionMode { - pub fn to_mat4(&self, viewport_size: Vec2) -> Mat4 { - match self { - CameraProjectionMode::Perspective(proj) => proj.to_mat(viewport_size), - CameraProjectionMode::Orthographic(proj) => proj.to_mat(viewport_size), - } - } -} +use crate::scene::CameraProjection; #[repr(C)] #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] @@ -96,7 +16,6 @@ pub struct CameraUniform { /// The position of the camera pub position: glam::Vec3, _padding: u32, - //_padding: [u8; 3], } impl Default for CameraUniform { @@ -130,7 +49,7 @@ impl CameraUniform { } } - pub fn from_component(transform: Transform, projection: CameraProjectionMode, viewport_size: Vec2) -> Self { + pub fn from_component(transform: Transform, projection: CameraProjection, viewport_size: Vec2) -> Self { let position = transform.translation; let forward = transform.forward(); let up = transform.up(); diff --git a/crates/lyra-game/src/render/graph/passes/base.rs b/crates/lyra-game/src/render/graph/passes/base.rs index c6599a8..a74d672 100644 --- a/crates/lyra-game/src/render/graph/passes/base.rs +++ b/crates/lyra-game/src/render/graph/passes/base.rs @@ -12,8 +12,7 @@ use crate::{ Node, NodeDesc, NodeType, RenderGraph, RenderGraphContext, SlotAttribute, SlotValue }, render_buffer::BufferWrapper, texture::RenderTexture, - }, - scene::CameraComponent, + }, scene::{Camera, CameraProjection}, }; #[derive(Debug, Hash, Clone, Default, PartialEq, RenderGraphLabel)] @@ -114,11 +113,20 @@ impl Node for BasePass { } fn prepare(&mut self, graph: &mut RenderGraph, world: &mut lyra_ecs::World, context: &mut RenderGraphContext) { - if let Some((camera, transform)) = world.view_iter::<(&CameraComponent, &Transform)>().next() { - let screen_size = graph.view_target().size(); - let uniform = CameraUniform::from_component(*transform, camera.projection, screen_size.as_vec2()); - context.queue_buffer_write_with(BasePassSlots::Camera, 0, uniform) - } else { + let mut found_camera = false; + + for (camera, projection, transform) in world.view_iter::<(&Camera, &CameraProjection, &Transform)>() { + if camera.is_active { + let screen_size = graph.view_target().size(); + let uniform = CameraUniform::from_component(*transform, *projection, screen_size.as_vec2()); + context.queue_buffer_write_with(BasePassSlots::Camera, 0, uniform); + + found_camera = true; + break; + } + } + + if !found_camera { warn!("Missing camera!"); } } diff --git a/crates/lyra-game/src/scene/camera.rs b/crates/lyra-game/src/scene/camera.rs index cb869d7..cbcb9d2 100755 --- a/crates/lyra-game/src/scene/camera.rs +++ b/crates/lyra-game/src/scene/camera.rs @@ -1,31 +1,127 @@ -use lyra_ecs::Component; +use glam::{Mat4, Vec2}; +use lyra_ecs::{Bundle, Component}; +use lyra_math::Angle; use lyra_reflect::Reflect; -use crate::render::camera::{CameraProjectionMode, OrthographicProjection, PerspectiveProjection}; - -#[derive(Clone, Component, Reflect)] -pub struct CameraComponent { - pub projection: CameraProjectionMode, - //pub debug: bool, +#[derive(Debug, Clone, Copy, PartialEq, Reflect)] +pub struct OrthographicProjection { + pub scale: f32, + pub znear: f32, + pub zfar: f32, } -impl Default for CameraComponent { +impl Default for OrthographicProjection { fn default() -> Self { Self { - projection: CameraProjectionMode::Perspective(PerspectiveProjection::default()), + scale: 1.0, + znear: 0.0, + zfar: 1000.0, } } } -impl CameraComponent { - pub fn new_3d() -> Self { - Self::default() - } +impl OrthographicProjection { + pub fn to_mat(&self, viewport_size: Vec2) -> Mat4 { + let origin_x = viewport_size.x as f32 * 0.5; + let origin_y = viewport_size.y as f32 * 0.5; - pub fn new_2d() -> Self { - CameraComponent { - projection: CameraProjectionMode::Orthographic(OrthographicProjection::default()), - ..Default::default() + glam::Mat4::orthographic_rh( + self.scale * -origin_x, + self.scale * viewport_size.x as f32 - origin_x, + self.scale * -origin_y, + self.scale * viewport_size.y as f32 - origin_y, + -1000.0, + 1000.0, + ) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Reflect)] +pub struct PerspectiveProjection { + pub fov: Angle, + pub znear: f32, + pub zfar: f32, +} + +impl Default for PerspectiveProjection { + fn default() -> Self { + Self { + fov: Angle::Degrees(45.0), + znear: 0.1, + zfar: 100.0, } } -} \ No newline at end of file +} + +impl PerspectiveProjection { + pub fn to_mat(&self, viewport_size: Vec2) -> Mat4 { + let aspect = viewport_size.x / viewport_size.y; + glam::Mat4::perspective_rh(self.fov.to_radians(), aspect, self.znear, self.zfar) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Reflect, Component)] +pub enum CameraProjection { + /// 3d camera projection + Perspective(PerspectiveProjection), + /// 2d camera projection + Orthographic(OrthographicProjection), +} + +impl Default for CameraProjection { + fn default() -> Self { + Self::Perspective(PerspectiveProjection::default()) + } +} + +impl CameraProjection { + pub fn to_mat4(&self, viewport_size: Vec2) -> Mat4 { + match self { + CameraProjection::Perspective(proj) => proj.to_mat(viewport_size), + CameraProjection::Orthographic(proj) => proj.to_mat(viewport_size), + } + } +} + +#[derive(Clone, Default, Component, Reflect)] +pub struct Camera2d; + +#[derive(Clone, Component, Reflect)] +pub struct Camera { + pub is_active: bool, +} + +impl Default for Camera { + fn default() -> Self { + Self { is_active: true } + } +} + +/// A component bundle for a Camera entity. +#[derive(Clone, Default, Bundle)] +pub struct CameraBundle { + pub camera: Camera, + pub projection: CameraProjection, +} + +/// A component bundle for a 2d Camera entity. +#[derive(Clone, Bundle)] +pub struct Camera2dBundle { + pub camera: Camera, + pub projection: CameraProjection, + pub camera_2d: Camera2d, +} + +impl Default for Camera2dBundle { + fn default() -> Self { + Self { + camera: Default::default(), + projection: CameraProjection::Orthographic(OrthographicProjection { + znear: -1000.0, + zfar: 1000.0, + ..Default::default() + }), + camera_2d: Default::default(), + } + } +} diff --git a/crates/lyra-scripting/src/lua/providers/ecs.rs b/crates/lyra-scripting/src/lua/providers/ecs.rs index 9c47e22..df41edd 100644 --- a/crates/lyra-scripting/src/lua/providers/ecs.rs +++ b/crates/lyra-scripting/src/lua/providers/ecs.rs @@ -17,7 +17,8 @@ impl ScriptApiProvider for LyraEcsApiProvider { world.register_lua_wrapper::(); world.register_lua_wrapper::(); - world.register_lua_convert_component::("Camera"); + // TODO: expose camera + // world.register_lua_convert_component::("Camera"); world.register_lua_convert_component::("FreeFlyCamera"); world.register_lua_convert_component::("WorldTransform"); @@ -54,7 +55,6 @@ impl ScriptApiProvider for LyraEcsApiProvider { globals.set("TickOfQuery", ctx.create_proxy::()?)?; globals.set("OptionalQuery", ctx.create_proxy::()?)?; - expose_comp_table_wrapper::(&ctx, &globals, "Camera")?; expose_comp_table_wrapper::(&ctx, &globals, "FreeFlyCamera")?; expose_comp_table_wrapper::(&ctx, &globals, "WorldTransform")?; expose_table_wrapper::(&ctx, &globals, "DeviceEvent")?; diff --git a/crates/lyra-scripting/src/lua/wrappers/mod.rs b/crates/lyra-scripting/src/lua/wrappers/mod.rs index bc7f297..56fb655 100644 --- a/crates/lyra-scripting/src/lua/wrappers/mod.rs +++ b/crates/lyra-scripting/src/lua/wrappers/mod.rs @@ -13,9 +13,6 @@ pub use delta_time::*; mod window; pub use window::*; -mod camera; -pub use camera::*; - mod free_fly_camera; pub use free_fly_camera::*; diff --git a/examples/2d/src/main.rs b/examples/2d/src/main.rs index 5bd8768..4132462 100644 --- a/examples/2d/src/main.rs +++ b/examples/2d/src/main.rs @@ -1,6 +1,5 @@ use lyra_engine::{ - assets::{Image, ResourceManager, Texture}, - ecs::query::View, + assets::{Image, ResourceManager}, game::App, gltf::Gltf, input::{ @@ -8,17 +7,11 @@ use lyra_engine::{ InputActionPlugin, KeyCode, LayoutId, }, math::{self, Transform, Vec3}, - render::{ - camera::{CameraProjectionMode, OrthographicProjection}, - light::directional::DirectionalLight, - }, + render::light::directional::DirectionalLight, scene::{ - system_update_world_transforms, CameraComponent, FreeFlyCamera, FreeFlyCameraPlugin, - WorldTransform, ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, - ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN, + system_update_world_transforms, Camera2dBundle, CameraProjection, FreeFlyCamera, FreeFlyCameraPlugin, OrthographicProjection, WorldTransform, ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN }, sprite::{self, Sprite}, - winit::WindowOptions, }; #[async_std::main] @@ -167,11 +160,12 @@ fn setup_scene_plugin(app: &mut App) { } world.spawn(( - CameraComponent { - projection: CameraProjectionMode::Orthographic(OrthographicProjection { + Camera2dBundle { + projection: CameraProjection::Orthographic(OrthographicProjection { scale: 0.75, ..Default::default() }), + ..Default::default() }, Transform::from_xyz(200.0, 120.0, 0.0), FreeFlyCamera::default(), diff --git a/examples/fixed-timestep-rotating-model/src/main.rs b/examples/fixed-timestep-rotating-model/src/main.rs index c4451d5..979b3b4 100644 --- a/examples/fixed-timestep-rotating-model/src/main.rs +++ b/examples/fixed-timestep-rotating-model/src/main.rs @@ -1,25 +1,16 @@ use std::ptr::NonNull; use lyra_engine::{ - assets::ResourceManager, gltf::Gltf, - ecs::{ + assets::ResourceManager, ecs::{ query::{Res, View}, system::{BatchedSystem, Criteria, CriteriaSchedule, IntoSystem}, World, - }, - game::App, - input::{ + }, game::App, gltf::Gltf, input::{ Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput, - }, - math::{self, Transform, Vec3}, - render::light::directional::DirectionalLight, - scene::{ - CameraComponent, FreeFlyCamera, FreeFlyCameraPlugin, WorldTransform, - ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, - ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN, - }, - DeltaTime, + }, math::{self, Transform, Vec3}, render::light::directional::DirectionalLight, scene::{ + CameraBundle, FreeFlyCamera, FreeFlyCameraPlugin, WorldTransform, 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 tracing::info; @@ -135,9 +126,11 @@ fn setup_scene_plugin(app: &mut App) { )); } - let mut camera = CameraComponent::new_3d(); - camera.transform.translation += math::Vec3::new(0.0, 0.0, 1.5); - world.spawn((camera, FreeFlyCamera::default())); + world.spawn(( + CameraBundle::default(), + Transform::from_xyz(0.0, 0.0, 1.5), + FreeFlyCamera::default(), + )); let fps_counter = |counter: Res, delta: Res| -> anyhow::Result<()> { diff --git a/examples/lua-scripting/src/main.rs b/examples/lua-scripting/src/main.rs index bd7bdb2..3b80cc1 100644 --- a/examples/lua-scripting/src/main.rs +++ b/examples/lua-scripting/src/main.rs @@ -1,9 +1,9 @@ use lyra_engine::{ - assets::ResourceManager, gltf::Gltf, game::App, input::{ + assets::ResourceManager, game::App, gltf::Gltf, input::{ Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput, }, math::{self, Transform, Vec3}, render::light::directional::DirectionalLight, scene::{ - self, CameraComponent, FreeFlyCamera, FreeFlyCameraPlugin, WorldTransform, ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN + self, CameraBundle, FreeFlyCamera, FreeFlyCameraPlugin, WorldTransform, ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN }, script::{lua::{LuaScript, LuaScriptingPlugin}, Script, ScriptList} }; @@ -125,9 +125,11 @@ fn setup_scene_plugin(app: &mut App) { )); } - let mut camera = CameraComponent::new_3d(); - camera.transform.translation += math::Vec3::new(0.0, 0.0, 5.5); - world.spawn((camera, FreeFlyCamera::default())); + world.spawn(( + CameraBundle::default(), + Transform::from_xyz(0.0, 0.0, 5.5), + FreeFlyCamera::default(), + )); } fn setup_script_plugin(app: &mut App) { diff --git a/examples/many-lights/src/main.rs b/examples/many-lights/src/main.rs index 77f9a37..641c3db 100644 --- a/examples/many-lights/src/main.rs +++ b/examples/many-lights/src/main.rs @@ -1,4 +1,4 @@ -use lyra_engine::{assets::ResourceManager, gltf::Gltf, ecs::query::{Res, View}, game::App, 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 lyra_engine::{assets::ResourceManager, ecs::query::Res, game::App, gltf::Gltf, input::{Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput}, math::{self, Quat, Transform, Vec3}, render::light::{directional::DirectionalLight, PointLight}, scene::{CameraBundle, 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; @@ -95,7 +95,6 @@ async fn main() { app.with_plugin(lyra_engine::DefaultPlugins); app.with_plugin(setup_scene_plugin); app.with_plugin(action_handler_plugin); - app.with_plugin(camera_debug_plugin); app.with_plugin(FreeFlyCameraPlugin); app.run(); } @@ -184,26 +183,15 @@ fn setup_scene_plugin(app: &mut App) { )); } - 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() )); + world.spawn(( + CameraBundle::default(), + // these values were taken by manually positioning the camera in the scene + // and printing the position to console. + Transform::new( + Vec3::new(-10.0, 0.94, -0.28), + Quat::from_xyzw(0.03375484, -0.7116095, 0.0342693, 0.70092666), + Vec3::ONE, + ), + FreeFlyCamera::default(), + )); } - -fn camera_debug_plugin(app: &mut App) { - let sys = |handler: Res, view: View<&mut CameraComponent>| -> anyhow::Result<()> { - if let Some(true) = handler.was_action_just_pressed("Debug") { - for mut cam in view.into_iter() { - cam.debug = !cam.debug; - } - } - - Ok(()) - }; - - app.with_system("camera_debug_trigger", sys, &[]); -} \ No newline at end of file diff --git a/examples/shadows/src/main.rs b/examples/shadows/src/main.rs index acb055d..34a896b 100644 --- a/examples/shadows/src/main.rs +++ b/examples/shadows/src/main.rs @@ -1,6 +1,7 @@ use lyra_engine::{ - assets::ResourceManager, gltf::Gltf, + assets::ResourceManager, game::App, + gltf::Gltf, input::{ Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput, @@ -11,9 +12,9 @@ use lyra_engine::{ light::{directional::DirectionalLight, SpotLight}, }, scene::{ - CameraComponent, FreeFlyCamera, FreeFlyCameraPlugin, WorldTransform, - ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, - ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN, + CameraBundle, FreeFlyCamera, FreeFlyCameraPlugin, WorldTransform, ACTLBL_LOOK_LEFT_RIGHT, + ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_MOVE_FORWARD_BACKWARD, + ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN, }, }; @@ -115,13 +116,6 @@ fn setup_scene_plugin(app: &mut App) { Transform::from_xyz(0.0, -5.0, -2.0), )); */ - let cube_gltf = resman - .request::("../assets/cube-texture-embedded.gltf") - .unwrap(); - - cube_gltf.wait_recurse_dependencies_load(); - let cube_mesh = &cube_gltf.data_ref().unwrap().scenes[0]; - let palm_tree_platform_gltf = resman .request::("../assets/shadows-platform-palmtree.glb") .unwrap(); @@ -213,9 +207,13 @@ fn setup_scene_plugin(app: &mut App) { let t = Transform::new( Vec3::new(4.0 - 1.43, -13.0, 0.0), //Vec3::new(-5.0, 1.0, -0.28), - //Vec3::new(-10.0, 0.94, -0.28), - - Quat::from_euler(math::EulerRot::XYZ, 0.0, math::Angle::Degrees(-45.0).to_radians(), 0.0), + //Vec3::new(-10.0, 0.94, -0.28), + Quat::from_euler( + math::EulerRot::XYZ, + 0.0, + math::Angle::Degrees(-45.0).to_radians(), + 0.0, + ), Vec3::new(0.15, 0.15, 0.15), ); @@ -238,10 +236,8 @@ fn setup_scene_plugin(app: &mut App) { )); } - let mut camera = CameraComponent::new_3d(); - camera.transform.translation = math::Vec3::new(-1.0, -10.0, -1.5); - camera.transform.rotate_x(math::Angle::Degrees(-27.0)); - camera.transform.rotate_y(math::Angle::Degrees(-90.0)); - - world.spawn((camera, FreeFlyCamera::default())); + let mut pos = Transform::from_xyz(-1.0, -10.0, -1.5); + pos.rotate_x(math::Angle::Degrees(-27.0)); + pos.rotate_y(math::Angle::Degrees(-90.0)); + world.spawn((CameraBundle::default(), pos, FreeFlyCamera::default())); } diff --git a/examples/simple_scene/src/main.rs b/examples/simple_scene/src/main.rs index a501144..20a03cb 100644 --- a/examples/simple_scene/src/main.rs +++ b/examples/simple_scene/src/main.rs @@ -1,10 +1,18 @@ use lyra_engine::{ - assets::ResourceManager, gltf::Gltf, ecs::query::View, game::App, input::{ + assets::ResourceManager, + game::App, + gltf::Gltf, + input::{ Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, InputActionPlugin, KeyCode, LayoutId, - }, math::{self, Transform, Vec3}, render::light::directional::DirectionalLight, scene::{ - system_update_world_transforms, CameraComponent, FreeFlyCamera, FreeFlyCameraPlugin, WorldTransform, ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN - }, winit::WindowOptions + }, + math::{self, Transform, Vec3}, + render::light::directional::DirectionalLight, + scene::{ + system_update_world_transforms, CameraBundle, FreeFlyCamera, FreeFlyCameraPlugin, + WorldTransform, ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, + ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN, + }, }; #[async_std::main] @@ -84,7 +92,11 @@ async fn main() { .with_plugin(action_handler_plugin) //.with_plugin(camera_debug_plugin) .with_plugin(FreeFlyCameraPlugin) - .with_system("system_update_world_transforms", system_update_world_transforms, &[]); + .with_system( + "system_update_world_transforms", + system_update_world_transforms, + &[], + ); a.run(); } @@ -135,7 +147,9 @@ fn setup_scene_plugin(app: &mut App) { )); } - let mut camera = CameraComponent::new_3d(); - camera.transform.translation += math::Vec3::new(0.0, 0.0, 5.5); - world.spawn((camera, FreeFlyCamera::default())); + world.spawn(( + CameraBundle::default(), + Transform::from_xyz(0.0, 0.0, 5.5), + FreeFlyCamera::default(), + )); } diff --git a/examples/testbed/src/main.rs b/examples/testbed/src/main.rs index 21d7205..6635ec0 100644 --- a/examples/testbed/src/main.rs +++ b/examples/testbed/src/main.rs @@ -1,14 +1,14 @@ use std::ptr::NonNull; use lyra_engine::assets::ResourceManager; +use lyra_engine::scene::CameraBundle; use lyra_engine::{ - gltf::Gltf, ecs::{ - query::{Res, View}, - system::{Criteria, CriteriaSchedule, IntoSystem}, + system::{Criteria, CriteriaSchedule}, Component, World, }, game::App, + gltf::Gltf, input::{ Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput, @@ -16,9 +16,9 @@ use lyra_engine::{ math::{self, Quat, Transform, Vec3}, render::light::{directional::DirectionalLight, PointLight, SpotLight}, scene::{ - self, CameraComponent, FreeFlyCamera, FreeFlyCameraPlugin, WorldTransform, - ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, - ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN, + self, FreeFlyCamera, FreeFlyCameraPlugin, WorldTransform, ACTLBL_LOOK_LEFT_RIGHT, + ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_MOVE_FORWARD_BACKWARD, + ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN, }, DeltaTime, }; @@ -101,205 +101,6 @@ struct CubeFlag; #[async_std::main] async fn main() { - let setup_sys = |world: &mut World| -> anyhow::Result<()> { - { - /* let mut window_options = world.get_resource_mut::>(); - window_options.cursor_grab = CursorGrabMode::Confined; - window_options.cursor_visible = false; */ - } - - let resman = world.get_resource_mut::().unwrap(); - //let diffuse_texture = resman.request::("assets/happy-tree.png").unwrap(); - //let antique_camera_model = resman.request::("assets/AntiqueCamera.glb").unwrap(); - //let cube_model = resman.request::("assets/cube-texture-bin.glb").unwrap(); - let cube_gltf = resman - .request::("../assets/texture-sep/texture-sep.gltf") - .unwrap(); - /*let crate_gltf = resman.request::("assets/crate/crate.gltf").unwrap(); - - let separate_gltf = resman.request::("assets/pos-testing/child-node-cubes.glb").unwrap(); */ - //drop(resman); - - cube_gltf.wait_recurse_dependencies_load(); - let cube_mesh = &cube_gltf.data_ref().unwrap().meshes[0]; - /* let crate_mesh = &crate_gltf.data_ref() - .unwrap().meshes[0]; - - let separate_scene = &separate_gltf.data_ref() - .unwrap().scenes[0]; */ - - let sponza_model = resman - .request::("../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(), - WorldTransform::default(), - 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.35, //..Default::default() - }, - light_tran, - )); - } - - { - let t = Transform::new( - //Vec3::new(-5.0, 1.0, -1.28), - Vec3::new(-5.0, 1.0, -0.0), - //Vec3::new(-10.0, 0.94, -0.28), - Quat::IDENTITY, - Vec3::new(0.25, 0.25, 0.25), - ); - - world.spawn(( - PointLight { - enabled: true, - color: Vec3::new(0.0, 0.0, 1.0), - intensity: 1.0, - range: 2.0, - ..Default::default() - }, - WorldTransform::from(t), - t, - cube_mesh.clone(), - )); - - let t = Transform::new( - Vec3::new(-3.0, 0.2, -1.5), - //Vec3::new(-5.0, 1.0, -0.28), - //Vec3::new(-10.0, 0.94, -0.28), - Quat::IDENTITY, - Vec3::new(0.15, 0.15, 0.15), - ); - - world.spawn(( - PointLight { - enabled: true, - color: Vec3::new(0.0, 0.5, 1.0), - intensity: 1.0, - range: 1.0, - ..Default::default() - }, - WorldTransform::from(t), - t, - cube_mesh.clone(), - )); - - let t = Transform::new( - Vec3::new(0.0, 0.2, -1.5), - //Vec3::new(-5.0, 1.0, -0.28), - //Vec3::new(-10.0, 0.94, -0.28), - Quat::IDENTITY, - Vec3::new(0.15, 0.15, 0.15), - ); - - world.spawn(( - SpotLight { - enabled: true, - color: Vec3::new(1.0, 0.0, 0.0), - intensity: 1.0, - range: 1.5, - //cutoff: math::Angle::Degrees(45.0), - ..Default::default() - }, - WorldTransform::from(t), - t, - cube_mesh.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, - }, - Transform::from(light_tran), - cube_mesh.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 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, - ); - //camera.transform.translation += math::Vec3::new(0.0, 0.0, 5.5); - world.spawn((camera, FreeFlyCamera::default())); - - Ok(()) - }; - - let camera_debug_plugin = move |app: &mut App| { - let sys = - |handler: Res, view: View<&mut CameraComponent>| -> anyhow::Result<()> { - if let Some(true) = handler.was_action_just_pressed("Debug") { - for mut cam in view.into_iter() { - cam.debug = !cam.debug; - } - } - - Ok(()) - }; - - app.with_system("camera_debug_trigger", sys, &[]); - app.with_system( - "update_world_transforms", - scene::system_update_world_transforms, - &[], - ); - }; - let action_handler_plugin = |app: &mut App| { let action_handler = ActionHandler::builder() .add_layout(LayoutId::from(0)) @@ -388,11 +189,197 @@ async fn main() { let mut app = App::new(); app.with_plugin(lyra_engine::DefaultPlugins); - app.with_startup_system(setup_sys.into_system()); + app.with_plugin(setup_scene_plugin); app.with_plugin(action_handler_plugin); //app.with_plugin(script_test_plugin) //app.with_plugin(fps_plugin) - app.with_plugin(camera_debug_plugin); + app.with_system( + "update_world_transforms", + scene::system_update_world_transforms, + &[], + ); app.with_plugin(FreeFlyCameraPlugin); app.run(); } + +fn setup_scene_plugin(app: &mut App) { + let world = &mut app.world; + { + /* let mut window_options = world.get_resource_mut::>(); + window_options.cursor_grab = CursorGrabMode::Confined; + window_options.cursor_visible = false; */ + } + + let resman = world.get_resource_mut::().unwrap(); + //let diffuse_texture = resman.request::("assets/happy-tree.png").unwrap(); + //let antique_camera_model = resman.request::("assets/AntiqueCamera.glb").unwrap(); + //let cube_model = resman.request::("assets/cube-texture-bin.glb").unwrap(); + let cube_gltf = resman + .request::("../assets/texture-sep/texture-sep.gltf") + .unwrap(); + /*let crate_gltf = resman.request::("assets/crate/crate.gltf").unwrap(); + + let separate_gltf = resman.request::("assets/pos-testing/child-node-cubes.glb").unwrap(); */ + //drop(resman); + + cube_gltf.wait_recurse_dependencies_load(); + let cube_mesh = &cube_gltf.data_ref().unwrap().meshes[0]; + /* let crate_mesh = &crate_gltf.data_ref() + .unwrap().meshes[0]; + + let separate_scene = &separate_gltf.data_ref() + .unwrap().scenes[0]; */ + + let sponza_model = resman + .request::("../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(), + WorldTransform::default(), + 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.35, //..Default::default() + }, + light_tran, + )); + } + + { + let t = Transform::new( + //Vec3::new(-5.0, 1.0, -1.28), + Vec3::new(-5.0, 1.0, -0.0), + //Vec3::new(-10.0, 0.94, -0.28), + Quat::IDENTITY, + Vec3::new(0.25, 0.25, 0.25), + ); + + world.spawn(( + PointLight { + enabled: true, + color: Vec3::new(0.0, 0.0, 1.0), + intensity: 1.0, + range: 2.0, + ..Default::default() + }, + WorldTransform::from(t), + t, + cube_mesh.clone(), + )); + + let t = Transform::new( + Vec3::new(-3.0, 0.2, -1.5), + //Vec3::new(-5.0, 1.0, -0.28), + //Vec3::new(-10.0, 0.94, -0.28), + Quat::IDENTITY, + Vec3::new(0.15, 0.15, 0.15), + ); + + world.spawn(( + PointLight { + enabled: true, + color: Vec3::new(0.0, 0.5, 1.0), + intensity: 1.0, + range: 1.0, + ..Default::default() + }, + WorldTransform::from(t), + t, + cube_mesh.clone(), + )); + + let t = Transform::new( + Vec3::new(0.0, 0.2, -1.5), + //Vec3::new(-5.0, 1.0, -0.28), + //Vec3::new(-10.0, 0.94, -0.28), + Quat::IDENTITY, + Vec3::new(0.15, 0.15, 0.15), + ); + + world.spawn(( + SpotLight { + enabled: true, + color: Vec3::new(1.0, 0.0, 0.0), + intensity: 1.0, + range: 1.5, + //cutoff: math::Angle::Degrees(45.0), + ..Default::default() + }, + WorldTransform::from(t), + t, + cube_mesh.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, + }, + Transform::from(light_tran), + cube_mesh.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()), + )); + } */ + + world.spawn(( + CameraBundle::default(), + // these values were taken by manually positioning the camera in the scene + // and printing the position to console. + Transform::new( + Vec3::new(-10.0, 0.94, -0.28), + Quat::from_xyzw(0.03375484, -0.7116095, 0.0342693, 0.70092666), + Vec3::ONE, + ), + FreeFlyCamera::default(), + )); + + //Ok(()) +} \ No newline at end of file