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 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 {
|
||||
/// 3d camera projection
|
||||
Perspective,
|
||||
Perspective(PerspectiveProjection),
|
||||
/// 2d camera projection
|
||||
Orthographic,
|
||||
Orthographic(OrthographicProjection),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Projection {
|
||||
aspect: f32,
|
||||
znear: f32,
|
||||
zfar: f32,
|
||||
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),
|
||||
}
|
||||
|
||||
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,
|
||||
/// The position of the camera
|
||||
pub position: glam::Vec3,
|
||||
pub tile_debug: u32,
|
||||
_padding: u32,
|
||||
//_padding: [u8; 3],
|
||||
|
||||
}
|
||||
|
||||
impl Default for CameraUniform {
|
||||
|
@ -61,106 +107,45 @@ impl Default for CameraUniform {
|
|||
view_projection: glam::Mat4::IDENTITY,
|
||||
projection: glam::Mat4::IDENTITY,
|
||||
position: Default::default(),
|
||||
tile_debug: 0,
|
||||
//_padding: 0,
|
||||
_padding: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
view,
|
||||
inverse_projection,
|
||||
view_projection,
|
||||
projection,
|
||||
position,
|
||||
tile_debug: 0
|
||||
}
|
||||
_padding: 0,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RenderCamera {
|
||||
view_proj: glam::Mat4,
|
||||
pub fn from_component(transform: Transform, projection: CameraProjectionMode, viewport_size: Vec2) -> Self {
|
||||
let position = transform.translation;
|
||||
let forward = transform.forward();
|
||||
let up = transform.up();
|
||||
let view = glam::Mat4::look_to_rh(position, forward, up);
|
||||
|
||||
#[allow(dead_code)]
|
||||
size: PhysicalSize<u32>,
|
||||
aspect: f32,
|
||||
znear: f32,
|
||||
zfar: f32,
|
||||
}
|
||||
let projection = projection.to_mat4(viewport_size);
|
||||
let view_projection = projection * view;
|
||||
|
||||
impl RenderCamera {
|
||||
pub fn new(size: PhysicalSize<u32>) -> 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,
|
||||
inverse_projection: proj.inverse(),
|
||||
view_projection: self.view_proj,
|
||||
projection: proj,
|
||||
inverse_projection: projection.inverse(),
|
||||
view_projection,
|
||||
projection,
|
||||
position,
|
||||
tile_debug: camera.debug as u32,
|
||||
}
|
||||
},
|
||||
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,
|
||||
}
|
||||
},
|
||||
_padding: 0,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,12 +2,12 @@ use std::sync::Arc;
|
|||
|
||||
use glam::UVec2;
|
||||
use lyra_game_derive::RenderGraphLabel;
|
||||
use lyra_math::Transform;
|
||||
use tracing::warn;
|
||||
use winit::dpi::PhysicalSize;
|
||||
|
||||
use crate::{
|
||||
render::{
|
||||
camera::{CameraUniform, RenderCamera},
|
||||
camera::CameraUniform,
|
||||
graph::{
|
||||
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) {
|
||||
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 mut render_cam =
|
||||
RenderCamera::new(PhysicalSize::new(screen_size.x, screen_size.y));
|
||||
let uniform = render_cam.calc_view_projection(&camera);
|
||||
|
||||
let uniform = CameraUniform::from_component(*transform, camera.projection, screen_size.as_vec2());
|
||||
context.queue_buffer_write_with(BasePassSlots::Camera, 0, uniform)
|
||||
} else {
|
||||
warn!("Missing camera!");
|
||||
|
|
|
@ -1,23 +1,18 @@
|
|||
use lyra_ecs::Component;
|
||||
use lyra_reflect::Reflect;
|
||||
|
||||
use crate::{math::{Angle, Transform}, render::camera::CameraProjectionMode};
|
||||
use crate::render::camera::{CameraProjectionMode, OrthographicProjection, PerspectiveProjection};
|
||||
|
||||
#[derive(Clone, Component, Reflect)]
|
||||
pub struct CameraComponent {
|
||||
pub transform: Transform,
|
||||
pub fov: Angle,
|
||||
pub mode: CameraProjectionMode,
|
||||
pub debug: bool,
|
||||
pub projection: CameraProjectionMode,
|
||||
//pub debug: bool,
|
||||
}
|
||||
|
||||
impl Default for CameraComponent {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
transform: Transform::default(),
|
||||
fov: Angle::Degrees(45.0),
|
||||
mode: CameraProjectionMode::Perspective,
|
||||
debug: false,
|
||||
projection: CameraProjectionMode::Perspective(PerspectiveProjection::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +24,7 @@ impl CameraComponent {
|
|||
|
||||
pub fn new_2d() -> Self {
|
||||
CameraComponent {
|
||||
mode: CameraProjectionMode::Orthographic,
|
||||
projection: CameraProjectionMode::Orthographic(OrthographicProjection::default()),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
use glam::{EulerRot, Quat, Vec3};
|
||||
use lyra_ecs::{query::{Res, View}, Component};
|
||||
use lyra_math::Transform;
|
||||
use lyra_reflect::Reflect;
|
||||
|
||||
use crate::{game::App, input::ActionHandler, plugin::Plugin, DeltaTime};
|
||||
|
||||
use super::CameraComponent;
|
||||
|
||||
pub const ACTLBL_MOVE_UP_DOWN: &str = "MoveUpDown";
|
||||
pub const ACTLBL_MOVE_LEFT_RIGHT: &str = "MoveLeftRight";
|
||||
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;
|
||||
for (mut cam, fly) in view.into_iter() {
|
||||
let forward = cam.transform.forward();
|
||||
let left = cam.transform.left();
|
||||
for (mut transform, fly) in view.into_iter() {
|
||||
let forward = transform.forward();
|
||||
let left = transform.left();
|
||||
let up = Vec3::Y;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
@ -72,13 +71,13 @@ pub fn free_fly_camera_controller(delta_time: Res<DeltaTime>, handler: Res<Actio
|
|||
if camera_rot != Vec3::ZERO {
|
||||
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;
|
||||
y += look_velocity.y;
|
||||
x = x.clamp(-1.54, 1.54);
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ pub fn radians_to_degrees(radians: f32) -> f32 {
|
|||
radians * 180.0 / PI
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum Angle {
|
||||
Degrees(f32),
|
||||
Radians(f32),
|
||||
|
|
|
@ -1,19 +1,66 @@
|
|||
use crate::{
|
||||
lua::{
|
||||
wrappers::{LuaAngle, LuaTransform},
|
||||
LuaWrapper
|
||||
wrappers::LuaAngle,
|
||||
LuaWrapper,
|
||||
},
|
||||
ScriptBorrow,
|
||||
};
|
||||
use lyra_game::{render::camera::CameraProjectionMode, scene::CameraComponent};
|
||||
use lyra_reflect::Enum;
|
||||
use lyra_game::{
|
||||
render::camera::{CameraProjectionMode, OrthographicProjection, PerspectiveProjection},
|
||||
scene::CameraComponent,
|
||||
};
|
||||
use lyra_scripting_derive::to_lua_convert;
|
||||
|
||||
fn projection_mode_from_str(s: &str) -> Option<CameraProjectionMode> {
|
||||
match s {
|
||||
"perspective" => Some(CameraProjectionMode::Perspective),
|
||||
"orthographic" => Some(CameraProjectionMode::Orthographic),
|
||||
_ => None,
|
||||
fn projection_as_table(lua: &mlua::Lua, projection: CameraProjectionMode) -> mlua::Result<mlua::Table> {
|
||||
let table = lua.create_table()?;
|
||||
|
||||
match projection {
|
||||
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'
|
||||
reflect=component,
|
||||
fields={
|
||||
transform: wrap(LuaTransform),
|
||||
fov: wrap(LuaAngle),
|
||||
(
|
||||
mode,
|
||||
// Get the table from the value, result must be `CameraProjectionMode`
|
||||
projection,
|
||||
get={
|
||||
let mode: String = table.get("mode")?;
|
||||
projection_mode_from_str(&mode).unwrap()
|
||||
let p: mlua::Table = table.get("projection")?;
|
||||
projection_from_table(&p)?
|
||||
|
||||
},
|
||||
// Get the value from self, result must be the type in Lua, here its `String`.
|
||||
set={
|
||||
self.mode.variant_name().to_lowercase()
|
||||
}
|
||||
),
|
||||
debug: bool
|
||||
projection_as_table(lua, self.projection)?
|
||||
},
|
||||
)
|
||||
}
|
||||
);
|
||||
|
|
|
@ -1,10 +1,24 @@
|
|||
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,
|
||||
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
|
||||
}, sprite::{self, Sprite}, winit::WindowOptions
|
||||
},
|
||||
math::{self, Transform, Vec3},
|
||||
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]
|
||||
|
@ -84,7 +98,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();
|
||||
}
|
||||
|
||||
|
@ -113,8 +131,7 @@ fn setup_scene_plugin(app: &mut App) {
|
|||
cube_gltf.wait_recurse_dependencies_load();
|
||||
let cube_mesh = &cube_gltf.data_ref().unwrap().scenes[0];
|
||||
|
||||
let image = resman.request::<Image>("../assets/Egg_item.png")
|
||||
.unwrap();
|
||||
let image = resman.request::<Image>("../assets/Egg_item.png").unwrap();
|
||||
image.wait_recurse_dependencies_load();
|
||||
|
||||
drop(resman);
|
||||
|
@ -131,7 +148,7 @@ fn setup_scene_plugin(app: &mut App) {
|
|||
pivot: sprite::Pivot::Center,
|
||||
},
|
||||
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();
|
||||
camera.transform.translation += math::Vec3::new(0.0, 0.0, 5.5);
|
||||
world.spawn((camera, FreeFlyCamera::default()));
|
||||
world.spawn((
|
||||
CameraComponent {
|
||||
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