Bam! Camera movement, pure jank implementation but on the right track

master
mitchellhansen 4 years ago
parent 189805dd13
commit 9c48da280c

@ -3,6 +3,7 @@ use winit::event::{MouseScrollDelta, VirtualKeyCode, ElementState};
use winit::dpi::{PhysicalPosition, LogicalPosition}; use winit::dpi::{PhysicalPosition, LogicalPosition};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use std::f32::consts::FRAC_PI_2; use std::f32::consts::FRAC_PI_2;
use crate::render::OPENGL_TO_WGPU_MATRIX;
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
pub struct Camera { pub struct Camera {
@ -28,8 +29,8 @@ impl Camera {
} }
} }
pub fn calc_matrix(&self) -> Matrix4<f32> { pub fn calc_matrix(&self, projection: cgmath::Matrix4<f32>) -> Matrix4<f32> {
Matrix4::look_at_dir( let mx_view = Matrix4::look_at_dir(
self.position, self.position,
Vector3::new( Vector3::new(
self.yaw.0.cos(), self.yaw.0.cos(),
@ -37,7 +38,9 @@ impl Camera {
self.yaw.0.sin(), self.yaw.0.sin(),
).normalize(), ).normalize(),
Vector3::unit_y(), Vector3::unit_y(),
) );
let mx_correction = OPENGL_TO_WGPU_MATRIX;
mx_correction * projection * mx_view
} }
} }
@ -123,10 +126,7 @@ impl CameraController {
}; };
} }
pub fn update_camera(&mut self, camera: &mut Camera, dt: Duration) { pub fn update_camera(&mut self, camera: &mut Camera, dt: f32) {
let dt = dt.as_secs_f32();
// Move forward/backward and left/right // Move forward/backward and left/right
let (yaw_sin, yaw_cos) = camera.yaw.0.sin_cos(); let (yaw_sin, yaw_cos) = camera.yaw.0.sin_cos();

@ -3,8 +3,17 @@ use std::sync::Arc;
use rapier3d::dynamics::{RigidBody, RigidBodyHandle}; use rapier3d::dynamics::{RigidBody, RigidBodyHandle};
use rapier3d::geometry::ColliderHandle; use rapier3d::geometry::ColliderHandle;
use rapier3d::geometry::Collider as r3dCollider; use rapier3d::geometry::Collider as r3dCollider;
use std::time::{Duration, Instant};
// a component is any type that is 'static, sized, send and sync // a component is any type that is 'static, sized, send and sync
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct LoopState {
pub delta_time: Duration,
pub start_time: Instant,
pub step_size: f32,
}
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
pub struct Position { pub struct Position {
pub x: f32, pub x: f32,

@ -30,10 +30,10 @@ use winit::{
use gilrs::Event as GilEvent; use gilrs::Event as GilEvent;
use crate::camera::{CameraController, Camera}; use crate::camera::{CameraController, Camera};
use crate::components::{Collider, Color, Physics, Position}; use crate::components::{Collider, Color, Physics, Position, LoopState};
use crate::physics::PhysicsState; use crate::physics::PhysicsState;
use crate::render::Renderer; use crate::render::Renderer;
use crate::owned_event::TrEventExtension; use crate::owned_event::{OwnedEventExtension, OwnedEvent};
use gilrs::{Gamepad, Gilrs}; use gilrs::{Gamepad, Gilrs};
use rapier3d::counters::Timer; use rapier3d::counters::Timer;
@ -85,12 +85,10 @@ fn main() {
(local_pool, spawner) (local_pool, spawner)
}; };
// Schedule for the render systen
let mut render_schedule = Schedule::builder() let mut render_schedule = Schedule::builder()
.add_system(render::render_test_system()) .add_system(render::render_test_system())
.build(); .build();
// TODO schedule for the update system and others
let mut update_schedule = Schedule::builder() let mut update_schedule = Schedule::builder()
.add_system(physics::update_camera_system()) .add_system(physics::update_camera_system())
.add_system(physics::run_physics_system()) .add_system(physics::run_physics_system())
@ -98,7 +96,11 @@ fn main() {
// next system here, gamelogic update system? // next system here, gamelogic update system?
.build(); .build();
let event_loop = EventLoop::<TrEventExtension>::with_user_event(); let mut event_schedule = Schedule::builder()
.add_system(owned_event::event_dispatch_system())
.build();
let event_loop = EventLoop::<OwnedEventExtension>::with_user_event();
let mut builder = winit::window::WindowBuilder::new(); let mut builder = winit::window::WindowBuilder::new();
builder = builder.with_title("MVGE"); builder = builder.with_title("MVGE");
@ -126,10 +128,15 @@ fn main() {
resources.insert(physics_state); resources.insert(physics_state);
resources.insert(physics_pipeline); resources.insert(physics_pipeline);
resources.insert(CameraController::new(1.0, 1.0)); resources.insert(LoopState {
resources.insert(Instant::now()); delta_time: Default::default(),
start_time: Instant::now(),
step_size: 0.005,
});
resources.insert(Vec::<OwnedEvent<OwnedEventExtension>>::new());
let event_loop_proxy = event_loop.create_proxy(); let event_loop_proxy = event_loop.create_proxy();
std::thread::spawn(move || { std::thread::spawn(move || {
@ -148,7 +155,7 @@ fn main() {
while let Some(GilEvent { id, event, time }) = gilrs.next_event() { while let Some(GilEvent { id, event, time }) = gilrs.next_event() {
println!("{:?} New event from {}: {:?}", time, id, event); println!("{:?} New event from {}: {:?}", time, id, event);
active_gamepad = Some(id); active_gamepad = Some(id);
event_loop_proxy.send_event(TrEventExtension::GamepadEvent { event_loop_proxy.send_event(OwnedEventExtension::GamepadEvent {
gil_event: GilEvent { id, event, time } gil_event: GilEvent { id, event, time }
}).ok(); }).ok();
} }
@ -164,19 +171,15 @@ fn main() {
} }
}); });
let step_size: f32 = 0.005;
let mut elapsed_time: f32 = { // deltatime since last frame let mut elapsed_time: f32 = { // deltatime since last frame
let last_frame = resources.get::<Instant>().unwrap(); let loop_state = resources.get::<LoopState>().unwrap();
last_frame.elapsed() loop_state.start_time.elapsed()
}.as_secs_f32(); }.as_secs_f32();
let mut delta_time: f32 = 0.0; let mut delta_time: f32 = 0.0;
let mut accumulator_time: f32 = 0.0; let mut accumulator_time: f32 = 0.0;
let mut current_time: f32 = elapsed_time; let mut current_time: f32 = elapsed_time;
event_loop.run(move |event, _, control_flow| { event_loop.run(move |event, _, control_flow| {
// Artificially slows the loop rate to 10 millis // Artificially slows the loop rate to 10 millis
// This is called after redraw events cleared // This is called after redraw events cleared
@ -184,12 +187,17 @@ fn main() {
*control_flow = ControlFlow::Poll; *control_flow = ControlFlow::Poll;
match event { match event {
event::Event::NewEvents(cause) => {
event_schedule.execute(&mut world, &mut resources);
resources.get_mut::<Vec<OwnedEvent<OwnedEventExtension>>>()
.unwrap().clear();
}
event::Event::MainEventsCleared => { event::Event::MainEventsCleared => {
elapsed_time = { // deltatime since last frame let (step_size, elapsed_time) = { // deltatime since last frame
let last_frame = resources.get::<Instant>().unwrap(); let loop_state = resources.get::<LoopState>().unwrap();
last_frame.elapsed() (loop_state.step_size, loop_state.start_time.elapsed().as_secs_f32())
}.as_secs_f32(); };
delta_time = elapsed_time - current_time; delta_time = elapsed_time - current_time;
current_time = elapsed_time; current_time = elapsed_time;
if delta_time > 0.02 { if delta_time > 0.02 {
@ -197,35 +205,15 @@ fn main() {
} }
accumulator_time += delta_time; accumulator_time += delta_time;
while ((accumulator_time - step_size) >= step_size) {
let dt = { // deltatime since last frame accumulator_time -= step_size;
let last_frame = resources.get::<Instant>().unwrap(); // ==== DELTA TIME LOCKED ====
last_frame.elapsed() update_schedule.execute(&mut world, &mut resources);
};
update_schedule.execute(&mut world, &mut resources);
// ask for a redraw every 20 millis
if dt > Duration::from_millis(20) {
} }
// update the world time here for next update // ==== FPS LOCKED ====
resources.insert(Instant::now());
render_schedule.execute(&mut world, &mut resources); render_schedule.execute(&mut world, &mut resources);
} }
event::Event::DeviceEvent {
event: MouseMotion { delta },
..
} => {
resources
.get_mut::<Renderer>()
.unwrap()
.cam_look_delta((delta.0, delta.1));
//swap_chain = device.create_swap_chain(&surface, &sc_desc);
}
// Resizing will queue a request_redraw // Resizing will queue a request_redraw
event::Event::WindowEvent { event::Event::WindowEvent {
event: WindowEvent::Resized(size), event: WindowEvent::Resized(size),
@ -239,51 +227,37 @@ fn main() {
.get_mut::<Renderer>() .get_mut::<Renderer>()
.unwrap() .unwrap()
.resize(width, height); .resize(width, height);
//swap_chain = device.create_swap_chain(&surface, &sc_desc);
} }
event::Event::WindowEvent { event, .. } => match event { event::Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
WindowEvent::KeyboardInput { *control_flow = ControlFlow::Exit
input: }
event::KeyboardInput {
virtual_keycode: Some(event::VirtualKeyCode::Escape),
state: event::ElementState::Pressed,
..
},
..
}
| WindowEvent::CloseRequested => {
*control_flow = ControlFlow::Exit;
}
_ => {
//renderer.update(event);
}
},
event::Event::RedrawRequested(_) => { event::Event::RedrawRequested(_) => {
// Call the render system // Call the render system
render_schedule.execute(&mut world, &mut resources); render_schedule.execute(&mut world, &mut resources);
} }
_ => {} _ => {}
} }
resources.get_mut::<Vec<OwnedEvent<OwnedEventExtension>>>()
.unwrap().push(event.into());
}); });
} }
pub fn entity_loading(world: &mut World, renderer: &mut Renderer) { pub fn entity_loading(world: &mut World, renderer: &mut Renderer) {
let monkey_mesh = renderer.load_mesh_to_buffer("./resources/monkey.obj"); let monkey_mesh = renderer.load_mesh_to_buffer("./resources/monkey.obj");
let camera_ent: Entity = world.push((
Camera {
// let camera_ent: Entity = world.push(( position: Point3 {
// Camera { x: 5.0,
// position: Point3 { y: 5.0,
// x: 5.0, z: 5.0
// y: 5.0, },
// z: 5.0 yaw: Rad(0.0),
// }, pitch: Rad(-75.0)
// yaw: Rad(45.0), },
// pitch: Rad(45.0) CameraController::new(1.0, 1.0),
// } ));
// ));
let light_entity: Entity = world.push(( let light_entity: Entity = world.push((
cgmath::Point3 { cgmath::Point3 {

@ -1,17 +1,25 @@
use winit::window::{WindowId, Theme};
use winit::event::{WindowEvent, DeviceId, DeviceEvent, KeyboardInput, ModifiersState, MouseScrollDelta, TouchPhase, ElementState, MouseButton, AxisId, Touch, StartCause, Event};
use winit::dpi::{PhysicalPosition, PhysicalSize};
use gilrs::Event as GilEvent;
use std::path::PathBuf; use std::path::PathBuf;
use gilrs::Event as GilEvent;
use legion::world::SubWorld;
use legion::*;
use winit::dpi::{PhysicalPosition, PhysicalSize};
use winit::event::DeviceEvent::MouseMotion;
use winit::event::{
AxisId, DeviceEvent, DeviceId, ElementState, Event, KeyboardInput, ModifiersState, MouseButton,
MouseScrollDelta, StartCause, Touch, TouchPhase, WindowEvent,
};
use winit::window::{Theme, WindowId};
use crate::camera::{Camera, CameraController};
#[derive(Clone)] #[derive(Clone)]
pub enum TrUIEvent<T> { pub enum OwnedUIEvent<T> {
UIEvent(T) UIEvent(T),
} }
#[derive(Clone)] #[derive(Clone)]
pub enum TrEventExtension { pub enum OwnedEventExtension {
/// Custom events here /// Custom events here
MouseHeldEvent {}, MouseHeldEvent {},
KeyHeldEvent {}, KeyHeldEvent {},
@ -21,8 +29,7 @@ pub enum TrEventExtension {
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum TrEvent<T> { pub enum OwnedEvent<T> {
/// Custom events here /// Custom events here
MouseHeldEvent {}, MouseHeldEvent {},
KeyHeldEvent {}, KeyHeldEvent {},
@ -34,7 +41,7 @@ pub enum TrEvent<T> {
NewEvents(StartCause), NewEvents(StartCause),
WindowEvent { WindowEvent {
window_id: WindowId, window_id: WindowId,
event: TrWindowEvent, event: OwnedWindowEvent,
}, },
DeviceEvent { DeviceEvent {
device_id: DeviceId, device_id: DeviceId,
@ -49,114 +56,127 @@ pub enum TrEvent<T> {
LoopDestroyed, LoopDestroyed,
} }
impl<T> From<Event<'_, T>> for OwnedEvent<T> {
impl<T> From<Event<'_, T>> for TrEvent<T> {
fn from(event: Event<T>) -> Self { fn from(event: Event<T>) -> Self {
match event { match event {
Event::NewEvents(cause) => { Event::NewEvents(cause) => OwnedEvent::NewEvents(cause),
TrEvent::NewEvents(cause) Event::WindowEvent {
}, window_id: window_id,
Event::WindowEvent { window_id: window_id, event: event } => { event: event,
TrEvent::WindowEvent { } => OwnedEvent::WindowEvent {
window_id: window_id, window_id: window_id,
event: match event { event: match event {
WindowEvent::AxisMotion { device_id, axis, value } => { WindowEvent::AxisMotion {
TrWindowEvent::AxisMotion { device_id, axis, value } device_id,
}, axis,
WindowEvent::Resized(physical_size) => { value,
TrWindowEvent::Resized(physical_size) } => OwnedWindowEvent::AxisMotion {
} device_id,
WindowEvent::Moved(physical_position) => { axis,
TrWindowEvent::Moved(physical_position) value,
} },
WindowEvent::CloseRequested => { WindowEvent::Resized(physical_size) => OwnedWindowEvent::Resized(physical_size),
TrWindowEvent::CloseRequested WindowEvent::Moved(physical_position) => {
} OwnedWindowEvent::Moved(physical_position)
WindowEvent::Destroyed => {
TrWindowEvent::Destroyed
}
WindowEvent::DroppedFile(path_buf) => {
TrWindowEvent::DroppedFile(path_buf)
}
WindowEvent::HoveredFile(path_buf) => {
TrWindowEvent::HoveredFile(path_buf)
}
WindowEvent::HoveredFileCancelled => {
TrWindowEvent::HoveredFileCancelled
}
WindowEvent::ReceivedCharacter(char) => {
TrWindowEvent::ReceivedCharacter(char)
}
WindowEvent::Focused(bool) => {
TrWindowEvent::Focused(bool)
}
WindowEvent::KeyboardInput { device_id: device_id, input: input, is_synthetic: is_synthetic } => {
TrWindowEvent::KeyboardInput { device_id, input, is_synthetic }
}
WindowEvent::ModifiersChanged(modifiers_state) => {
TrWindowEvent::ModifiersChanged(modifiers_state)
}
WindowEvent::CursorMoved { device_id: device_id, position: position, modifiers: modifiers } => {
TrWindowEvent::CursorMoved { device_id, position, modifiers }
}
WindowEvent::CursorEntered { device_id: device_id } => {
TrWindowEvent::CursorEntered { device_id }
}
WindowEvent::CursorLeft { device_id: device_id } => {
TrWindowEvent::CursorLeft { device_id }
}
WindowEvent::MouseWheel { device_id: device_id, delta: delta, phase: phase, modifiers: modifiers } => {
TrWindowEvent::MouseWheel { device_id, delta, phase, modifiers }
}
WindowEvent::MouseInput { device_id: device_id, state: state, button: button, modifiers: modifiers } => {
TrWindowEvent::MouseInput { device_id, state, button, modifiers }
}
WindowEvent::TouchpadPressure { device_id: device_id, pressure: pressure, stage: stage } => {
TrWindowEvent::TouchpadPressure { device_id, pressure, stage }
}
WindowEvent::Touch(touch) => {
TrWindowEvent::Touch(touch)
}
WindowEvent::ScaleFactorChanged { scale_factor: scale_factor, new_inner_size: new_inner_size } => {
TrWindowEvent::ScaleFactorChanged { scale_factor, new_inner_size: PhysicalSize { width: new_inner_size.width, height: new_inner_size.height } }
}
WindowEvent::ThemeChanged(theme) => {
TrWindowEvent::ThemeChanged(theme)
}
} }
} WindowEvent::CloseRequested => OwnedWindowEvent::CloseRequested,
} WindowEvent::Destroyed => OwnedWindowEvent::Destroyed,
Event::DeviceEvent { device_id: device_id, event: event } => { WindowEvent::DroppedFile(path_buf) => OwnedWindowEvent::DroppedFile(path_buf),
TrEvent::DeviceEvent { device_id, event } WindowEvent::HoveredFile(path_buf) => OwnedWindowEvent::HoveredFile(path_buf),
} WindowEvent::HoveredFileCancelled => OwnedWindowEvent::HoveredFileCancelled,
Event::UserEvent(user_event) => { WindowEvent::ReceivedCharacter(char) => {
TrEvent::UserEvent(user_event) OwnedWindowEvent::ReceivedCharacter(char)
} }
Event::Suspended => { WindowEvent::Focused(bool) => OwnedWindowEvent::Focused(bool),
TrEvent::Suspended WindowEvent::KeyboardInput {
} device_id: device_id,
Event::Resumed => { input: input,
TrEvent::Resumed is_synthetic: is_synthetic,
} } => OwnedWindowEvent::KeyboardInput {
Event::MainEventsCleared => { device_id,
TrEvent::MainEventsCleared input,
} is_synthetic,
Event::RedrawRequested(window_id) => { },
TrEvent::RedrawRequested(window_id) WindowEvent::ModifiersChanged(modifiers_state) => {
} OwnedWindowEvent::ModifiersChanged(modifiers_state)
Event::RedrawEventsCleared => { }
TrEvent::RedrawEventsCleared WindowEvent::CursorMoved {
} device_id: device_id,
Event::LoopDestroyed => { position: position,
TrEvent::LoopDestroyed modifiers: modifiers,
} } => OwnedWindowEvent::CursorMoved {
device_id,
position,
modifiers,
},
WindowEvent::CursorEntered {
device_id: device_id,
} => OwnedWindowEvent::CursorEntered { device_id },
WindowEvent::CursorLeft {
device_id: device_id,
} => OwnedWindowEvent::CursorLeft { device_id },
WindowEvent::MouseWheel {
device_id: device_id,
delta: delta,
phase: phase,
modifiers: modifiers,
} => OwnedWindowEvent::MouseWheel {
device_id,
delta,
phase,
modifiers,
},
WindowEvent::MouseInput {
device_id: device_id,
state: state,
button: button,
modifiers: modifiers,
} => OwnedWindowEvent::MouseInput {
device_id,
state,
button,
modifiers,
},
WindowEvent::TouchpadPressure {
device_id: device_id,
pressure: pressure,
stage: stage,
} => OwnedWindowEvent::TouchpadPressure {
device_id,
pressure,
stage,
},
WindowEvent::Touch(touch) => OwnedWindowEvent::Touch(touch),
WindowEvent::ScaleFactorChanged {
scale_factor: scale_factor,
new_inner_size: new_inner_size,
} => OwnedWindowEvent::ScaleFactorChanged {
scale_factor,
new_inner_size: PhysicalSize {
width: new_inner_size.width,
height: new_inner_size.height,
},
},
WindowEvent::ThemeChanged(theme) => OwnedWindowEvent::ThemeChanged(theme),
},
},
Event::DeviceEvent {
device_id: device_id,
event: event,
} => OwnedEvent::DeviceEvent { device_id, event },
Event::UserEvent(user_event) => OwnedEvent::UserEvent(user_event),
Event::Suspended => OwnedEvent::Suspended,
Event::Resumed => OwnedEvent::Resumed,
Event::MainEventsCleared => OwnedEvent::MainEventsCleared,
Event::RedrawRequested(window_id) => OwnedEvent::RedrawRequested(window_id),
Event::RedrawEventsCleared => OwnedEvent::RedrawEventsCleared,
Event::LoopDestroyed => OwnedEvent::LoopDestroyed,
} }
} }
} }
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum TrWindowEvent { pub enum OwnedWindowEvent {
Resized(PhysicalSize<u32>), Resized(PhysicalSize<u32>),
Moved(PhysicalPosition<i32>), Moved(PhysicalPosition<i32>),
CloseRequested, CloseRequested,
@ -178,8 +198,12 @@ pub enum TrWindowEvent {
#[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"] #[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"]
modifiers: ModifiersState, modifiers: ModifiersState,
}, },
CursorEntered { device_id: DeviceId }, CursorEntered {
CursorLeft { device_id: DeviceId }, device_id: DeviceId,
},
CursorLeft {
device_id: DeviceId,
},
MouseWheel { MouseWheel {
device_id: DeviceId, device_id: DeviceId,
delta: MouseScrollDelta, delta: MouseScrollDelta,
@ -210,4 +234,61 @@ pub enum TrWindowEvent {
new_inner_size: PhysicalSize<u32>, new_inner_size: PhysicalSize<u32>,
}, },
ThemeChanged(Theme), ThemeChanged(Theme),
} }
/// Because I am a glutton for punishment I am going to just do a mono-event-dispatch-magoooo
#[system]
#[write_component(Camera)]
#[write_component(CameraController)]
pub fn event_dispatch(
world: &mut SubWorld,
#[resource] event_stack: &mut Vec<OwnedEvent<OwnedEventExtension>>,
) {
use winit::event::Event::DeviceEvent;
for event in event_stack {
match event {
OwnedEvent::DeviceEvent {
event: MouseMotion { delta },
..
} => {
let mut query = <(&mut CameraController)>::query();
for (camera_controller) in query.iter_mut(world) {
camera_controller.process_mouse(delta.0, delta.1);
}
}
OwnedEvent::DeviceEvent { device_id, event } => {
match event {
winit::event::DeviceEvent::Key(keyboard_input) => {
let mut query = <(&mut CameraController)>::query();
for (camera_controller) in query.iter_mut(world) {
camera_controller.process_keyboard(
keyboard_input.virtual_keycode.unwrap(),
keyboard_input.state,
);
}
// match keyboard_input.virtual_keycode.unwrap() {
// VirtualKeyCode::A => {
// if keyboard_input.state == ElementState::Pressed {}
// }
// VirtualKeyCode::S => {
// if keyboard_input.state == ElementState::Pressed {}
// }
// VirtualKeyCode::P => {
// if keyboard_input.state == ElementState::Pressed {
// let data = world.write_resource::<VkProcessor>().read_compute_buffer(compute_buffer.clone());
// image::save_buffer(&Path::new("image.png"), data.as_slice(), (image_data.1).0, (image_data.1).1, image::RGBA(8));
// }
// }
// _ => ()
// }
}
_ => {}
}
}
_ => {}
}
}
}

@ -7,7 +7,7 @@ use legion::*;
use crate::render::{EntityUniforms, Renderer}; use crate::render::{EntityUniforms, Renderer};
use cgmath::Quaternion; use cgmath::Quaternion;
use crate::components::{Collider, Physics, Mesh, Position}; use crate::components::{Collider, Physics, Mesh, Position, LoopState};
use crate::camera::{CameraController, Camera}; use crate::camera::{CameraController, Camera};
use std::time::Instant; use std::time::Instant;
@ -83,16 +83,15 @@ pub fn run_physics(
#[system] #[system]
#[write_component(Camera)] #[write_component(Camera)]
#[write_component(CameraController)]
pub fn update_camera( pub fn update_camera(
world: &mut SubWorld, world: &mut SubWorld,
#[resource] camera_controller: &mut CameraController, #[resource] loop_state: &mut LoopState,
#[resource] last_frame: &mut Instant,
) { ) {
let mut query = <(&mut Camera)>::query(); let mut query = <(&mut Camera, &mut CameraController)>::query();
for (camera) in query.iter_mut(world) { for (mut camera, controller) in query.iter_mut(world) {
//camera.update_camera() controller.update_camera(&mut camera, loop_state.step_size)
} }
} }
#[system] #[system]

@ -3,14 +3,17 @@ use std::{iter, num::NonZeroU32, ops::Range, rc::Rc};
use bytemuck::__core::mem; use bytemuck::__core::mem;
use bytemuck::{Pod, Zeroable}; use bytemuck::{Pod, Zeroable};
use cgmath::{vec3, Decomposed, Deg, Euler, InnerSpace, Matrix4, Point3, Quaternion, Rotation3, Transform, Vector3, Rad}; use cgmath::{
vec3, Decomposed, Deg, Euler, InnerSpace, Matrix4, Point3, Quaternion, Rad, Rotation3,
Transform, Vector3,
};
use futures::executor::LocalPool; use futures::executor::LocalPool;
use legion::world::SubWorld; use legion::world::SubWorld;
use legion::*; use legion::*;
use rapier3d::parry::motion::RigidMotionComposition; use rapier3d::parry::motion::RigidMotionComposition;
use wgpu::util::DeviceExt; use wgpu::util::DeviceExt;
use wgpu::{ use wgpu::{
BindGroup, BindGroupLayout, Buffer, Device, Instance, Queue, Surface, SwapChain, BackendBit, BindGroup, BindGroupLayout, Buffer, Device, Instance, Queue, Surface, SwapChain,
SwapChainDescriptor, SwapChainFrame, TextureView, SwapChainDescriptor, SwapChainFrame, TextureView,
}; };
use winit::dpi::PhysicalSize; use winit::dpi::PhysicalSize;
@ -69,43 +72,14 @@ pub struct Pass {
uniform_buf: wgpu::Buffer, uniform_buf: wgpu::Buffer,
} }
pub struct Renderer {
swapchain: SwapChain,
swapchain_description: SwapChainDescriptor,
instance: Arc<Instance>,
device: Arc<Device>,
queue: Arc<Queue>,
size: PhysicalSize<u32>,
surface: Arc<Surface>,
lights_are_dirty: bool,
shadow_pass: Pass,
shadow_target_views: Vec<Arc<TextureView>>,
views_given: u32,
forward_pass: Pass,
forward_depth: wgpu::TextureView,
entity_bind_group_layout: BindGroupLayout,
light_uniform_buf: wgpu::Buffer,
camera_projection: Matrix4<f32>,
}
#[system] #[system]
#[write_component(Camera)]
#[write_component(Position)] #[write_component(Position)]
#[write_component(Point3<f32>)] #[write_component(Point3<f32>)]
#[write_component(Mesh)] #[write_component(Mesh)]
#[write_component(Color)] #[write_component(Color)]
#[write_component(DirectionalLight)] #[write_component(DirectionalLight)]
pub fn render_test( pub fn render_test(world: &mut SubWorld, #[resource] renderer: &mut Renderer) {
world: &mut SubWorld,
#[resource] renderer: &mut Renderer,
#[resource] camera_controller: &mut CameraController,
) {
let mut encoder = renderer let mut encoder = renderer
.device .device
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
@ -113,6 +87,17 @@ pub fn render_test(
let frame = renderer.get_current_frame(); let frame = renderer.get_current_frame();
let mut query = <(&mut Camera)>::query();
for (camera) in query.iter_mut(world) {
let matrix = camera.calc_matrix(renderer.camera_projection);
let mx_ref: &[f32; 16] = matrix.as_ref();
renderer.queue.write_buffer(
&renderer.forward_pass.uniform_buf,
0,
bytemuck::cast_slice(mx_ref),
);
}
let mut query = <(&mut Position, &mut Mesh, &mut Color)>::query(); let mut query = <(&mut Position, &mut Mesh, &mut Color)>::query();
let mut mesh_stack = Vec::new(); let mut mesh_stack = Vec::new();
@ -240,6 +225,31 @@ pub fn render_test(
renderer.queue.submit(iter::once(encoder.finish())); renderer.queue.submit(iter::once(encoder.finish()));
} }
pub struct Renderer {
swapchain: SwapChain,
swapchain_description: SwapChainDescriptor,
instance: Arc<Instance>,
device: Arc<Device>,
queue: Arc<Queue>,
size: PhysicalSize<u32>,
surface: Arc<Surface>,
lights_are_dirty: bool,
shadow_pass: Pass,
shadow_target_views: Vec<Arc<TextureView>>,
views_given: u32,
forward_pass: Pass,
forward_depth: wgpu::TextureView,
entity_bind_group_layout: BindGroupLayout,
light_uniform_buf: wgpu::Buffer,
camera_projection: Matrix4<f32>,
}
impl Renderer { impl Renderer {
const MAX_LIGHTS: usize = 10; const MAX_LIGHTS: usize = 10;
const SHADOW_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float; const SHADOW_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
@ -250,71 +260,21 @@ impl Renderer {
}; };
const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float; const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
pub fn generate_matrix(aspect_ratio: f32) -> cgmath::Matrix4<f32> { /// Generate a projection matrix with no look-at yet
pub fn generate_matrix(&self) -> cgmath::Matrix4<f32> {
// Specifies the aspect ratio that determines the field of view in the x direction. // Specifies the aspect ratio that determines the field of view in the x direction.
// The aspect ratio is the ratio of x (width) to y (height). // The aspect ratio is the ratio of x (width) to y (height).
let mx_projection = cgmath::perspective(cgmath::Deg(75f32), aspect_ratio, 1.0, 20.0); cgmath::perspective(
let mx_view = cgmath::Matrix4::look_at( cgmath::Deg(75f32),
cgmath::Point3::new(1.0f32, 1.0, 4.0), self.size.width as f32 / self.size.height as f32,
cgmath::Point3::new(0.0f32, 0.0, 0.0), 1.0,
cgmath::Vector3::unit_z(), 20.0,
); )
let mx_correction = OPENGL_TO_WGPU_MATRIX;
mx_correction * mx_projection * mx_view
}
pub fn cam_look_delta(&mut self, delta: (f64, f64)) {
// let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 20.0);
// let mx_view = cgmath::Matrix4::look_at(
// cgmath::Point3::new(3.0f32, -9.0, 6.0),
// cgmath::Point3::new(0f32, 0.0, 0.0),
// cgmath::Vector3::unit_z(),
// );
// let mx_correction = OPENGL_TO_WGPU_MATRIX;
// let mx_total = mx_correction * mx_projection * mx_view;
//
// let rotation = Quaternion::from(Euler {
// x: Deg(90.0),
// y: Deg(45.0),
// z: Deg(15.0),
// });
//
// Euler {
// x: (),
// y: (),
// z: ()
// };
//
// let offset = cgmath::vec3(1.0, 1.0, 4.0);
// let transform = Decomposed {
// disp: offset.clone(),
// rot: Quaternion::from_axis_angle(offset.normalize(), Deg(50.0)),
// scale: 1.0,
// };
//
// let mut q = Quaternion::from(self.camera_direction);
// q.v.z += delta.0 as f32;
// q.v.y += delta.1 as f32;
// //let q2 = Quaternion::from_angle_x(Deg(delta.0 as f32));
// //let q3 = Quaternion::from_angle_y(Deg(delta.1 as f32));
// let w = Matrix4::from(q);
// //mx_total = mx_total + w;
//
// self.camera_projection = transform.into();
// let mut mx_total = self.camera_projection.clone();
//
// let mx_ref: &[f32; 16] = mx_total.as_ref();
// self.queue.write_buffer(
// &self.forward_pass.uniform_buf,
// 0,
// bytemuck::cast_slice(mx_ref),
// );
} }
/// Get the next frame from the swapchain
/// (recreates if something funky goes on)
pub fn get_current_frame(&mut self) -> SwapChainFrame { pub fn get_current_frame(&mut self) -> SwapChainFrame {
// Update the renderers swapchain state
match self.swapchain.get_current_frame() { match self.swapchain.get_current_frame() {
Ok(frame) => frame, Ok(frame) => frame,
Err(_) => { Err(_) => {
@ -328,6 +288,8 @@ impl Renderer {
} }
} }
/// Create a bare vertex & indices buffer
/// TODO I really should remove this / consolidate it
pub fn create_buffer( pub fn create_buffer(
device: &wgpu::Device, device: &wgpu::Device,
indices: Vec<u32>, indices: Vec<u32>,
@ -352,6 +314,9 @@ impl Renderer {
(vertex_buf, index_buf) (vertex_buf, index_buf)
} }
/// When creating a light we have to give it a target view to render to
/// This is major danger scary since we have a 10 light limit, and only
/// 2 views created at this moment, need to smarten this up
pub fn create_light(&mut self) -> DirectionalLight { pub fn create_light(&mut self) -> DirectionalLight {
let target = self let target = self
.shadow_target_views .shadow_target_views
@ -375,6 +340,7 @@ impl Renderer {
} }
} }
/// I don't know why the hell this is still in here
pub fn create_plane(&self, size: f32) -> Mesh { pub fn create_plane(&self, size: f32) -> Mesh {
let vertices = [ let vertices = [
vertex([size, -size, 0.0], [0.0, 0.0, 1.0]), vertex([size, -size, 0.0], [0.0, 0.0, 1.0]),
@ -701,7 +667,12 @@ impl Renderer {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); let mx_projection = cgmath::perspective(
cgmath::Deg(75f32), // FOV, might wanna hook this up somewhere
sc_desc.width as f32 / sc_desc.height as f32,
1.0,
20.0,
);
let forward_pass = { let forward_pass = {
// Create pipeline layout // Create pipeline layout
@ -758,7 +729,7 @@ impl Renderer {
// I need to know the number of lights... // I need to know the number of lights...
let forward_uniforms = ForwardUniforms { let forward_uniforms = ForwardUniforms {
proj: *mx_total.as_ref(), proj: *mx_projection.as_ref(),
//num_lights: [lights.len() as u32, 0, 0, 0], //num_lights: [lights.len() as u32, 0, 0, 0],
num_lights: [2 as u32, 0, 0, 0], num_lights: [2 as u32, 0, 0, 0],
}; };
@ -883,7 +854,7 @@ impl Renderer {
surface, surface,
instance: Arc::new(instance), instance: Arc::new(instance),
views_given: 0, views_given: 0,
camera_projection: mx_total, camera_projection: mx_projection,
} }
} }
@ -903,7 +874,7 @@ impl Renderer {
.create_swap_chain(&self.surface, &self.swapchain_description.clone()); .create_swap_chain(&self.surface, &self.swapchain_description.clone());
// update view-projection matrix // update view-projection matrix
let mx_total = Self::generate_matrix(width as f32 / height as f32); let mx_total = self.generate_matrix();
let mx_ref: &[f32; 16] = mx_total.as_ref(); let mx_ref: &[f32; 16] = mx_total.as_ref();
self.queue.write_buffer( self.queue.write_buffer(
&self.forward_pass.uniform_buf, &self.forward_pass.uniform_buf,

Loading…
Cancel
Save