Create simple keyboard controlled free fly camera
ci/woodpecker/push/build Pipeline was successful
Details
ci/woodpecker/push/build Pipeline was successful
Details
This commit is contained in:
parent
4191a463f5
commit
249b87afed
|
@ -2313,6 +2313,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"async-std",
|
||||
"edict",
|
||||
"fps_counter",
|
||||
"lyra-engine",
|
||||
"tracing",
|
||||
|
|
|
@ -11,5 +11,6 @@ anyhow = "1.0.75"
|
|||
async-std = "1.12.0"
|
||||
tracing = "0.1.37"
|
||||
fps_counter = "2.0.0"
|
||||
edict = "0.5.0"
|
||||
|
||||
[workspace]
|
||||
[workspace]
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use edict::{World, Component};
|
||||
use lyra_engine::{math::{Vec3, Angle, Quat}, input::{InputButtons, KeyCode, MouseMotion}, ecs::{SimpleSystem, components::camera::CameraComponent, EventQueue}, game::Game, plugin::Plugin};
|
||||
use tracing::debug;
|
||||
|
||||
#[derive(Clone, Component)]
|
||||
pub struct FreeFlyCamera {
|
||||
pub speed: f32,
|
||||
pub look_speed: f32,
|
||||
pub look_with_keys: bool
|
||||
}
|
||||
|
||||
impl Default for FreeFlyCamera {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
speed: 0.07,
|
||||
look_speed: 0.01,
|
||||
look_with_keys: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FreeFlyCamera {
|
||||
pub fn new(speed: f32, look_speed: f32, look_with_keys: bool) -> Self {
|
||||
Self {
|
||||
speed,
|
||||
look_speed,
|
||||
look_with_keys
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FreeFlyCameraController;
|
||||
|
||||
impl SimpleSystem for FreeFlyCameraController {
|
||||
fn execute_mut(&mut self, world: &mut World) -> anyhow::Result<()> {
|
||||
let mut camera_rot = Vec3::default();
|
||||
|
||||
let keys = world.get_resource::<InputButtons<KeyCode>>()
|
||||
.map(|r| r.deref().clone());
|
||||
if keys.is_none() {
|
||||
return Ok(());
|
||||
}
|
||||
let keys = keys.unwrap();
|
||||
|
||||
if keys.is_pressed(KeyCode::Left) {
|
||||
camera_rot.y += 1.0;
|
||||
}
|
||||
|
||||
if keys.is_pressed(KeyCode::Right) {
|
||||
camera_rot.y -= 1.0;
|
||||
}
|
||||
|
||||
if keys.is_pressed(KeyCode::Up) {
|
||||
camera_rot.x += 1.0;
|
||||
}
|
||||
|
||||
if keys.is_pressed(KeyCode::Down) {
|
||||
camera_rot.x -= 1.0;
|
||||
}
|
||||
|
||||
if keys.is_pressed(KeyCode::E) {
|
||||
camera_rot.z -= 1.0;
|
||||
}
|
||||
|
||||
if keys.is_pressed(KeyCode::Q) {
|
||||
camera_rot.z += 1.0;
|
||||
}
|
||||
|
||||
let camera_rot = camera_rot.normalize();
|
||||
|
||||
for (cam, fly) in world.query_mut::<(&mut CameraComponent, &mut FreeFlyCamera)>().iter_mut() {
|
||||
let forward = cam.transform.forward();
|
||||
let left = cam.transform.left();
|
||||
let up = cam.transform.up();
|
||||
|
||||
let mut velocity = Vec3::ZERO;
|
||||
|
||||
if keys.is_pressed(KeyCode::A) {
|
||||
velocity -= left;
|
||||
}
|
||||
|
||||
if keys.is_pressed(KeyCode::D) {
|
||||
velocity += left;
|
||||
}
|
||||
|
||||
if keys.is_pressed(KeyCode::W) {
|
||||
velocity += forward;
|
||||
}
|
||||
|
||||
if keys.is_pressed(KeyCode::S) {
|
||||
velocity -= forward;
|
||||
}
|
||||
|
||||
if keys.is_pressed(KeyCode::C) {
|
||||
velocity += up;
|
||||
}
|
||||
|
||||
if keys.is_pressed(KeyCode::Z) {
|
||||
velocity -= up;
|
||||
}
|
||||
|
||||
if velocity != Vec3::ZERO {
|
||||
cam.transform.translation += velocity.normalize() * fly.speed;
|
||||
}
|
||||
|
||||
if !camera_rot.is_nan() {
|
||||
let look_velocity = camera_rot.normalize() * fly.look_speed;
|
||||
cam.transform.rotation *= Quat::from_rotation_x(look_velocity.x) * Quat::from_rotation_y(look_velocity.y) * Quat::from_rotation_z(look_velocity.z);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Plugin for FreeFlyCameraController {
|
||||
fn setup(&self, game: &mut Game) {
|
||||
game.with_system("free_fly_camera_controller", FreeFlyCameraController, &[]);
|
||||
}
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
use lyra_engine::{math, ecs::{World, components::{transform::TransformComponent, camera::CameraComponent, model::ModelComponent}, EventQueue}, math::Transform, input::{KeyCode, InputButtons, MouseMotion}, game::Game};
|
||||
|
||||
use lyra_engine::{math::{self, Vec3}, ecs::{World, components::{transform::TransformComponent, camera::CameraComponent, model::ModelComponent}, EventQueue, SimpleSystem, Component}, math::Transform, input::{KeyCode, InputButtons, MouseMotion}, game::Game, plugin::Plugin, render::window::{CursorGrabMode, WindowOptions}, change_tracker::Ct};
|
||||
use lyra_engine::assets::{ResourceManager, Model};
|
||||
|
||||
use tracing::debug;
|
||||
|
||||
mod free_fly_camera;
|
||||
use free_fly_camera::{FreeFlyCameraController, FreeFlyCamera};
|
||||
|
||||
/* pub const VERTICES: &[Vertex] = &[
|
||||
Vertex { position: [-0.0868241, 0.49240386, 0.0], tex_coords: [0.4131759, 0.00759614], }, // A
|
||||
Vertex { position: [-0.49513406, 0.06958647, 0.0], tex_coords: [0.0048659444, 0.43041354], }, // B
|
||||
|
@ -46,8 +48,8 @@ async fn main() {
|
|||
let mut camera = CameraComponent::new_3d();
|
||||
camera.transform.translation += math::Vec3::new(0.0, 0.0, 7.5);
|
||||
//camera.transform.rotate_y(Angle::Degrees(-25.0));
|
||||
camera.transform.rotate_z(math::Angle::Degrees(-90.0));
|
||||
world.spawn((camera,));
|
||||
//camera.transform.rotate_z(math::Angle::Degrees(-90.0));
|
||||
world.spawn(( camera, FreeFlyCamera::default() ));
|
||||
|
||||
Ok(())
|
||||
};
|
||||
|
@ -156,7 +158,7 @@ async fn main() {
|
|||
};
|
||||
|
||||
let jiggle_plugin = move |game: &mut Game| {
|
||||
game.with_system("jiggle", jiggle_system, &["input"]);
|
||||
//game.with_system("jiggle", jiggle_system, &["input"]);
|
||||
};
|
||||
|
||||
Game::initialize().await
|
||||
|
@ -164,5 +166,6 @@ async fn main() {
|
|||
.with_startup_system(setup_sys)
|
||||
//.with_plugin(fps_plugin)
|
||||
.with_plugin(jiggle_plugin)
|
||||
.with_plugin(FreeFlyCameraController)
|
||||
.run().await;
|
||||
}
|
||||
|
|
|
@ -139,6 +139,7 @@ pub struct CursorEnteredWindow;
|
|||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct CursorLeftWindow;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InputButtons<T: Clone + Hash + Eq + PartialEq + 'static> {
|
||||
// the u64 as the key is the hashed value of T. this makes it easier to
|
||||
// search for a button and see its state
|
||||
|
|
|
@ -56,7 +56,17 @@ impl Transform {
|
|||
|
||||
/// Get the forward vector of the Transform.
|
||||
pub fn forward(&self) -> Vec3 {
|
||||
self.rotation * ONE_V3
|
||||
(self.rotation * -Vec3::Z).normalize()
|
||||
}
|
||||
|
||||
/// Get the left vector of the Transform.
|
||||
pub fn left(&self) -> Vec3 {
|
||||
(self.rotation * Vec3::X).normalize()
|
||||
}
|
||||
|
||||
/// Get the up vector of the Transform.
|
||||
pub fn up(&self) -> Vec3 {
|
||||
(self.rotation * Vec3::Y).normalize()
|
||||
}
|
||||
|
||||
/// Rotate this transform using a Quaternion
|
||||
|
|
|
@ -66,13 +66,13 @@ impl RenderCamera {
|
|||
match camera.mode {
|
||||
CameraProjectionMode::Perspective => {
|
||||
let position = camera.transform.translation;
|
||||
let target = camera.transform.rotation * glam::Vec3::new(0.0, 0.0, -1.0);
|
||||
let target = target.normalize();
|
||||
let forward = camera.transform.forward();
|
||||
let up = camera.transform.up();
|
||||
|
||||
let view = glam::Mat4::look_to_rh(
|
||||
position,
|
||||
target,
|
||||
glam::Vec3::new(0.0, 1.0, 0.0)
|
||||
forward,
|
||||
up
|
||||
);
|
||||
|
||||
let proj = glam::Mat4::perspective_rh_gl(camera.fov.to_radians(), self.aspect, self.znear, self.zfar);
|
||||
|
|
Loading…
Reference in New Issue