update examples to use new camera bundles

This commit is contained in:
SeanOMik 2024-11-03 15:02:49 -05:00 committed by SeanOMik
parent 6a09b64902
commit 865fbf9b91
12 changed files with 401 additions and 407 deletions

View File

@ -1,87 +1,7 @@
use glam::{Mat4, Vec2}; use glam::Vec2;
use lyra_math::Transform; use lyra_math::Transform;
use lyra_reflect::Reflect;
use crate::math::Angle; use crate::scene::CameraProjection;
#[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),
}
}
}
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
@ -96,7 +16,6 @@ pub struct CameraUniform {
/// The position of the camera /// The position of the camera
pub position: glam::Vec3, pub position: glam::Vec3,
_padding: u32, _padding: u32,
//_padding: [u8; 3],
} }
impl Default for CameraUniform { 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 position = transform.translation;
let forward = transform.forward(); let forward = transform.forward();
let up = transform.up(); let up = transform.up();

View File

@ -12,8 +12,7 @@ use crate::{
Node, NodeDesc, NodeType, RenderGraph, RenderGraphContext, SlotAttribute, SlotValue Node, NodeDesc, NodeType, RenderGraph, RenderGraphContext, SlotAttribute, SlotValue
}, },
render_buffer::BufferWrapper, texture::RenderTexture, render_buffer::BufferWrapper, texture::RenderTexture,
}, }, scene::{Camera, CameraProjection},
scene::CameraComponent,
}; };
#[derive(Debug, Hash, Clone, Default, PartialEq, RenderGraphLabel)] #[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) { 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 mut found_camera = false;
let screen_size = graph.view_target().size();
let uniform = CameraUniform::from_component(*transform, camera.projection, screen_size.as_vec2()); for (camera, projection, transform) in world.view_iter::<(&Camera, &CameraProjection, &Transform)>() {
context.queue_buffer_write_with(BasePassSlots::Camera, 0, uniform) if camera.is_active {
} else { 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!"); warn!("Missing camera!");
} }
} }

View File

@ -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 lyra_reflect::Reflect;
use crate::render::camera::{CameraProjectionMode, OrthographicProjection, PerspectiveProjection}; #[derive(Debug, Clone, Copy, PartialEq, Reflect)]
pub struct OrthographicProjection {
#[derive(Clone, Component, Reflect)] pub scale: f32,
pub struct CameraComponent { pub znear: f32,
pub projection: CameraProjectionMode, pub zfar: f32,
//pub debug: bool,
} }
impl Default for CameraComponent { impl Default for OrthographicProjection {
fn default() -> Self { fn default() -> Self {
Self { Self {
projection: CameraProjectionMode::Perspective(PerspectiveProjection::default()), scale: 1.0,
znear: 0.0,
zfar: 1000.0,
} }
} }
} }
impl CameraComponent { impl OrthographicProjection {
pub fn new_3d() -> Self { pub fn to_mat(&self, viewport_size: Vec2) -> Mat4 {
Self::default() 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 { glam::Mat4::orthographic_rh(
CameraComponent { self.scale * -origin_x,
projection: CameraProjectionMode::Orthographic(OrthographicProjection::default()), self.scale * viewport_size.x as f32 - origin_x,
..Default::default() 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,
} }
} }
} }
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(),
}
}
}

View File

