Compare commits
3 commits
5b791e53b2
...
ebad6bdd7d
Author | SHA1 | Date | |
---|---|---|---|
ebad6bdd7d | |||
|
45c0a31cb3 | ||
|
fe9099aac9 |
5 changed files with 176 additions and 71 deletions
|
@ -1,36 +1,110 @@
|
|||
use crate::prelude::*;
|
||||
use crate::prelude::{cgmath::*, *};
|
||||
use anyhow::Result;
|
||||
use context::prelude::cgmath::num_traits::clamp;
|
||||
|
||||
pub struct FreeCameraControl {}
|
||||
struct HoldInfo {
|
||||
roll: Deg<f32>,
|
||||
pitch: Deg<f32>,
|
||||
yaw: Deg<f32>,
|
||||
|
||||
impl Default for FreeCameraControl {
|
||||
fn default() -> Self {
|
||||
Self {}
|
||||
mouse_position: (u32, u32),
|
||||
}
|
||||
|
||||
impl<'a> From<&'a FreeCameraControl> for HoldInfo {
|
||||
fn from(value: &'a FreeCameraControl) -> Self {
|
||||
Self {
|
||||
roll: value.roll,
|
||||
pitch: value.pitch,
|
||||
yaw: value.yaw,
|
||||
|
||||
mouse_position: value.mouse_position,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FreeCameraControl {
|
||||
roll: Deg<f32>,
|
||||
pitch: Deg<f32>,
|
||||
yaw: Deg<f32>,
|
||||
|
||||
mouse_position: (u32, u32),
|
||||
|
||||
hold_info: Option<HoldInfo>,
|
||||
}
|
||||
|
||||
impl FreeCameraControl {
|
||||
pub fn roll(&mut self, view: &View) -> Result<()> {
|
||||
const SCALE: f32 = 0.3;
|
||||
const DEFAULT_DIR: Vector3<f32> = vec3(0.0, 1.0, 0.0);
|
||||
|
||||
pub fn new(view: &mut View) -> Result<Self> {
|
||||
view.camera_mut().look_at(false);
|
||||
view.camera_mut().set_eye_dir(Self::DEFAULT_DIR);
|
||||
view.update_buffer()?;
|
||||
|
||||
Ok(Self {
|
||||
roll: Deg(0.0),
|
||||
pitch: Deg(0.0),
|
||||
yaw: Deg(0.0),
|
||||
|
||||
mouse_position: (0, 0),
|
||||
|
||||
hold_info: None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn roll(&mut self, _view: &mut View) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn pitch(&mut self, _view: &mut View) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn yaw(&mut self, _view: &mut View) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn mouse_down(&mut self) {
|
||||
self.hold_info = Some((&*self).into());
|
||||
}
|
||||
|
||||
pub fn mouse_release(&mut self) {
|
||||
self.hold_info = None;
|
||||
}
|
||||
|
||||
pub fn mouse_move(&mut self, x: u32, y: u32, view: &mut View) -> Result<()> {
|
||||
self.mouse_position = (x, y);
|
||||
|
||||
if let Some(hold_info) = &self.hold_info {
|
||||
let x_diff = (hold_info.mouse_position.0 as i32 - x as i32) as f32 * Self::SCALE;
|
||||
let y_diff = (hold_info.mouse_position.1 as i32 - y as i32) as f32 * Self::SCALE;
|
||||
|
||||
self.yaw = Deg((hold_info.yaw.0 + x_diff) % 360.0);
|
||||
self.roll = Deg(clamp(hold_info.roll.0 + y_diff, -89.0, 89.0));
|
||||
|
||||
self.update_camera(view)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn pitch(&mut self, view: &View) -> Result<()> {
|
||||
Ok(())
|
||||
pub fn forward_back(&mut self, _view: &mut View) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn yaw(&mut self, view: &View) -> Result<()> {
|
||||
Ok(())
|
||||
pub fn left_right(&mut self, _view: &mut View) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn forward_back(&mut self, view: &View) -> Result<()> {
|
||||
Ok(())
|
||||
pub fn up_down(&mut self, _view: &mut View) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn left_right(&mut self, view: &View) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
fn update_camera(&self, view: &mut View) -> Result<()> {
|
||||
view.camera_mut().set_eye_dir(
|
||||
Matrix3::from_angle_z(self.yaw) * Matrix3::from_angle_x(self.roll) * Self::DEFAULT_DIR,
|
||||
);
|
||||
|
||||
pub fn up_down(&mut self, view: &View) -> Result<()> {
|
||||
Ok(())
|
||||
view.update_buffer()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
pub use super::camera::*;
|
||||
|
||||
pub use super::free_camera_control::*;
|
||||
pub use super::light::*;
|
||||
|
||||
pub use super::validcommandbuffer::*;
|
||||
|
||||
pub use super::view::*;
|
||||
|
||||
pub use super::top_down_camera_control::*;
|
||||
|
||||
pub use super::validcommandbuffer::*;
|
||||
pub use super::view::*;
|
||||
pub use super::view_frustum::*;
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
use std::{path::Path, time::Duration};
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use ecs::*;
|
||||
use engine::prelude::{
|
||||
cgmath::{Deg, Matrix3, Vector3, vec3},
|
||||
*,
|
||||
};
|
||||
use engine::prelude::*;
|
||||
use skybox::SkyBox;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
|
@ -33,12 +30,8 @@ fn main() -> Result<()> {
|
|||
)?;
|
||||
|
||||
let view = world_builder.resources.get_mut::<Scene>().view_mut();
|
||||
let camera = view.camera_mut();
|
||||
|
||||
camera.look_at(false);
|
||||
camera.set_center(vec3(0.0, 0.0, 0.0));
|
||||
camera.set_eye_dir(Vector3::unit_y());
|
||||
view.update_buffer()?;
|
||||
let camera_control = FreeCameraControl::new(view)?;
|
||||
world_builder.resources.insert(camera_control);
|
||||
|
||||
world_builder.build().run()
|
||||
}
|
||||
|
@ -56,7 +49,7 @@ impl GameState {
|
|||
let me = world.resources.get_mut_unchecked::<Self>();
|
||||
|
||||
match me {
|
||||
GameState::Startup => *me = GameState::Game(Game { start: world.now() }),
|
||||
GameState::Startup => *me = GameState::Game(Game),
|
||||
GameState::Game(game) => game.update(world)?,
|
||||
}
|
||||
|
||||
|
@ -75,28 +68,34 @@ impl EventConsumer for GameState {
|
|||
}
|
||||
}
|
||||
|
||||
struct Game {
|
||||
start: Duration,
|
||||
}
|
||||
struct Game;
|
||||
|
||||
impl Game {
|
||||
fn update(&mut self, world: &mut World) -> Result<()> {
|
||||
let now = world.now();
|
||||
let view = world.resources.get_mut::<Scene>().view_mut();
|
||||
let camera = view.camera_mut();
|
||||
|
||||
let diff = now.as_secs_f32() - self.start.as_secs_f32();
|
||||
camera.set_eye_dir(
|
||||
Matrix3::from_angle_z(Deg(diff * 36.0))
|
||||
* Matrix3::from_angle_x(Deg(diff.sin() * 30.0))
|
||||
* Vector3::unit_y(),
|
||||
);
|
||||
view.update_buffer()?;
|
||||
|
||||
fn update(&mut self, _world: &mut World) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn event(&mut self, _world: &mut World, _event: EngineEvent<'_>) -> Result<()> {
|
||||
fn event(&mut self, world: &mut World, event: EngineEvent<'_>) -> Result<()> {
|
||||
match event {
|
||||
EngineEvent::MouseButtonDown(MouseButton::Left) => {
|
||||
let camera_control = world.resources.get_mut::<FreeCameraControl>();
|
||||
camera_control.mouse_down();
|
||||
}
|
||||
EngineEvent::MouseButtonUp(MouseButton::Left) => {
|
||||
let camera_control = world.resources.get_mut::<FreeCameraControl>();
|
||||
camera_control.mouse_release();
|
||||
}
|
||||
EngineEvent::MouseMotion(x, y) => {
|
||||
let mut resources = world.resources.multi_mut();
|
||||
let scene = resources.get::<Scene>();
|
||||
let camera_control = resources.get::<FreeCameraControl>();
|
||||
|
||||
camera_control.mouse_move(x, y, scene.view_mut())?;
|
||||
}
|
||||
|
||||
_ => (),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,49 @@
|
|||
use engine::prelude::{cgmath::*, *};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CubeCorners(pub [PositionOnly; 8]);
|
||||
|
||||
impl CubeCorners {
|
||||
#[rustfmt::skip]
|
||||
pub fn new(offset: Vector3<f32>, extent: Vector3<f32>) -> Self {
|
||||
Self([
|
||||
// 0 - left bottom front
|
||||
PositionOnly::new(vec3(offset.x, offset.y, offset.z)),
|
||||
PositionOnly::new(vec3(
|
||||
offset.x,
|
||||
offset.y,
|
||||
offset.z
|
||||
)),
|
||||
// 1 - right bottom front
|
||||
PositionOnly::new(vec3(offset.x + extent.x, offset.y, offset.z)),
|
||||
PositionOnly::new(vec3(
|
||||
offset.x + extent.x,
|
||||
offset.y,
|
||||
offset.z
|
||||
)),
|
||||
// 2 - right top front
|
||||
PositionOnly::new(vec3(offset.x + extent.x, offset.y + extent.y, offset.z)),
|
||||
PositionOnly::new(vec3(
|
||||
offset.x + extent.x,
|
||||
offset.y + extent.y,
|
||||
offset.z
|
||||
)),
|
||||
// 3 - left top front
|
||||
PositionOnly::new(vec3(offset.x, offset.y + extent.y, offset.z)),
|
||||
PositionOnly::new(vec3(
|
||||
offset.x,
|
||||
offset.y + extent.y,
|
||||
offset.z
|
||||
)),
|
||||
|
||||
// 4 - left bottom back
|
||||
PositionOnly::new(vec3(offset.x, offset.y, offset.z + extent.z)),
|
||||
PositionOnly::new(vec3(
|
||||
offset.x,
|
||||
offset.y,
|
||||
offset.z + extent.z
|
||||
)),
|
||||
// 5 - right bottom back
|
||||
PositionOnly::new(vec3(offset.x + extent.x, offset.y, offset.z + extent.z)),
|
||||
PositionOnly::new(vec3(
|
||||
offset.x + extent.x,
|
||||
offset.y,
|
||||
offset.z + extent.z
|
||||
)),
|
||||
// 6 - right top back
|
||||
PositionOnly::new(vec3(
|
||||
offset.x + extent.x,
|
||||
|
@ -24,11 +51,16 @@ impl CubeCorners {
|
|||
offset.z + extent.z,
|
||||
)),
|
||||
// 7 - left top back
|
||||
PositionOnly::new(vec3(offset.x, offset.y + extent.y, offset.z + extent.z)),
|
||||
PositionOnly::new(vec3(
|
||||
offset.x,
|
||||
offset.y + extent.y,
|
||||
offset.z + extent.z
|
||||
)),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Plane([PositionOnly; 4]);
|
||||
|
||||
impl Plane {
|
||||
|
@ -45,9 +77,10 @@ impl<'a> From<(&'a CubeCorners, usize, usize, usize, usize)> for Plane {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Cube {
|
||||
pub left: Plane,
|
||||
pub right: Plane,
|
||||
pub left: Plane,
|
||||
pub front: Plane,
|
||||
pub back: Plane,
|
||||
pub top: Plane,
|
||||
|
@ -57,9 +90,9 @@ pub struct Cube {
|
|||
impl Cube {
|
||||
pub fn triangulate(self) -> [PositionOnly; 36] {
|
||||
[
|
||||
self.front.triangulate(),
|
||||
self.left.triangulate(),
|
||||
self.right.triangulate(),
|
||||
self.left.triangulate(),
|
||||
self.front.triangulate(),
|
||||
self.back.triangulate(),
|
||||
self.top.triangulate(),
|
||||
self.bottom.triangulate(),
|
||||
|
@ -73,8 +106,8 @@ impl Cube {
|
|||
impl From<CubeCorners> for Cube {
|
||||
fn from(corners: CubeCorners) -> Self {
|
||||
Self {
|
||||
left: Plane::from((&corners, 0, 3, 4, 7)),
|
||||
right: Plane::from((&corners, 2, 1, 6, 5)),
|
||||
right: Plane::from((&corners, 1, 2, 6, 5)),
|
||||
left: Plane::from((&corners, 3, 0, 4, 7)),
|
||||
front: Plane::from((&corners, 0, 1, 2, 3)),
|
||||
back: Plane::from((&corners, 5, 4, 7, 6)),
|
||||
top: Plane::from((&corners, 3, 2, 6, 7)),
|
||||
|
|
|
@ -59,14 +59,17 @@ impl SkyBox {
|
|||
let images = images.into();
|
||||
let cube_map = Image::cube_map([
|
||||
(
|
||||
images.front.try_into()?,
|
||||
vec![ImageModifier::Rotate90, ImageModifier::FlipH],
|
||||
images.right.try_into()?,
|
||||
vec![ImageModifier::FlipV, ImageModifier::Rotate90],
|
||||
),
|
||||
(images.left.try_into()?, vec![ImageModifier::Rotate90]),
|
||||
(images.right.try_into()?, vec![ImageModifier::Rotate270]),
|
||||
(
|
||||
images.left.try_into()?,
|
||||
vec![ImageModifier::Rotate90, ImageModifier::FlipV],
|
||||
),
|
||||
(images.front.try_into()?, vec![ImageModifier::FlipV]),
|
||||
(images.back.try_into()?, vec![ImageModifier::FlipH]),
|
||||
(images.top.try_into()?, vec![ImageModifier::None]),
|
||||
(images.bottom.try_into()?, vec![ImageModifier::None]),
|
||||
(images.top.try_into()?, vec![ImageModifier::FlipV]),
|
||||
(images.bottom.try_into()?, vec![ImageModifier::FlipH]),
|
||||
])?
|
||||
.format(VK_FORMAT_R8G8B8A8_UNORM)
|
||||
.max_mip_map_levels()
|
||||
|
|
Loading…
Reference in a new issue