Fix most warnings and clippy lints
ci/woodpecker/push/build Pipeline was successful
Details
ci/woodpecker/push/build Pipeline was successful
Details
This commit is contained in:
parent
04d47c34bc
commit
63df35f8fc
|
@ -1,6 +1,5 @@
|
|||
use std::{sync::Arc, path::{Path, PathBuf}};
|
||||
use std::{sync::Arc, path::PathBuf};
|
||||
|
||||
use base64::Engine;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::{ResourceLoader, LoaderError, Mesh, Model, MeshVertexAttribute, VertexAttributeData, Resource, Material, MeshIndices, ResourceManager, util};
|
||||
|
@ -27,6 +26,7 @@ impl From<ModelLoaderError> for LoaderError {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) struct GltfLoadContext<'a> {
|
||||
pub resource_manager: &'a mut ResourceManager,
|
||||
pub gltf: &'a gltf::Gltf,
|
||||
|
@ -161,15 +161,15 @@ impl ResourceLoader for ModelLoader {
|
|||
let gltf = gltf::Gltf::open(path)?;
|
||||
|
||||
let mut use_bin = false;
|
||||
let buffers: Vec<Vec<u8>> = gltf.buffers().map(|b| match b.source() {
|
||||
let buffers: Vec<Vec<u8>> = gltf.buffers().flat_map(|b| match b.source() {
|
||||
gltf::buffer::Source::Bin => {
|
||||
use_bin = true;
|
||||
gltf.blob.as_deref().map(|v| v.to_vec())
|
||||
.ok_or(ModelLoaderError::MissingBin(path.to_string()))
|
||||
},
|
||||
gltf::buffer::Source::Uri(uri) => util::gltf_read_buffer_uri(&parent_path, uri)
|
||||
.map_err(|e| ModelLoaderError::UriDecodingError(e)),
|
||||
}).flatten().collect();
|
||||
.map_err(ModelLoaderError::UriDecodingError),
|
||||
}).collect();
|
||||
|
||||
// TODO: Read in multiple scenes
|
||||
let scene = gltf.scenes().next().unwrap();
|
||||
|
@ -186,13 +186,14 @@ impl ResourceLoader for ModelLoader {
|
|||
.map(|mat| Material::from_gltf(&mut context, mat)).collect();
|
||||
|
||||
let meshes: Vec<Mesh> = scene.nodes()
|
||||
.map(|node| self.process_node(&buffers, &materials, node))
|
||||
.flatten().collect();
|
||||
.flat_map(|node| self.process_node(&buffers, &materials, node))
|
||||
.collect();
|
||||
debug!("Loaded {} meshes, and {} materials from '{}'", meshes.len(), materials.len(), path);
|
||||
|
||||
Ok(Arc::new(Resource::with_data(path, Model::new(meshes))))
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn load_bytes(&self, resource_manager: &mut ResourceManager, bytes: Vec<u8>, offset: usize, length: usize) -> Result<Arc<dyn crate::ResourceStorage>, LoaderError> {
|
||||
todo!()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::{fs::File, io::{BufReader, Read}, collections::hash_map::DefaultHasher, hash::{Hash, Hasher}};
|
||||
use std::{collections::hash_map::DefaultHasher, hash::{Hash, Hasher}};
|
||||
|
||||
use crate::{Texture, ResHandle, ResourceManager, util, loader::model::GltfLoadContext};
|
||||
use crate::{Texture, ResHandle, util, loader::model::GltfLoadContext};
|
||||
|
||||
/// PBR metallic roughness
|
||||
#[derive(Clone, Debug, Default)]
|
||||
|
@ -128,6 +128,7 @@ pub struct Material {
|
|||
//pub texture: Option<ResHandle<Texture>>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl Material {
|
||||
/// Get a uri's identifier
|
||||
///
|
||||
|
@ -142,7 +143,7 @@ impl Material {
|
|||
|
||||
fn source_ident(gltf_rel_path: &str, src: &gltf::image::Source) -> Option<String> {
|
||||
match src {
|
||||
gltf::image::Source::View { view, mime_type } => {
|
||||
gltf::image::Source::View { view, mime_type: _ } => {
|
||||
let buf = view.buffer();
|
||||
let src = buf.source();
|
||||
|
||||
|
@ -153,7 +154,7 @@ impl Material {
|
|||
}
|
||||
}
|
||||
},
|
||||
gltf::image::Source::Uri { uri, mime_type } => {
|
||||
gltf::image::Source::Uri { uri, mime_type: _ } => {
|
||||
Some(Material::uri_ident(gltf_rel_path, uri))
|
||||
},
|
||||
}
|
||||
|
|
|
@ -17,6 +17,10 @@ impl MeshIndices {
|
|||
MeshIndices::U32(v) => v.len(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
}
|
||||
|
||||
/* impl From<Vec<u8>> for MeshIndices {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::{sync::Arc, collections::{HashMap, hash_map::DefaultHasher}, hash::{Hash, Hasher}, any::Any};
|
||||
use std::{sync::Arc, collections::HashMap, any::Any};
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
|
@ -51,11 +51,17 @@ pub struct ResourceManager {
|
|||
loaders: Vec<Arc<dyn ResourceLoader>>,
|
||||
}
|
||||
|
||||
impl Default for ResourceManager {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl ResourceManager {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
resources: HashMap::new(),
|
||||
loaders: vec![ Arc::new(ImageLoader::default()), Arc::new(ModelLoader::default()) ],
|
||||
loaders: vec![ Arc::new(ImageLoader), Arc::new(ModelLoader) ],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,7 +78,7 @@ impl ResourceManager {
|
|||
.find(|l| l.does_support_file(path)) {
|
||||
|
||||
// Load the resource and store it
|
||||
let loader = Arc::clone(&loader); // stop borrowing from self
|
||||
let loader = Arc::clone(loader); // stop borrowing from self
|
||||
let res = loader.load(self, path)?;
|
||||
self.resources.insert(path.to_string(), res.clone());
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use image::{DynamicImage, ImageResult, ImageBuffer, Rgba};
|
||||
use image::DynamicImage;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Texture {
|
||||
|
|
|
@ -2,6 +2,7 @@ use base64::Engine;
|
|||
use thiserror::Error;
|
||||
use std::io;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Error, Debug)]
|
||||
pub enum UriReadError {
|
||||
#[error("IOError: '{0}'")]
|
||||
|
@ -22,7 +23,7 @@ pub enum UriReadError {
|
|||
/// i.e. parent="resources/models/player.gltf", containing="resource/models"
|
||||
pub(crate) fn gltf_read_buffer_uri(containing_path: &str, uri: &str) -> Result<Vec<u8>, UriReadError> {
|
||||
if let Some((mime, data)) = uri.strip_prefix("data")
|
||||
.and_then(|uri| uri.split_once(",")) {
|
||||
.and_then(|uri| uri.split_once(',')) {
|
||||
let (_mime, is_base64) = match mime.strip_suffix(";base64") {
|
||||
Some(mime) => (mime, true),
|
||||
None => (mime, false),
|
||||
|
@ -30,12 +31,12 @@ pub(crate) fn gltf_read_buffer_uri(containing_path: &str, uri: &str) -> Result<V
|
|||
|
||||
if is_base64 {
|
||||
base64::engine::general_purpose::STANDARD.decode(data)
|
||||
.map_err(|e| UriReadError::Base64Decode(e))
|
||||
.map_err(UriReadError::Base64Decode)
|
||||
} else {
|
||||
Ok(data.as_bytes().to_vec())
|
||||
}
|
||||
} else {
|
||||
let full_path = format!("{containing_path}/{uri}");
|
||||
std::fs::read(&full_path).map_err(|e| UriReadError::IoError(e))
|
||||
std::fs::read(full_path).map_err(UriReadError::IoError)
|
||||
}
|
||||
}
|
|
@ -25,8 +25,9 @@ impl CameraComponent {
|
|||
}
|
||||
|
||||
pub fn new_2d() -> Self {
|
||||
let mut s = Self::default();
|
||||
s.mode = CameraProjectionMode::Orthographic;
|
||||
s
|
||||
CameraComponent {
|
||||
mode: CameraProjectionMode::Orthographic,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,19 +2,11 @@ use edict::Component;
|
|||
|
||||
use crate::math::Transform;
|
||||
|
||||
#[derive(Clone, Component)]
|
||||
#[derive(Clone, Component, Default)]
|
||||
pub struct TransformComponent {
|
||||
pub transform: Transform,
|
||||
}
|
||||
|
||||
impl Default for TransformComponent {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
transform: Transform::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Transform> for TransformComponent {
|
||||
fn from(transform: Transform) -> Self {
|
||||
Self {
|
||||
|
|
|
@ -12,6 +12,12 @@ pub struct EventQueue {
|
|||
event_write_queue: HashMap<TypeId, RefCell<Box<dyn CastableAny>>>
|
||||
}
|
||||
|
||||
impl Default for EventQueue {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl EventQueue {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
@ -26,7 +32,7 @@ impl EventQueue {
|
|||
E: Event
|
||||
{
|
||||
// the compiler wants me to explicit right here for some reason
|
||||
let default = || RefCell::new(Box::new(Events::<E>::new()) as Box<dyn CastableAny>);
|
||||
let default = || RefCell::new(Box::<Events::<E>>::default() as Box<dyn CastableAny>);
|
||||
|
||||
// Get, or create, a list of events of this type
|
||||
let type_id = event.type_id();
|
||||
|
@ -45,7 +51,7 @@ impl EventQueue {
|
|||
self.events.clear();
|
||||
|
||||
// get all keys of events
|
||||
let keys: Vec<TypeId> = self.event_write_queue.keys().map(|k| k.clone()).collect();
|
||||
let keys: Vec<TypeId> = self.event_write_queue.keys().copied().collect();
|
||||
|
||||
// remove all elements from self.event_write_queue and insert them to events
|
||||
for k in keys.into_iter() {
|
||||
|
|
|
@ -11,7 +11,7 @@ use tracing::warn;
|
|||
|
||||
/// A trait that represents a simple system
|
||||
pub trait SimpleSystem {
|
||||
fn setup(&mut self, world: &mut World) -> anyhow::Result<()> {
|
||||
fn setup(&mut self, _world: &mut World) -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,8 @@ impl SimpleSystem for BatchedSystem {
|
|||
|
||||
struct SystemGraphNode {
|
||||
name: String,
|
||||
dependent_on: Vec<String>,
|
||||
#[allow(dead_code)]
|
||||
dependent_on: Vec<String>, // TODO
|
||||
system: Box<dyn SimpleSystem>,
|
||||
}
|
||||
|
||||
|
@ -114,7 +115,7 @@ impl SystemDispatcher {
|
|||
.get(&depend)
|
||||
.expect("Dependency not found!");
|
||||
|
||||
self.graph.add_edge(idx.clone(), added_index, SystemGraphEdge { });
|
||||
self.graph.add_edge(*idx, added_index, SystemGraphEdge { });
|
||||
}
|
||||
|
||||
true
|
||||
|
|
45
src/game.rs
45
src/game.rs
|
@ -1,20 +1,18 @@
|
|||
use std::{sync::Arc, collections::VecDeque};
|
||||
|
||||
use async_std::{task::block_on, sync::Mutex};
|
||||
use async_std::task::block_on;
|
||||
|
||||
//use hecs::World;
|
||||
use instant::Instant;
|
||||
use tracing::{metadata::LevelFilter, info, debug, warn, error, Level};
|
||||
use tracing::{info, error, Level};
|
||||
use tracing_appender::non_blocking;
|
||||
use tracing_subscriber::{
|
||||
layer::{Layer, SubscriberExt},
|
||||
filter::{FilterFn, self},
|
||||
layer::SubscriberExt,
|
||||
filter,
|
||||
util::SubscriberInitExt, fmt,
|
||||
};
|
||||
|
||||
use winit::{window::{WindowBuilder, Window}, event::{Event, WindowEvent, KeyboardInput, ElementState, VirtualKeyCode, DeviceEvent}, event_loop::{EventLoop, ControlFlow}};
|
||||
|
||||
use crate::{render::renderer::{Renderer, BasicRenderer}, input_event::InputEvent, ecs::{SimpleSystem, SystemDispatcher, EventQueue, Events}, input::InputSystem, plugin::Plugin};
|
||||
use crate::{render::renderer::{Renderer, BasicRenderer}, input_event::InputEvent, ecs::{SimpleSystem, SystemDispatcher, EventQueue, Events}, plugin::Plugin};
|
||||
|
||||
pub struct Controls<'a> {
|
||||
pub world: &'a mut edict::World,
|
||||
|
@ -95,14 +93,14 @@ impl GameLoop {
|
|||
|
||||
// TODO: Create system for this? or maybe merge into input system, idk
|
||||
InputEvent::CursorEntered { .. } => {
|
||||
let mut state = self.world.with_resource(|| WindowState::new());
|
||||
let state = self.world.with_resource(WindowState::new);
|
||||
state.is_cursor_inside_window = true;
|
||||
|
||||
None
|
||||
},
|
||||
|
||||
InputEvent::CursorLeft { .. } => {
|
||||
let mut state = self.world.with_resource(|| WindowState::new());
|
||||
let state = self.world.with_resource(WindowState::new);
|
||||
state.is_cursor_inside_window = false;
|
||||
|
||||
None
|
||||
|
@ -123,23 +121,18 @@ impl GameLoop {
|
|||
pub async fn run_event_loop(&mut self, event: Event<'_, ()>, control_flow: &mut ControlFlow) {
|
||||
*control_flow = ControlFlow::Poll;
|
||||
match event {
|
||||
Event::DeviceEvent { device_id, event } => match event {
|
||||
Event::DeviceEvent { device_id, event: DeviceEvent::MouseMotion { delta } } => {
|
||||
// convert a MouseMotion event to an InputEvent
|
||||
DeviceEvent::MouseMotion { delta } => {
|
||||
// make sure that the mouse is inside the window and the mouse has focus before reporting mouse motion
|
||||
let trigger = match self.world.get_resource::<WindowState>() {
|
||||
Some(window_state) if window_state.is_focused && window_state.is_cursor_inside_window => true,
|
||||
_ => false,
|
||||
};
|
||||
// make sure that the mouse is inside the window and the mouse has focus before reporting mouse motion
|
||||
let trigger = matches!(self.world.get_resource::<WindowState>(), Some(window_state)
|
||||
if window_state.is_focused && window_state.is_cursor_inside_window);
|
||||
|
||||
if trigger {
|
||||
let event_queue = self.world.with_resource(|| Events::<InputEvent>::new());
|
||||
|
||||
let input_event = InputEvent::MouseMotion { device_id, delta, };
|
||||
event_queue.push_back(input_event);
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
if trigger {
|
||||
let event_queue = self.world.with_resource(Events::<InputEvent>::new);
|
||||
|
||||
let input_event = InputEvent::MouseMotion { device_id, delta, };
|
||||
event_queue.push_back(input_event);
|
||||
}
|
||||
},
|
||||
Event::WindowEvent {
|
||||
ref event,
|
||||
|
@ -177,7 +170,7 @@ impl GameLoop {
|
|||
},
|
||||
|
||||
WindowEvent::Focused(is_focused) => {
|
||||
let mut state = self.world.with_resource(|| WindowState::new());
|
||||
let state = self.world.with_resource(WindowState::new);
|
||||
state.is_focused = *is_focused;
|
||||
},
|
||||
|
||||
|
@ -306,7 +299,7 @@ impl Game {
|
|||
plugin.as_ref().setup(self);
|
||||
}
|
||||
|
||||
let mut world = self.world.take().unwrap_or_else(|| edict::World::new());
|
||||
let mut world = self.world.take().unwrap_or_default();
|
||||
|
||||
// run startup systems
|
||||
while let Some(mut startup) = self.startup_systems.pop_front() {
|
||||
|
|
40
src/input.rs
40
src/input.rs
|
@ -1,11 +1,10 @@
|
|||
use std::{collections::{HashMap, hash_map::DefaultHasher}, hash::{Hash, Hasher}, sync::{Arc, Mutex}};
|
||||
use std::{collections::{HashMap, hash_map::DefaultHasher}, hash::{Hash, Hasher}};
|
||||
|
||||
use gilrs_core::Gilrs;
|
||||
use glam::Vec2;
|
||||
use tracing::{warn, debug};
|
||||
use winit::{event::{ElementState, MouseScrollDelta}, window::{Window, CursorGrabMode}, dpi::PhysicalPosition};
|
||||
use tracing::debug;
|
||||
use winit::event::{ElementState, MouseScrollDelta};
|
||||
|
||||
use crate::{ecs::{SimpleSystem, EventQueue}, input_event::InputEvent, plugin::Plugin, render::window::WindowOptions, change_tracker::Ct};
|
||||
use crate::{ecs::{SimpleSystem, EventQueue}, input_event::InputEvent, plugin::Plugin,};
|
||||
|
||||
pub type KeyCode = winit::event::VirtualKeyCode;
|
||||
|
||||
|
@ -98,6 +97,12 @@ pub struct Touches {
|
|||
pub touches: Vec<Touch>,
|
||||
}
|
||||
|
||||
impl Default for Touches {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Touches {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
@ -140,6 +145,12 @@ pub struct InputButtons<T: Clone + Hash + Eq + PartialEq + 'static> {
|
|||
button_events: HashMap<u64, ButtonEvent<T>>,
|
||||
}
|
||||
|
||||
impl<T: Clone + Hash + Eq + PartialEq + 'static> Default for InputButtons<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + Hash + Eq + PartialEq + 'static> InputButtons<T> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
|
@ -236,7 +247,7 @@ impl InputSystem {
|
|||
InputEvent::KeyboardInput { input, .. } => {
|
||||
if let Some(code) = input.virtual_keycode {
|
||||
drop(event_queue);
|
||||
let e = world.with_resource(|| InputButtons::<KeyCode>::new());
|
||||
let e = world.with_resource(InputButtons::<KeyCode>::new);
|
||||
//let mut e = with_resource_mut(world, || InputButtons::<KeyCode>::new());
|
||||
e.add_input_from_winit(code, input.state);
|
||||
}
|
||||
|
@ -285,11 +296,11 @@ impl InputSystem {
|
|||
winit::event::MouseButton::Other(v) => MouseButton::Other(*v),
|
||||
};
|
||||
|
||||
event_queue.trigger_event(button_event.clone());
|
||||
event_queue.trigger_event(button_event);
|
||||
drop(event_queue);
|
||||
|
||||
let e = world.with_resource(|| InputButtons::<MouseButton>::new());
|
||||
e.add_input_from_winit(button_event, state.clone());
|
||||
let e = world.with_resource(InputButtons::<MouseButton>::new);
|
||||
e.add_input_from_winit(button_event, *state);
|
||||
},
|
||||
InputEvent::Touch(t) => {
|
||||
drop(event_queue);
|
||||
|
@ -297,14 +308,11 @@ impl InputSystem {
|
|||
let touch = Touch {
|
||||
phase: TouchPhase::from(t.phase),
|
||||
location: Vec2::new(t.location.x as f32, t.location.y as f32),
|
||||
force: match t.force {
|
||||
Some(f) => Some(Force::from(f)),
|
||||
None => None,
|
||||
},
|
||||
force: t.force.map(Force::from),
|
||||
finger_id: t.id,
|
||||
};
|
||||
|
||||
let touches = world.with_resource(|| Touches::new());
|
||||
let touches = world.with_resource(Touches::new);
|
||||
touches.touches.push(touch);
|
||||
},
|
||||
_ => {},
|
||||
|
@ -317,7 +325,7 @@ impl InputSystem {
|
|||
impl SimpleSystem for InputSystem {
|
||||
fn execute_mut(&mut self, world: &mut edict::World) -> anyhow::Result<()> {
|
||||
let queue = world.get_resource_mut::<EventQueue>()
|
||||
.map(|q| q.read_events::<InputEvent>()).flatten();
|
||||
.and_then(|q| q.read_events::<InputEvent>());
|
||||
|
||||
if queue.is_none() {
|
||||
return Ok(());
|
||||
|
@ -339,6 +347,6 @@ pub struct InputPlugin;
|
|||
|
||||
impl Plugin for InputPlugin {
|
||||
fn setup(&self, game: &mut crate::game::Game) {
|
||||
game.with_system("input", InputSystem::default(), &[]);
|
||||
game.with_system("input", InputSystem, &[]);
|
||||
}
|
||||
}
|
|
@ -153,67 +153,70 @@ impl<'a> TryFrom<&'a WindowEvent<'a>> for InputEvent {
|
|||
match value {
|
||||
WindowEvent::KeyboardInput { device_id, input, is_synthetic } =>
|
||||
Ok(InputEvent::KeyboardInput {
|
||||
device_id: device_id.clone(),
|
||||
input: input.clone(),
|
||||
is_synthetic: is_synthetic.clone()
|
||||
device_id: *device_id,
|
||||
input: *input,
|
||||
is_synthetic: *is_synthetic
|
||||
}),
|
||||
#[allow(deprecated, reason="Compatibility")]
|
||||
WindowEvent::CursorMoved { device_id, position, modifiers } =>
|
||||
Ok(InputEvent::CursorMoved {
|
||||
device_id: device_id.clone(),
|
||||
position: position.clone(),
|
||||
modifiers: modifiers.clone()
|
||||
device_id: *device_id,
|
||||
position: *position,
|
||||
modifiers: *modifiers
|
||||
}),
|
||||
WindowEvent::CursorEntered { device_id } =>
|
||||
Ok(InputEvent::CursorEntered {
|
||||
device_id: device_id.clone()
|
||||
device_id: *device_id
|
||||
}),
|
||||
WindowEvent::CursorLeft { device_id } =>
|
||||
Ok(InputEvent::CursorLeft {
|
||||
device_id: device_id.clone()
|
||||
device_id: *device_id
|
||||
}),
|
||||
#[allow(deprecated, reason="Compatibility")]
|
||||
WindowEvent::MouseWheel { device_id, delta, phase, modifiers } =>
|
||||
Ok(InputEvent::MouseWheel {
|
||||
device_id: device_id.clone(),
|
||||
delta: delta.clone(),
|
||||
phase: phase.clone(),
|
||||
modifiers: modifiers.clone()
|
||||
device_id: *device_id,
|
||||
delta: *delta,
|
||||
phase: *phase,
|
||||
modifiers: *modifiers
|
||||
}),
|
||||
#[allow(deprecated, reason="Compatibility")]
|
||||
WindowEvent::MouseInput { device_id, state, button, modifiers } =>
|
||||
Ok(InputEvent::MouseInput {
|
||||
device_id: device_id.clone(),
|
||||
state: state.clone(),
|
||||
button: button.clone(),
|
||||
modifiers: modifiers.clone()
|
||||
device_id: *device_id,
|
||||
state: *state,
|
||||
button: *button,
|
||||
modifiers: *modifiers
|
||||
}),
|
||||
WindowEvent::TouchpadMagnify { device_id, delta, phase } =>
|
||||
Ok(InputEvent::TouchpadMagnify {
|
||||
device_id: device_id.clone(),
|
||||
delta: delta.clone(),
|
||||
phase: phase.clone()
|
||||
device_id: *device_id,
|
||||
delta: *delta,
|
||||
phase: *phase
|
||||
}),
|
||||
WindowEvent::SmartMagnify { device_id } =>
|
||||
Ok(InputEvent::SmartMagnify {
|
||||
device_id: device_id.clone()
|
||||
device_id: *device_id
|
||||
}),
|
||||
WindowEvent::TouchpadRotate { device_id, delta, phase } =>
|
||||
Ok(InputEvent::TouchpadRotate {
|
||||
device_id: device_id.clone(),
|
||||
delta: delta.clone(),
|
||||
phase: phase.clone()
|
||||
device_id: *device_id,
|
||||
delta: *delta,
|
||||
phase: *phase
|
||||
}),
|
||||
WindowEvent::TouchpadPressure { device_id, pressure, stage } =>
|
||||
Ok(InputEvent::TouchpadPressure {
|
||||
device_id: device_id.clone(),
|
||||
pressure: pressure.clone(),
|
||||
stage: stage.clone()
|
||||
device_id: *device_id,
|
||||
pressure: *pressure,
|
||||
stage: *stage
|
||||
}),
|
||||
WindowEvent::AxisMotion { device_id, axis, value } =>
|
||||
Ok(InputEvent::AxisMotion {
|
||||
device_id: device_id.clone(),
|
||||
axis: axis.clone(),
|
||||
value: value.clone()
|
||||
device_id: *device_id,
|
||||
axis: *axis,
|
||||
value: *value
|
||||
}),
|
||||
WindowEvent::Touch(t) => Ok(InputEvent::Touch(t.clone())),
|
||||
WindowEvent::Touch(t) => Ok(InputEvent::Touch(*t)),
|
||||
|
||||
_ => Err(InputEventConversionError::FromError(value))
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#![feature(hash_extract_if)]
|
||||
#![feature(lint_reasons)]
|
||||
|
||||
pub mod game;
|
||||
pub mod render;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use glam::{Vec3, Mat4, Quat};
|
||||
|
||||
use crate::math::angle::{self, Angle};
|
||||
use crate::math::angle::Angle;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
|
@ -28,6 +28,7 @@ impl Default for Transform {
|
|||
|
||||
// TODO: https://www.brainvoyager.com/bv/doc/UsersGuide/CoordsAndTransforms/SpatialTransformationMatrices.html
|
||||
|
||||
#[allow(dead_code)]
|
||||
const ZERO_V3: Vec3 = Vec3::new(0.0, 0.0, 0.0);
|
||||
const ONE_V3: Vec3 = Vec3::new(1.0, 1.0, 1.0);
|
||||
|
||||
|
|
|
@ -10,15 +10,15 @@ pub trait Plugin {
|
|||
/// Setup this plugin. This runs before the game has started
|
||||
fn setup(&self, game: &mut Game);
|
||||
|
||||
fn is_ready(&self, game: &mut Game) -> bool {
|
||||
fn is_ready(&self, _game: &mut Game) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn complete(&self, game: &mut Game) {
|
||||
fn complete(&self, _game: &mut Game) {
|
||||
|
||||
}
|
||||
|
||||
fn cleanup(&self, game: &mut Game) {
|
||||
fn cleanup(&self, _game: &mut Game) {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -108,9 +108,9 @@ pub struct DefaultPlugins;
|
|||
impl Plugin for DefaultPlugins {
|
||||
fn setup(&self, game: &mut Game) {
|
||||
// setup input
|
||||
EventsPlugin::default().setup(game);
|
||||
InputPlugin::default().setup(game);
|
||||
ResourceManagerPlugin::default().setup(game);
|
||||
EventsPlugin.setup(game);
|
||||
InputPlugin.setup(game);
|
||||
ResourceManagerPlugin.setup(game);
|
||||
WindowPlugin::default().setup(game);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
use tracing::debug;
|
||||
use winit::dpi::PhysicalSize;
|
||||
|
||||
use crate::{math::{Angle, OPENGL_TO_WGPU_MATRIX}, ecs::components::camera::CameraComponent};
|
||||
|
@ -31,7 +30,7 @@ impl Projection {
|
|||
self.aspect = width as f32 / height as f32;
|
||||
}
|
||||
|
||||
pub fn calc_matrix(&self, fov: Angle, mode: CameraProjectionMode) -> glam::Mat4 {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +39,7 @@ impl Projection {
|
|||
pub struct RenderCamera {
|
||||
view_proj: glam::Mat4,
|
||||
|
||||
#[allow(dead_code)]
|
||||
size: PhysicalSize<u32>,
|
||||
aspect: f32,
|
||||
znear: f32,
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
use wgpu::{BindGroup, BindGroupLayout};
|
||||
|
||||
use super::{vertex::Vertex, render_buffer::{BufferStorage}};
|
||||
use super::vertex::Vertex;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Mesh {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use std::ops::Range;
|
||||
use wgpu::{PipelineLayout, RenderPipeline, VertexBufferLayout, BindGroupLayout};
|
||||
|
||||
use wgpu::{PipelineLayout, RenderPipeline, RenderPass, VertexBufferLayout, BindGroupLayout};
|
||||
|
||||
use super::{render_job::RenderJob, texture::RenderTexture};
|
||||
use super::texture::RenderTexture;
|
||||
|
||||
pub struct FullRenderPipeline {
|
||||
layout: PipelineLayout,
|
||||
|
@ -34,12 +32,12 @@ impl FullRenderPipeline {
|
|||
label: Some("Render Pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex: wgpu::VertexState {
|
||||
module: &shader,
|
||||
module: shader,
|
||||
entry_point: "vs_main",
|
||||
buffers: &buffer_layouts,
|
||||
},
|
||||
fragment: Some(wgpu::FragmentState {
|
||||
module: &shader,
|
||||
module: shader,
|
||||
entry_point: "fs_main",
|
||||
targets: &[Some(wgpu::ColorTargetState {
|
||||
format: config.format,
|
||||
|
@ -89,28 +87,4 @@ impl FullRenderPipeline {
|
|||
pub fn get_wgpu_pipeline(&self) -> &RenderPipeline {
|
||||
&self.wgpu_pipeline
|
||||
}
|
||||
|
||||
pub fn render<'a>(&'a self, jobs: &'a Vec<RenderJob>, pass: &'a mut RenderPass<'a>, vertices: Range<u32>, instances: Range<u32>) {
|
||||
todo!()
|
||||
/* pass.set_pipeline(&self.wgpu_pipeline);
|
||||
|
||||
for job in jobs.iter() {
|
||||
let mesh = job.mesh();
|
||||
|
||||
if let Some(tex) = mesh.texture_bindgroup.as_ref() {
|
||||
pass.set_bind_group(0, &tex, &[]);
|
||||
}
|
||||
|
||||
if let Some(indices) = mesh.buffer_indices.as_ref() {
|
||||
let indices_len = indices.count().unwrap(); // index buffers will have count, if not thats a bug
|
||||
|
||||
pass.set_vertex_buffer(mesh.buffer_vertex.slot(), mesh.buffer_vertex.buffer().slice(..));
|
||||
pass.set_index_buffer(indices.buffer().slice(..), wgpu::IndexFormat::Uint16);
|
||||
pass.draw_indexed(0..indices_len, 0, instances.clone());
|
||||
} else {
|
||||
pass.set_vertex_buffer(mesh.buffer_vertex.slot(), mesh.buffer_vertex.buffer().slice(..));
|
||||
pass.draw(vertices.clone(), instances.clone());
|
||||
}
|
||||
} */
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
use std::cell::RefCell;
|
||||
use std::collections::{HashMap, VecDeque, HashSet};
|
||||
use std::mem;
|
||||
use std::num::NonZeroU64;
|
||||
|
@ -14,7 +13,6 @@ use wgpu::util::DeviceExt;
|
|||
use winit::window::Window;
|
||||
|
||||
use crate::ecs::components::camera::CameraComponent;
|
||||
use crate::ecs::components::mesh::MeshComponent;
|
||||
use crate::ecs::components::model::ModelComponent;
|
||||
use crate::ecs::components::transform::TransformComponent;
|
||||
use crate::math::Transform;
|
||||
|
@ -40,6 +38,7 @@ struct RenderBufferStorage {
|
|||
buffer_vertex: BufferStorage,
|
||||
buffer_indices: Option<(wgpu::IndexFormat, BufferStorage)>,
|
||||
|
||||
#[allow(dead_code)]
|
||||
render_texture: Option<RenderTexture>,
|
||||
texture_bindgroup: Option<BindGroup>,
|
||||
|
||||
|
@ -85,13 +84,13 @@ impl TransformBuffers {
|
|||
// get a dead index, or create a new one
|
||||
let (indices, buffer) = if let Some(index) = self.dead_indices.pop_front() {
|
||||
let (_, buffer, _) = self.buffer_bindgroups.get(index.buffer_index).unwrap();
|
||||
(index, &*buffer)
|
||||
(index, buffer)
|
||||
} else {
|
||||
let indices = &mut self.next_indices;
|
||||
let this_idx = indices.clone();
|
||||
let this_idx = *indices;
|
||||
let (count, buffer, _) = self.buffer_bindgroups.get_mut(indices.buffer_index).unwrap();
|
||||
|
||||
if count.clone() >= self.max_transform_count {
|
||||
if *count >= self.max_transform_count {
|
||||
panic!("Transform buffer is filled and 'next_indices' was not incremented! Was a new buffer created?");
|
||||
}
|
||||
|
||||
|
@ -126,8 +125,7 @@ impl TransformBuffers {
|
|||
/// Collect the dead entities, mark entities and not updated for next updates.
|
||||
fn tick(&mut self) {
|
||||
// take the dead entities, these were ones that were not updated this tick
|
||||
let dead: VecDeque<TransformBufferIndices> = self.not_updated.values()
|
||||
.map(|t| t.clone()).collect();
|
||||
let dead: VecDeque<TransformBufferIndices> = self.not_updated.values().copied().collect();
|
||||
self.dead_indices = dead;
|
||||
|
||||
self.not_updated = self.just_updated.clone();
|
||||
|
@ -141,7 +139,7 @@ impl TransformBuffers {
|
|||
/// Returns whether or not the transform buffers should be expanded
|
||||
fn should_expand(&self) -> bool {
|
||||
if let Some(( count, _, _ )) = self.buffer_bindgroups.last() {
|
||||
count.clone() >= self.max_transform_count
|
||||
*count >= self.max_transform_count
|
||||
} else {
|
||||
true
|
||||
}
|
||||
|
@ -228,8 +226,7 @@ impl BasicRenderer {
|
|||
|
||||
let surface_format = surface_caps.formats.iter()
|
||||
.copied()
|
||||
.filter(|f| f.describe().srgb)
|
||||
.next()
|
||||
.find(|f| f.describe().srgb)
|
||||
.unwrap_or(surface_caps.formats[0]);
|
||||
let config = wgpu::SurfaceConfiguration {
|
||||
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
|
||||
|
@ -270,7 +267,7 @@ impl BasicRenderer {
|
|||
let shader_src = include_str!("shaders/base.wgsl");
|
||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||
label: Some("Shader"),
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(&shader_src)),
|
||||
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(shader_src)),
|
||||
});
|
||||
|
||||
let transform_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
|
@ -446,7 +443,7 @@ impl BasicRenderer {
|
|||
let vertices = vertices.as_slice();
|
||||
// align the vertices to 4 bytes (u32 is 4 bytes, which is wgpu::COPY_BUFFER_ALIGNMENT)
|
||||
let (_, vertices, _) = bytemuck::pod_align_to::<Vec3, u32>(vertices);
|
||||
self.queue.write_buffer(&vertex_buffer, 0, bytemuck::cast_slice(&vertices));
|
||||
self.queue.write_buffer(vertex_buffer, 0, bytemuck::cast_slice(vertices));
|
||||
|
||||
// update the indices if they're given
|
||||
if let Some(index_buffer) = buffers.buffer_indices.as_ref() {
|
||||
|
@ -457,7 +454,7 @@ impl BasicRenderer {
|
|||
};
|
||||
|
||||
let index_buffer = index_buffer.1.buffer();
|
||||
self.queue.write_buffer(index_buffer, 0, bytemuck::cast_slice(&aligned_indices));
|
||||
self.queue.write_buffer(index_buffer, 0, bytemuck::cast_slice(aligned_indices));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -469,8 +466,8 @@ impl BasicRenderer {
|
|||
|
||||
assert!(positions.len() == tex_coords.len());
|
||||
|
||||
let vertex_inputs: Vec<Vertex> = std::iter::zip(positions, tex_coords.into_iter())
|
||||
.map(|(v, t)| Vertex::new(v.clone(), t))
|
||||
let vertex_inputs: Vec<Vertex> = std::iter::zip(positions, tex_coords)
|
||||
.map(|(v, t)| Vertex::new(*v, t))
|
||||
.collect();
|
||||
|
||||
let vertex_buffer = self.device.create_buffer_init(
|
||||
|
@ -485,8 +482,8 @@ impl BasicRenderer {
|
|||
let indices = match mesh.indices.as_ref() {
|
||||
Some(indices) => {
|
||||
let (idx_type, len, contents) = match indices {
|
||||
lyra_resource::MeshIndices::U16(v) => (wgpu::IndexFormat::Uint16, v.len(), bytemuck::cast_slice(&v)),
|
||||
lyra_resource::MeshIndices::U32(v) => (wgpu::IndexFormat::Uint32, v.len(), bytemuck::cast_slice(&v)),
|
||||
lyra_resource::MeshIndices::U16(v) => (wgpu::IndexFormat::Uint16, v.len(), bytemuck::cast_slice(v)),
|
||||
lyra_resource::MeshIndices::U32(v) => (wgpu::IndexFormat::Uint32, v.len(), bytemuck::cast_slice(v)),
|
||||
};
|
||||
|
||||
let index_buffer = self.device.create_buffer_init(
|
||||
|
@ -588,9 +585,8 @@ impl BasicRenderer {
|
|||
let indices = self.transform_buffers.update_or_insert(&self.queue, &self.render_limits,
|
||||
entity, || transform.calculate_mat4());
|
||||
|
||||
if self.mesh_buffers.contains_key(&mesh.uuid) {
|
||||
false
|
||||
} else {
|
||||
#[allow(clippy::map_entry)]
|
||||
if !self.mesh_buffers.contains_key(&mesh.uuid) {
|
||||
// check if the transform buffers need to be expanded
|
||||
if self.transform_buffers.should_expand() {
|
||||
self.expand_transform_buffers();
|
||||
|
@ -602,7 +598,7 @@ impl BasicRenderer {
|
|||
self.entity_meshes.insert(entity, mesh.uuid);
|
||||
|
||||
true
|
||||
}
|
||||
} else { false }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -618,10 +614,8 @@ impl Renderer for BasicRenderer {
|
|||
let model = model.data.as_ref().unwrap().as_ref();
|
||||
|
||||
for mesh in model.meshes.iter() {
|
||||
if !self.process_mesh(entity, transform.transform, mesh) {
|
||||
if model_epoch == last_epoch {
|
||||
self.update_mesh_buffers(entity, mesh);
|
||||
}
|
||||
if !self.process_mesh(entity, transform.transform, mesh) && model_epoch == last_epoch {
|
||||
self.update_mesh_buffers(entity, mesh);
|
||||
}
|
||||
|
||||
let shader = mesh.material().shader_uuid.unwrap_or(0);
|
||||
|
@ -630,9 +624,9 @@ impl Renderer for BasicRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
for (entity, mesh, mesh_epoch, transform) in main_world.query::<(Entities, &MeshComponent, EpochOf<MeshComponent>, &TransformComponent)>().iter() {
|
||||
/* for (entity, mesh, mesh_epoch, transform) in main_world.query::<(Entities, &MeshComponent, EpochOf<MeshComponent>, &TransformComponent)>().iter() {
|
||||
debug!("TODO: Process MeshComponents"); // TODO: Process MeshComponents
|
||||
}
|
||||
} */
|
||||
|
||||
// collect dead entities
|
||||
self.transform_buffers.tick();
|
||||
|
@ -649,7 +643,7 @@ impl Renderer for BasicRenderer {
|
|||
|
||||
if let Some(camera) = main_world.query_mut::<(&mut CameraComponent,)>().into_iter().next() {
|
||||
let view_proj = self.inuse_camera.update_view_projection(camera);
|
||||
self.queue.write_buffer(&self.camera_buffer, 0, bytemuck::cast_slice(&[view_proj.clone()]));
|
||||
self.queue.write_buffer(&self.camera_buffer, 0, bytemuck::cast_slice(&[*view_proj]));
|
||||
} else {
|
||||
warn!("Missing camera!");
|
||||
}
|
||||
|
@ -698,7 +692,7 @@ impl Renderer for BasicRenderer {
|
|||
|
||||
// Bind the optional texture
|
||||
if let Some(tex) = buffers.texture_bindgroup.as_ref() {
|
||||
render_pass.set_bind_group(0, &tex, &[]);
|
||||
render_pass.set_bind_group(0, tex, &[]);
|
||||
} else {
|
||||
render_pass.set_bind_group(0, &self.default_texture_bind_group, &[]);
|
||||
}
|
||||
|
@ -717,7 +711,7 @@ impl Renderer for BasicRenderer {
|
|||
let indices_len = indices.count() as u32;
|
||||
|
||||
render_pass.set_vertex_buffer(buffers.buffer_vertex.slot(), buffers.buffer_vertex.buffer().slice(..));
|
||||
render_pass.set_index_buffer(indices.buffer().slice(..), idx_type.clone());
|
||||
render_pass.set_index_buffer(indices.buffer().slice(..), *idx_type);
|
||||
render_pass.draw_indexed(0..indices_len, 0, 0..1);
|
||||
} else {
|
||||
let vertex_count = buffers.buffer_vertex.count();
|
||||
|
|
|
@ -96,7 +96,7 @@ impl RenderTexture {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn update_texture(&mut self, device: &wgpu::Device, queue: &wgpu::Queue, texture: &Arc<Resource<Texture>>) {
|
||||
pub fn update_texture(&mut self, _device: &wgpu::Device, queue: &wgpu::Queue, texture: &Arc<Resource<Texture>>) {
|
||||
let texture = &texture.data.as_ref().unwrap().image;
|
||||
let rgba = texture.to_rgba8();
|
||||
let dimensions = texture.dimensions();
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use glam::{Vec2, IVec2};
|
||||
use tracing::{warn, error, debug};
|
||||
use tracing::{warn, error};
|
||||
use winit::{window::{Window, Fullscreen}, dpi::{LogicalPosition, LogicalSize, PhysicalPosition}, error::ExternalError};
|
||||
|
||||
pub use winit::window::{CursorGrabMode, CursorIcon, Icon, Theme, WindowButtons, WindowLevel};
|
||||
|
||||
//use winit::dpi::{LogicalPosition, PhysicalPosition};
|
||||
|
||||
use crate::{plugin::Plugin, change_tracker::Ct};
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
|
@ -206,6 +204,7 @@ impl Default for WindowOptions {
|
|||
|
||||
#[derive(Default)]
|
||||
pub struct WindowPlugin {
|
||||
#[allow(dead_code)]
|
||||
create_options: WindowOptions,
|
||||
}
|
||||
|
||||
|
@ -221,7 +220,7 @@ fn ivec2_to_logical_size(size: IVec2) -> LogicalSize<i32> {
|
|||
|
||||
/// Convert an Option<IVec2> to an Option<LogicalSize<i32>>
|
||||
fn ivec2_to_logical_size_op(size: Option<IVec2>) -> Option<LogicalSize<i32>> {
|
||||
size.map(|size| ivec2_to_logical_size(size))
|
||||
size.map(ivec2_to_logical_size)
|
||||
}
|
||||
|
||||
/// Convert an Option<Vec2> to an Option<LogicalSize<f32>>
|
||||
|
@ -256,7 +255,7 @@ fn set_cursor_grab(window: &Window, grab: &mut CursorGrabMode) -> anyhow::Result
|
|||
/// if the window is set to confine the cursor, and the cursor is invisible,
|
||||
/// set the cursor position to the center of the screen.
|
||||
fn center_mouse(window: &Window, options: &WindowOptions) {
|
||||
if options.cursor_grab == CursorGrabMode::Confined && options.cursor_visible == false {
|
||||
if options.cursor_grab == CursorGrabMode::Confined && !options.cursor_visible {
|
||||
let size = window.inner_size();
|
||||
let middle = PhysicalPosition {
|
||||
x: size.width / 2,
|
||||
|
|
|
@ -10,7 +10,7 @@ pub async fn load_bytes(file_name: &str) -> anyhow::Result<Vec<u8>> {
|
|||
.bytes()
|
||||
.await?;
|
||||
} else {
|
||||
let out_dir = std::env::var("OUT_DIR").unwrap_or(String::new());
|
||||
let out_dir = std::env::var("OUT_DIR").unwrap_or_default();
|
||||
let path = std::path::Path::new(&out_dir)
|
||||
.join("res")
|
||||
.join(file_name);
|
||||
|
|
Loading…
Reference in New Issue