@ -17,7 +17,8 @@ impl ScriptApiProvider for LyraEcsApiProvider {
world.register_lua_wrapper::<LuaActionHandler>(); world.register_lua_wrapper::<LuaActionHandler>();
world.register_lua_wrapper::<LuaWindow>(); world.register_lua_wrapper::<LuaWindow>();
world.register_lua_convert_component::<LuaCamera>("Camera"); // TODO: expose camera
// world.register_lua_convert_component::<LuaCamera>("Camera");
world.register_lua_convert_component::<LuaFreeFlyCamera>("FreeFlyCamera"); world.register_lua_convert_component::<LuaFreeFlyCamera>("FreeFlyCamera");
world.register_lua_convert_component::<LuaWorldTransform>("WorldTransform"); world.register_lua_convert_component::<LuaWorldTransform>("WorldTransform");
@ -54,7 +55,6 @@ impl ScriptApiProvider for LyraEcsApiProvider {
globals.set("TickOfQuery", ctx.create_proxy::<LuaTickOfQuery>()?)?; globals.set("TickOfQuery", ctx.create_proxy::<LuaTickOfQuery>()?)?;
globals.set("OptionalQuery", ctx.create_proxy::<LuaOptionalQuery>()?)?; globals.set("OptionalQuery", ctx.create_proxy::<LuaOptionalQuery>()?)?;
expose_comp_table_wrapper::<LuaCamera>(&ctx, &globals, "Camera")?;
expose_comp_table_wrapper::<LuaFreeFlyCamera>(&ctx, &globals, "FreeFlyCamera")?; expose_comp_table_wrapper::<LuaFreeFlyCamera>(&ctx, &globals, "FreeFlyCamera")?;
expose_comp_table_wrapper::<LuaWorldTransform>(&ctx, &globals, "WorldTransform")?; expose_comp_table_wrapper::<LuaWorldTransform>(&ctx, &globals, "WorldTransform")?;
expose_table_wrapper::<LuaDeviceEvent>(&ctx, &globals, "DeviceEvent")?; expose_table_wrapper::<LuaDeviceEvent>(&ctx, &globals, "DeviceEvent")?;

View File

@ -13,9 +13,6 @@ pub use delta_time::*;
mod window; mod window;
pub use window::*; pub use window::*;
mod camera;
pub use camera::*;
mod free_fly_camera; mod free_fly_camera;
pub use free_fly_camera::*; pub use free_fly_camera::*;

View File

@ -1,6 +1,5 @@
use lyra_engine::{ use lyra_engine::{
assets::{Image, ResourceManager, Texture}, assets::{Image, ResourceManager},
ecs::query::View,
game::App, game::App,
gltf::Gltf, gltf::Gltf,
input::{ input::{
@ -8,17 +7,11 @@ use lyra_engine::{
InputActionPlugin, KeyCode, LayoutId, InputActionPlugin, KeyCode, LayoutId,
}, },
math::{self, Transform, Vec3}, math::{self, Transform, Vec3},
render::{ render::light::directional::DirectionalLight,
camera::{CameraProjectionMode, OrthographicProjection},
light::directional::DirectionalLight,
},
scene::{ scene::{
system_update_world_transforms, CameraComponent, FreeFlyCamera, FreeFlyCameraPlugin, 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
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}, sprite::{self, Sprite},
winit::WindowOptions,
}; };
#[async_std::main] #[async_std::main]
@ -167,11 +160,12 @@ fn setup_scene_plugin(app: &mut App) {
} }
world.spawn(( world.spawn((
CameraComponent { Camera2dBundle {
projection: CameraProjectionMode::Orthographic(OrthographicProjection { projection: CameraProjection::Orthographic(OrthographicProjection {
scale: 0.75, scale: 0.75,
..Default::default() ..Default::default()
}), }),
..Default::default()
}, },
Transform::from_xyz(200.0, 120.0, 0.0), Transform::from_xyz(200.0, 120.0, 0.0),
FreeFlyCamera::default(), FreeFlyCamera::default(),

View File

@ -1,25 +1,16 @@
use std::ptr::NonNull; use std::ptr::NonNull;
use lyra_engine::{ use lyra_engine::{
assets::ResourceManager, gltf::Gltf, assets::ResourceManager, ecs::{
ecs::{
query::{Res, View}, query::{Res, View},
system::{BatchedSystem, Criteria, CriteriaSchedule, IntoSystem}, system::{BatchedSystem, Criteria, CriteriaSchedule, IntoSystem},
World, World,
}, }, game::App, gltf::Gltf, input::{
game::App,
input::{
Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource,
InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput, InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput,
}, }, math::{self, Transform, Vec3}, render::light::directional::DirectionalLight, scene::{
math::{self, Transform, Vec3}, 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
render::light::directional::DirectionalLight, }, DeltaTime
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,
}; };
use tracing::info; use tracing::info;
@ -135,9 +126,11 @@ fn setup_scene_plugin(app: &mut App) {
)); ));
} }
let mut camera = CameraComponent::new_3d(); world.spawn((
camera.transform.translation += math::Vec3::new(0.0, 0.0, 1.5); CameraBundle::default(),
world.spawn((camera, FreeFlyCamera::default())); Transform::from_xyz(0.0, 0.0, 1.5),
FreeFlyCamera::default(),
));
let fps_counter = |counter: Res<fps_counter::FPSCounter>, let fps_counter = |counter: Res<fps_counter::FPSCounter>,
delta: Res<DeltaTime>| -> anyhow::Result<()> { delta: Res<DeltaTime>| -> anyhow::Result<()> {

View File

@ -1,9 +1,9 @@
use lyra_engine::{ use lyra_engine::{
assets::ResourceManager, gltf::Gltf, game::App, input::{ assets::ResourceManager, game::App, gltf::Gltf, input::{
Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource,
InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput, InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput,
}, math::{self, Transform, Vec3}, render::light::directional::DirectionalLight, scene::{ }, 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} }, script::{lua::{LuaScript, LuaScriptingPlugin}, Script, ScriptList}
}; };
@ -125,9 +125,11 @@ fn setup_scene_plugin(app: &mut App) {
)); ));
} }
let mut camera = CameraComponent::new_3d(); world.spawn((
camera.transform.translation += math::Vec3::new(0.0, 0.0, 5.5); CameraBundle::default(),
world.spawn((camera, FreeFlyCamera::default())); Transform::from_xyz(0.0, 0.0, 5.5),
FreeFlyCamera::default(),
));
} }
fn setup_script_plugin(app: &mut App) { fn setup_script_plugin(app: &mut App) {

View File

@ -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 rand::Rng;
use tracing::info; use tracing::info;
@ -95,7 +95,6 @@ async fn main() {
app.with_plugin(lyra_engine::DefaultPlugins); app.with_plugin(lyra_engine::DefaultPlugins);
app.with_plugin(setup_scene_plugin); app.with_plugin(setup_scene_plugin);
app.with_plugin(action_handler_plugin); app.with_plugin(action_handler_plugin);
app.with_plugin(camera_debug_plugin);
app.with_plugin(FreeFlyCameraPlugin); app.with_plugin(FreeFlyCameraPlugin);
app.run(); app.run();
} }
@ -184,26 +183,15 @@ fn setup_scene_plugin(app: &mut App) {
)); ));
} }
let mut camera = CameraComponent::new_3d(); world.spawn((
// these values were taken by manually positioning the camera in the scene. CameraBundle::default(),
camera.transform = Transform::new( // these values were taken by manually positioning the camera in the scene
Vec3::new(-10.0, 0.94, -0.28), // and printing the position to console.
Quat::from_xyzw(0.03375484, -0.7116095, 0.0342693, 0.70092666), Transform::new(
Vec3::ONE Vec3::new(-10.0, 0.94, -0.28),
); Quat::from_xyzw(0.03375484, -0.7116095, 0.0342693, 0.70092666),
world.spawn(( camera, FreeFlyCamera::default() )); Vec3::ONE,
),
FreeFlyCamera::default(),
));
} }
fn camera_debug_plugin(app: &mut App) {
let sys = |handler: Res<ActionHandler>, 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, &[]);
}

View File

@ -1,6 +1,7 @@
use lyra_engine::{ use lyra_engine::{
assets::ResourceManager, gltf::Gltf, assets::ResourceManager,
game::App, game::App,
gltf::Gltf,
input::{ input::{
Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource,
InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput, InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput,
@ -11,9 +12,9 @@ use lyra_engine::{
light::{directional::DirectionalLight, SpotLight}, light::{directional::DirectionalLight, SpotLight},
}, },
scene::{ scene::{
CameraComponent, FreeFlyCamera, FreeFlyCameraPlugin, WorldTransform, CameraBundle, FreeFlyCamera, FreeFlyCameraPlugin, WorldTransform, ACTLBL_LOOK_LEFT_RIGHT,
ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_MOVE_FORWARD_BACKWARD,
ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN, 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), Transform::from_xyz(0.0, -5.0, -2.0),
)); */ )); */
let cube_gltf = resman
.request::<Gltf>("../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 let palm_tree_platform_gltf = resman
.request::<Gltf>("../assets/shadows-platform-palmtree.glb") .request::<Gltf>("../assets/shadows-platform-palmtree.glb")
.unwrap(); .unwrap();
@ -213,9 +207,13 @@ fn setup_scene_plugin(app: &mut App) {
let t = Transform::new( let t = Transform::new(
Vec3::new(4.0 - 1.43, -13.0, 0.0), Vec3::new(4.0 - 1.43, -13.0, 0.0),
//Vec3::new(-5.0, 1.0, -0.28), //Vec3::new(-5.0, 1.0, -0.28),
//Vec3::new(-10.0, 0.94, -0.28), //Vec3::new(-10.0, 0.94, -0.28),
Quat::from_euler(
Quat::from_euler(math::EulerRot::XYZ, 0.0, math::Angle::Degrees(-45.0).to_radians(), 0.0), math::EulerRot::XYZ,
0.0,
math::Angle::Degrees(-45.0).to_radians(),
0.0,
),
Vec3::new(0.15, 0.15, 0.15), 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(); let mut pos = Transform::from_xyz(-1.0, -10.0, -1.5);
camera.transform.translation = math::Vec3::new(-1.0, -10.0, -1.5); pos.rotate_x(math::Angle::Degrees(-27.0));
camera.transform.rotate_x(math::Angle::Degrees(-27.0)); pos.rotate_y(math::Angle::Degrees(-90.0));
camera.transform.rotate_y(math::Angle::Degrees(-90.0)); world.spawn((CameraBundle::default(), pos, FreeFlyCamera::default()));
world.spawn((camera, FreeFlyCamera::default()));
} }

View File

@ -1,10 +1,18 @@
use lyra_engine::{ 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, Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource,
InputActionPlugin, KeyCode, LayoutId, 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 math::{self, Transform, Vec3},
}, winit::WindowOptions 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] #[async_std::main]
@ -84,7 +92,11 @@ async fn main() {
.with_plugin(action_handler_plugin) .with_plugin(action_handler_plugin)
//.with_plugin(camera_debug_plugin) //.with_plugin(camera_debug_plugin)
.with_plugin(FreeFlyCameraPlugin) .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(); a.run();
} }
@ -135,7 +147,9 @@ fn setup_scene_plugin(app: &mut App) {
)); ));
} }
let mut camera = CameraComponent::new_3d(); world.spawn((
camera.transform.translation += math::Vec3::new(0.0, 0.0, 5.5); CameraBundle::default(),
world.spawn((camera, FreeFlyCamera::default())); Transform::from_xyz(0.0, 0.0, 5.5),
FreeFlyCamera::default(),
));
} }

View File

@ -1,14 +1,14 @@
use std::ptr::NonNull; use std::ptr::NonNull;
use lyra_engine::assets::ResourceManager; use lyra_engine::assets::ResourceManager;
use lyra_engine::scene::CameraBundle;
use lyra_engine::{ use lyra_engine::{
gltf::Gltf,
ecs::{ ecs::{
query::{Res, View}, system::{Criteria, CriteriaSchedule},
system::{Criteria, CriteriaSchedule, IntoSystem},
Component, World, Component, World,
}, },
game::App, game::App,
gltf::Gltf,
input::{ input::{
Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource,
InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput, InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput,
@ -16,9 +16,9 @@ use lyra_engine::{
math::{self, Quat, Transform, Vec3}, math::{self, Quat, Transform, Vec3},
render::light::{directional::DirectionalLight, PointLight, SpotLight}, render::light::{directional::DirectionalLight, PointLight, SpotLight},
scene::{ scene::{
self, CameraComponent, FreeFlyCamera, FreeFlyCameraPlugin, WorldTransform, self, FreeFlyCamera, FreeFlyCameraPlugin, WorldTransform, ACTLBL_LOOK_LEFT_RIGHT,
ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_MOVE_FORWARD_BACKWARD,
ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN,
}, },
DeltaTime, DeltaTime,
}; };
@ -101,205 +101,6 @@ struct CubeFlag;
#[async_std::main] #[async_std::main]
async fn 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 resman = world.get_resource_mut::<ResourceManager>().unwrap();
//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_gltf = resman
.request::<Gltf>("../assets/texture-sep/texture-sep.gltf")
.unwrap();
/*let crate_gltf = resman.request::<Gltf>("assets/crate/crate.gltf").unwrap();
let separate_gltf = resman.request::<Gltf>("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::<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(),
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<ActionHandler>, 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_plugin = |app: &mut App| {
let action_handler = ActionHandler::builder() let action_handler = ActionHandler::builder()
.add_layout(LayoutId::from(0)) .add_layout(LayoutId::from(0))
@ -388,11 +189,197 @@ async fn main() {
let mut app = App::new(); let mut app = App::new();
app.with_plugin(lyra_engine::DefaultPlugins); 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(action_handler_plugin);
//app.with_plugin(script_test_plugin) //app.with_plugin(script_test_plugin)
//app.with_plugin(fps_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.with_plugin(FreeFlyCameraPlugin);
app.run(); app.run();
} }
fn setup_scene_plugin(app: &mut App) {
let world = &mut app.world;
{
/* let mut window_options = world.get_resource_mut::<Ct<WindowOptions>>();
window_options.cursor_grab = CursorGrabMode::Confined;
window_options.cursor_visible = false; */
}
let resman = world.get_resource_mut::<ResourceManager>().unwrap();
//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_gltf = resman
.request::<Gltf>("../assets/texture-sep/texture-sep.gltf")
.unwrap();
/*let crate_gltf = resman.request::<Gltf>("assets/crate/crate.gltf").unwrap();
let separate_gltf = resman.request::<Gltf>("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::<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(),
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(())
}