render: fix 2d camera
This commit is contained in:
parent
315924f920
commit
617c4d69e8
|
@ -1,38 +1,85 @@
|
||||||
|
use glam::{Mat4, Vec2};
|
||||||
|
use lyra_math::Transform;
|
||||||
use lyra_reflect::Reflect;
|
use lyra_reflect::Reflect;
|
||||||
use winit::dpi::PhysicalSize;
|
|
||||||
|
|
||||||
use crate::{math::{Angle, OPENGL_TO_WGPU_MATRIX}, scene::CameraComponent};
|
use crate::math::Angle;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Reflect)]
|
#[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 {
|
pub enum CameraProjectionMode {
|
||||||
/// 3d camera projection
|
/// 3d camera projection
|
||||||
Perspective,
|
Perspective(PerspectiveProjection),
|
||||||
/// 2d camera projection
|
/// 2d camera projection
|
||||||
Orthographic,
|
Orthographic(OrthographicProjection),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
impl CameraProjectionMode {
|
||||||
pub struct Projection {
|
pub fn to_mat4(&self, viewport_size: Vec2) -> Mat4 {
|
||||||
aspect: f32,
|
match self {
|
||||||
znear: f32,
|
CameraProjectionMode::Perspective(proj) => proj.to_mat(viewport_size),
|
||||||
zfar: f32,
|
CameraProjectionMode::Orthographic(proj) => proj.to_mat(viewport_size),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Projection {
|
|
||||||
pub fn new(width: u32, height: u32, znear: f32, zfar: f32) -> Self {
|
|
||||||
Self {
|
|
||||||
aspect: width as f32 / height as f32,
|
|
||||||
znear,
|
|
||||||
zfar,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resize(&mut self, width: u32, height: u32) {
|
|
||||||
self.aspect = width as f32 / height as f32;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn calc_matrix(&self, fov: Angle, _mode: CameraProjectionMode) -> glam::Mat4 {
|
|
||||||
OPENGL_TO_WGPU_MATRIX * glam::Mat4::perspective_rh_gl(fov.to_radians(), self.aspect, self.znear, self.zfar)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,9 +95,8 @@ pub struct CameraUniform {
|
||||||
pub projection: glam::Mat4,
|
pub projection: glam::Mat4,
|
||||||
/// The position of the camera
|
/// The position of the camera
|
||||||
pub position: glam::Vec3,
|
pub position: glam::Vec3,
|
||||||
pub tile_debug: u32,
|
_padding: u32,
|
||||||
//_padding: [u8; 3],
|
//_padding: [u8; 3],
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CameraUniform {
|
impl Default for CameraUniform {
|
||||||
|
@ -61,106 +107,45 @@ impl Default for CameraUniform {
|
||||||
view_projection: glam::Mat4::IDENTITY,
|
view_projection: glam::Mat4::IDENTITY,
|
||||||
projection: glam::Mat4::IDENTITY,
|
projection: glam::Mat4::IDENTITY,
|
||||||
position: Default::default(),
|
position: Default::default(),
|
||||||
tile_debug: 0,
|
_padding: 0,
|
||||||
//_padding: 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CameraUniform {
|
impl CameraUniform {
|
||||||
pub fn new(view: glam::Mat4, inverse_projection: glam::Mat4, view_projection: glam::Mat4, projection: glam::Mat4, position: glam::Vec3) -> Self {
|
pub fn new(
|
||||||
|
view: glam::Mat4,
|
||||||
|
inverse_projection: glam::Mat4,
|
||||||
|
view_projection: glam::Mat4,
|
||||||
|
projection: glam::Mat4,
|
||||||
|
position: glam::Vec3,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
view,
|
view,
|
||||||
inverse_projection,
|
inverse_projection,
|
||||||
view_projection,
|
view_projection,
|
||||||
projection,
|
projection,
|
||||||
position,
|
position,
|
||||||
tile_debug: 0
|
_padding: 0,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
pub fn from_component(transform: Transform, projection: CameraProjectionMode, viewport_size: Vec2) -> Self {
|
||||||
pub struct RenderCamera {
|
let position = transform.translation;
|
||||||
view_proj: glam::Mat4,
|
let forward = transform.forward();
|
||||||
|
let up = transform.up();
|
||||||
|
let view = glam::Mat4::look_to_rh(position, forward, up);
|
||||||
|
|
||||||
#[allow(dead_code)]
|
let projection = projection.to_mat4(viewport_size);
|
||||||
size: PhysicalSize<u32>,
|
let view_projection = projection * view;
|
||||||
aspect: f32,
|
|
||||||
znear: f32,
|
|
||||||
zfar: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RenderCamera {
|
|
||||||
pub fn new(size: PhysicalSize<u32>) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
view_proj: glam::Mat4::IDENTITY,
|
|
||||||
|
|
||||||
size,
|
|
||||||
aspect: size.width as f32 / size.height as f32,
|
|
||||||
znear: 0.1,
|
|
||||||
zfar: 100.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_aspect_ratio(&mut self, size: PhysicalSize<u32>) {
|
|
||||||
self.aspect = size.width as f32 / size.height as f32;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculates the view projection, and the view
|
|
||||||
///
|
|
||||||
/// Returns: A tuple with the view projection as the first element, and the
|
|
||||||
/// view matrix as the second.
|
|
||||||
pub fn calc_view_projection(&mut self, camera: &CameraComponent) -> CameraUniform {
|
|
||||||
let position = camera.transform.translation;
|
|
||||||
let forward = camera.transform.forward();
|
|
||||||
let up = camera.transform.up();
|
|
||||||
|
|
||||||
let view = glam::Mat4::look_to_rh(
|
|
||||||
position,
|
|
||||||
forward,
|
|
||||||
up
|
|
||||||
);
|
|
||||||
|
|
||||||
match camera.mode {
|
|
||||||
CameraProjectionMode::Perspective => {
|
|
||||||
let proj = glam::Mat4::perspective_rh_gl(camera.fov.to_radians(), self.aspect, self.znear, self.zfar);
|
|
||||||
|
|
||||||
self.view_proj = OPENGL_TO_WGPU_MATRIX * proj * view;
|
|
||||||
//(&self.view_proj, view)
|
|
||||||
|
|
||||||
CameraUniform {
|
|
||||||
view,
|
view,
|
||||||
inverse_projection: proj.inverse(),
|
inverse_projection: projection.inverse(),
|
||||||
view_projection: self.view_proj,
|
view_projection,
|
||||||
projection: proj,
|
projection,
|
||||||
position,
|
position,
|
||||||
tile_debug: camera.debug as u32,
|
_padding: 0,
|
||||||
}
|
|
||||||
},
|
|
||||||
CameraProjectionMode::Orthographic => {
|
|
||||||
let target = camera.transform.rotation * glam::Vec3::new(0.0, 0.0, -1.0);
|
|
||||||
let target = target.normalize();
|
|
||||||
|
|
||||||
let ratio_size_per_depth = ((camera.fov.to_radians() / 2.0) * 2.0).atan();
|
|
||||||
let distance = (target - position).length();
|
|
||||||
|
|
||||||
let size_y = ratio_size_per_depth * distance;
|
|
||||||
let size_x = ratio_size_per_depth * distance * self.aspect;
|
|
||||||
|
|
||||||
let proj = glam::Mat4::orthographic_rh_gl(-size_x, size_x, -size_y, size_y, self.znear, self.zfar);
|
|
||||||
|
|
||||||
self.view_proj = OPENGL_TO_WGPU_MATRIX * proj;
|
|
||||||
|
|
||||||
CameraUniform {
|
|
||||||
view,
|
|
||||||
inverse_projection: proj.inverse(),
|
|
||||||
view_projection: self.view_proj,
|
|
||||||
projection: proj,
|
|
||||||
position,
|
|
||||||
tile_debug: camera.debug as u32,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,12 +2,12 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use glam::UVec2;
|
use glam::UVec2;
|
||||||
use lyra_game_derive::RenderGraphLabel;
|
use lyra_game_derive::RenderGraphLabel;
|
||||||
|
use lyra_math::Transform;
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
use winit::dpi::PhysicalSize;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
render::{
|
render::{
|
||||||
camera::{CameraUniform, RenderCamera},
|
camera::CameraUniform,
|
||||||
graph::{
|
graph::{
|
||||||
Node, NodeDesc, NodeType, RenderGraph, RenderGraphContext, SlotAttribute, SlotValue
|
Node, NodeDesc, NodeType, RenderGraph, RenderGraphContext, SlotAttribute, SlotValue
|
||||||
},
|
},
|
||||||
|
@ -114,13 +114,9 @@ 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) = world.view_iter::<&mut CameraComponent>().next() {
|
if let Some((camera, transform)) = world.view_iter::<(&CameraComponent, &Transform)>().next() {
|
||||||
let screen_size = graph.view_target().size();
|
let screen_size = graph.view_target().size();
|
||||||
|
let uniform = CameraUniform::from_component(*transform, camera.projection, screen_size.as_vec2());
|
||||||
let mut render_cam =
|
|
||||||
RenderCamera::new(PhysicalSize::new(screen_size.x, screen_size.y));
|
|
||||||
let uniform = render_cam.calc_view_projection(&camera);
|
|
||||||
|
|
||||||
context.queue_buffer_write_with(BasePassSlots::Camera, 0, uniform)
|
context.queue_buffer_write_with(BasePassSlots::Camera, 0, uniform)
|
||||||
} else {
|
} else {
|
||||||
warn!("Missing camera!");
|
warn!("Missing camera!");
|
||||||
|
|
|
@ -1,23 +1,18 @@
|
||||||
use lyra_ecs::Component;
|
use lyra_ecs::Component;
|
||||||
use lyra_reflect::Reflect;
|
use lyra_reflect::Reflect;
|
||||||
|
|
||||||
use crate::{math::{Angle, Transform}, render::camera::CameraProjectionMode};
|
use crate::render::camera::{CameraProjectionMode, OrthographicProjection, PerspectiveProjection};
|
||||||
|
|
||||||
#[derive(Clone, Component, Reflect)]
|
#[derive(Clone, Component, Reflect)]
|
||||||
pub struct CameraComponent {
|
pub struct CameraComponent {
|
||||||
pub transform: Transform,
|
pub projection: CameraProjectionMode,
|
||||||
pub fov: Angle,
|
//pub debug: bool,
|
||||||
pub mode: CameraProjectionMode,
|
|
||||||
pub debug: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CameraComponent {
|
impl Default for CameraComponent {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
transform: Transform::default(),
|
projection: CameraProjectionMode::Perspective(PerspectiveProjection::default()),
|
||||||
fov: Angle::Degrees(45.0),
|
|
||||||
mode: CameraProjectionMode::Perspective,
|
|
||||||
debug: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +24,7 @@ impl CameraComponent {
|
||||||
|
|
||||||
pub fn new_2d() -> Self {
|
pub fn new_2d() -> Self {
|
||||||
CameraComponent {
|
CameraComponent {
|
||||||
mode: CameraProjectionMode::Orthographic,
|
projection: CameraProjectionMode::Orthographic(OrthographicProjection::default()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
use glam::{EulerRot, Quat, Vec3};
|
use glam::{EulerRot, Quat, Vec3};
|
||||||
use lyra_ecs::{query::{Res, View}, Component};
|
use lyra_ecs::{query::{Res, View}, Component};
|
||||||
|
use lyra_math::Transform;
|
||||||
use lyra_reflect::Reflect;
|
use lyra_reflect::Reflect;
|
||||||
|
|
||||||
use crate::{game::App, input::ActionHandler, plugin::Plugin, DeltaTime};
|
use crate::{game::App, input::ActionHandler, plugin::Plugin, DeltaTime};
|
||||||
|
|
||||||
use super::CameraComponent;
|
|
||||||
|
|
||||||
pub const ACTLBL_MOVE_UP_DOWN: &str = "MoveUpDown";
|
pub const ACTLBL_MOVE_UP_DOWN: &str = "MoveUpDown";
|
||||||
pub const ACTLBL_MOVE_LEFT_RIGHT: &str = "MoveLeftRight";
|
pub const ACTLBL_MOVE_LEFT_RIGHT: &str = "MoveLeftRight";
|
||||||
pub const ACTLBL_MOVE_FORWARD_BACKWARD: &str = "MoveForwardBackward";
|
pub const ACTLBL_MOVE_FORWARD_BACKWARD: &str = "MoveForwardBackward";
|
||||||
|
@ -40,11 +39,11 @@ impl FreeFlyCamera {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn free_fly_camera_controller(delta_time: Res<DeltaTime>, handler: Res<ActionHandler>, view: View<(&mut CameraComponent, &FreeFlyCamera)>) -> anyhow::Result<()> {
|
pub fn free_fly_camera_controller(delta_time: Res<DeltaTime>, handler: Res<ActionHandler>, view: View<(&mut Transform, &FreeFlyCamera)>) -> anyhow::Result<()> {
|
||||||
let delta_time = **delta_time;
|
let delta_time = **delta_time;
|
||||||
for (mut cam, fly) in view.into_iter() {
|
for (mut transform, fly) in view.into_iter() {
|
||||||
let forward = cam.transform.forward();
|
let forward = transform.forward();
|
||||||
let left = cam.transform.left();
|
let left = transform.left();
|
||||||
let up = Vec3::Y;
|
let up = Vec3::Y;
|
||||||
|
|
||||||
let move_y = handler.get_axis_modifier(ACTLBL_MOVE_UP_DOWN).unwrap_or(0.0);
|
let move_y = handler.get_axis_modifier(ACTLBL_MOVE_UP_DOWN).unwrap_or(0.0);
|
||||||
|
@ -57,7 +56,7 @@ pub fn free_fly_camera_controller(delta_time: Res<DeltaTime>, handler: Res<Actio
|
||||||
velocity += move_z * forward;
|
velocity += move_z * forward;
|
||||||
|
|
||||||
if velocity != Vec3::ZERO {
|
if velocity != Vec3::ZERO {
|
||||||
cam.transform.translation += velocity.normalize() * fly.speed * delta_time; // TODO: speeding up
|
transform.translation += velocity.normalize() * fly.speed * delta_time; // TODO: speeding up
|
||||||
}
|
}
|
||||||
|
|
||||||
let motion_x = handler.get_axis_modifier(ACTLBL_LOOK_LEFT_RIGHT).unwrap_or(0.0);
|
let motion_x = handler.get_axis_modifier(ACTLBL_LOOK_LEFT_RIGHT).unwrap_or(0.0);
|
||||||
|
@ -72,13 +71,13 @@ pub fn free_fly_camera_controller(delta_time: Res<DeltaTime>, handler: Res<Actio
|
||||||
if camera_rot != Vec3::ZERO {
|
if camera_rot != Vec3::ZERO {
|
||||||
let look_velocity = camera_rot * fly.look_speed * delta_time;
|
let look_velocity = camera_rot * fly.look_speed * delta_time;
|
||||||
|
|
||||||
let (mut y, mut x, _) = cam.transform.rotation.to_euler(EulerRot::YXZ);
|
let (mut y, mut x, _) = transform.rotation.to_euler(EulerRot::YXZ);
|
||||||
x += look_velocity.x;
|
x += look_velocity.x;
|
||||||
y += look_velocity.y;
|
y += look_velocity.y;
|
||||||
x = x.clamp(-1.54, 1.54);
|
x = x.clamp(-1.54, 1.54);
|
||||||
|
|
||||||
// rotation is not commutative, keep this order to avoid unintended roll
|
// rotation is not commutative, keep this order to avoid unintended roll
|
||||||
cam.transform.rotation = Quat::from_axis_angle(Vec3::Y, y)
|
transform.rotation = Quat::from_axis_angle(Vec3::Y, y)
|
||||||
* Quat::from_axis_angle(Vec3::X, x);
|
* Quat::from_axis_angle(Vec3::X, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub fn radians_to_degrees(radians: f32) -> f32 {
|
||||||
radians * 180.0 / PI
|
radians * 180.0 / PI
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub enum Angle {
|
pub enum Angle {
|
||||||
Degrees(f32),
|
Degrees(f32),
|
||||||
Radians(f32),
|
Radians(f32),
|
||||||
|
|
|
@ -1,19 +1,66 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
lua::{
|
lua::{
|
||||||
wrappers::{LuaAngle, LuaTransform},
|
wrappers::LuaAngle,
|
||||||
LuaWrapper
|
LuaWrapper,
|
||||||
},
|
},
|
||||||
ScriptBorrow,
|
ScriptBorrow,
|
||||||
};
|
};
|
||||||
use lyra_game::{render::camera::CameraProjectionMode, scene::CameraComponent};
|
use lyra_game::{
|
||||||
use lyra_reflect::Enum;
|
render::camera::{CameraProjectionMode, OrthographicProjection, PerspectiveProjection},
|
||||||
|
scene::CameraComponent,
|
||||||
|
};
|
||||||
use lyra_scripting_derive::to_lua_convert;
|
use lyra_scripting_derive::to_lua_convert;
|
||||||
|
|
||||||
fn projection_mode_from_str(s: &str) -> Option<CameraProjectionMode> {
|
fn projection_as_table(lua: &mlua::Lua, projection: CameraProjectionMode) -> mlua::Result<mlua::Table> {
|
||||||
match s {
|
let table = lua.create_table()?;
|
||||||
"perspective" => Some(CameraProjectionMode::Perspective),
|
|
||||||
"orthographic" => Some(CameraProjectionMode::Orthographic),
|
match projection {
|
||||||
_ => None,
|
CameraProjectionMode::Perspective(proj) => {
|
||||||
|
table.set("type", "perspective")?;
|
||||||
|
table.set("fov", LuaAngle(proj.fov))?;
|
||||||
|
table.set("znear", proj.znear)?;
|
||||||
|
table.set("zfar", proj.zfar)?;
|
||||||
|
},
|
||||||
|
CameraProjectionMode::Orthographic(proj) => {
|
||||||
|
table.set("type", "orthographic")?;
|
||||||
|
table.set("scale", proj.scale)?;
|
||||||
|
table.set("znear", proj.znear)?;
|
||||||
|
table.set("zfar", proj.zfar)?;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(table)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn projection_from_table(t: &mlua::Table) -> mlua::Result<CameraProjectionMode> {
|
||||||
|
let ty: String = t.get("type")?;
|
||||||
|
let ty = ty.as_str();
|
||||||
|
|
||||||
|
let znear: f32 = t.get("znear")?;
|
||||||
|
let zfar: f32 = t.get("zfar")?;
|
||||||
|
|
||||||
|
match ty {
|
||||||
|
"perspective" => {
|
||||||
|
let fov: LuaAngle = t.get("fov")?;
|
||||||
|
Ok(CameraProjectionMode::Perspective(PerspectiveProjection {
|
||||||
|
fov: fov.0,
|
||||||
|
znear,
|
||||||
|
zfar,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
"orthographic" => {
|
||||||
|
let scale: f32 = t.get("scale")?;
|
||||||
|
Ok(CameraProjectionMode::Orthographic(OrthographicProjection {
|
||||||
|
scale,
|
||||||
|
znear,
|
||||||
|
zfar,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
_ => Err(mlua::Error::FromLuaConversionError {
|
||||||
|
from: "Table",
|
||||||
|
to: "CameraProjection".into(),
|
||||||
|
message: Some(format!("unknown projection type: '{}'", ty)),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,20 +74,16 @@ to_lua_convert!(
|
||||||
// Reflection type, can be 'component' or 'resource'
|
// Reflection type, can be 'component' or 'resource'
|
||||||
reflect=component,
|
reflect=component,
|
||||||
fields={
|
fields={
|
||||||
transform: wrap(LuaTransform),
|
|
||||||
fov: wrap(LuaAngle),
|
|
||||||
(
|
(
|
||||||
mode,
|
projection,
|
||||||
// Get the table from the value, result must be `CameraProjectionMode`
|
|
||||||
get={
|
get={
|
||||||
let mode: String = table.get("mode")?;
|
let p: mlua::Table = table.get("projection")?;
|
||||||
projection_mode_from_str(&mode).unwrap()
|
projection_from_table(&p)?
|
||||||
|
|
||||||
},
|
},
|
||||||
// Get the value from self, result must be the type in Lua, here its `String`.
|
|
||||||
set={
|
set={
|
||||||
self.mode.variant_name().to_lowercase()
|
projection_as_table(lua, self.projection)?
|
||||||
}
|
},
|
||||||
),
|
)
|
||||||
debug: bool
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,10 +1,24 @@
|
||||||
use lyra_engine::{
|
use lyra_engine::{
|
||||||
assets::{Image, ResourceManager, Texture}, ecs::query::View, game::App, gltf::Gltf, input::{
|
assets::{Image, ResourceManager, Texture},
|
||||||
|
ecs::query::View,
|
||||||
|
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},
|
||||||
}, sprite::{self, Sprite}, winit::WindowOptions
|
render::{
|
||||||
|
camera::{CameraProjectionMode, OrthographicProjection},
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
sprite::{self, Sprite},
|
||||||
|
winit::WindowOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[async_std::main]
|
#[async_std::main]
|
||||||
|
@ -84,7 +98,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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,8 +131,7 @@ fn setup_scene_plugin(app: &mut App) {
|
||||||
cube_gltf.wait_recurse_dependencies_load();
|
cube_gltf.wait_recurse_dependencies_load();
|
||||||
let cube_mesh = &cube_gltf.data_ref().unwrap().scenes[0];
|
let cube_mesh = &cube_gltf.data_ref().unwrap().scenes[0];
|
||||||
|
|
||||||
let image = resman.request::<Image>("../assets/Egg_item.png")
|
let image = resman.request::<Image>("../assets/Egg_item.png").unwrap();
|
||||||
.unwrap();
|
|
||||||
image.wait_recurse_dependencies_load();
|
image.wait_recurse_dependencies_load();
|
||||||
|
|
||||||
drop(resman);
|
drop(resman);
|
||||||
|
@ -131,7 +148,7 @@ fn setup_scene_plugin(app: &mut App) {
|
||||||
pivot: sprite::Pivot::Center,
|
pivot: sprite::Pivot::Center,
|
||||||
},
|
},
|
||||||
WorldTransform::default(),
|
WorldTransform::default(),
|
||||||
Transform::from_xyz(0.0, 0.0, -20.0),
|
Transform::from_xyz(0.0, 0.0, -10.0),
|
||||||
));
|
));
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -149,7 +166,14 @@ 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);
|
CameraComponent {
|
||||||
world.spawn((camera, FreeFlyCamera::default()));
|
projection: CameraProjectionMode::Orthographic(OrthographicProjection {
|
||||||
|
scale: 0.75,
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
Transform::from_xyz(200.0, 120.0, 0.0),
|
||||||
|
FreeFlyCamera::default(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue