From c67de88ad9c261a9dee5296379242f7588baedf5 Mon Sep 17 00:00:00 2001 From: Freja Roberts Date: Sat, 7 Dec 2024 21:01:03 +0100 Subject: [PATCH] feat: boolean input state --- ivy-assets/src/handle.rs | 13 +- ivy-assets/src/lib.rs | 3 +- ivy-assets/src/service.rs | 10 +- ivy-core/src/app/builder.rs | 1 - ivy-core/src/app/mod.rs | 7 +- ivy-core/src/components/mod.rs | 1 + ivy-core/src/dir.rs | 3 +- ivy-core/src/extent.rs | 3 +- ivy-core/src/gizmos/traits.rs | 3 +- ivy-core/src/layer/mod.rs | 16 +- ivy-core/src/lib.rs | 2 +- ivy-core/src/time.rs | 8 + ivy-game/src/free_camera.rs | 38 ++- ivy-game/src/ray_picker.rs | 24 +- ivy-gltf/src/lib.rs | 38 +-- ivy-graphics/src/mesh.rs | 2 +- ivy-graphics/src/texture.rs | 2 +- ivy-input/src/bindings.rs | 323 ++++++++++-------- ivy-input/src/lib.rs | 41 ++- ivy-physics/src/lib.rs | 1 - ivy-physics/src/plugin.rs | 15 +- ivy-physics/src/state.rs | 5 +- ivy-physics/src/systems.rs | 9 +- ivy-ui/src/layer.rs | 39 ++- ivy-ui/src/lib.rs | 5 +- ivy-wgpu-types/src/lib.rs | 2 +- ivy-wgpu-types/src/shader.rs | 3 +- ivy-wgpu-types/src/texture.rs | 3 +- ivy-wgpu/src/driver.rs | 2 +- ivy-wgpu/src/gltf/node.rs | 1 - ivy-wgpu/src/mesh.rs | 3 +- ivy-wgpu/src/mesh_buffer.rs | 3 +- ivy-wgpu/src/renderer/gizmos_renderer.rs | 3 +- ivy-wgpu/src/renderer/light_manager.rs | 6 +- ivy-wgpu/src/renderer/mesh_renderer.rs | 3 +- ivy-wgpu/src/renderer/mod.rs | 3 +- ivy-wgpu/src/renderer/shadowmapping.rs | 32 +- .../src/renderer/skinned_mesh_renderer.rs | 8 +- ivy-wgpu/src/rendergraph/mod.rs | 11 +- ivy-wgpu/src/rendergraph/resources.rs | 4 +- ivy-wgpu/src/shaders.rs | 20 +- src/lib.rs | 10 +- violet | 2 +- 43 files changed, 398 insertions(+), 333 deletions(-) diff --git a/ivy-assets/src/handle.rs b/ivy-assets/src/handle.rs index 478bfc00..9191ead7 100644 --- a/ivy-assets/src/handle.rs +++ b/ivy-assets/src/handle.rs @@ -1,9 +1,9 @@ -use std::cmp::Ordering; -use std::{self}; - -use std::hash::Hash; - -use std::sync::{Arc, Weak}; +use std::{ + cmp::Ordering, + hash::Hash, + sync::{Arc, Weak}, + {self}, +}; use super::AssetId; @@ -103,7 +103,6 @@ impl Asset { pub fn id(&self) -> AssetId { self.id } - } impl Hash for Asset { diff --git a/ivy-assets/src/lib.rs b/ivy-assets/src/lib.rs index 1c89ed9d..a12ce1a3 100644 --- a/ivy-assets/src/lib.rs +++ b/ivy-assets/src/lib.rs @@ -432,9 +432,8 @@ impl Future for AssetLoadFuture { mod tests { use std::{convert::Infallible, path::Path}; - use crate::service::FsAssetError; - use super::*; + use crate::service::FsAssetError; #[test] fn asset_cache() { diff --git a/ivy-assets/src/service.rs b/ivy-assets/src/service.rs index f36a08c6..ee7956b2 100644 --- a/ivy-assets/src/service.rs +++ b/ivy-assets/src/service.rs @@ -1,7 +1,9 @@ -use std::convert::Infallible; -use std::fs::File; -use std::io::{self, BufReader, Read}; -use std::path::{Path, PathBuf}; +use std::{ + convert::Infallible, + fs::File, + io::{self, BufReader, Read}, + path::{Path, PathBuf}, +}; use futures::AsyncReadExt; use thiserror::Error; diff --git a/ivy-core/src/app/builder.rs b/ivy-core/src/app/builder.rs index 51638335..8f98379c 100644 --- a/ivy-core/src/app/builder.rs +++ b/ivy-core/src/app/builder.rs @@ -1,5 +1,4 @@ use self::driver::{DefaultDriver, Driver}; - use super::*; pub struct AppBuilder { diff --git a/ivy-core/src/app/mod.rs b/ivy-core/src/app/mod.rs index b3a7303c..07db1600 100644 --- a/ivy-core/src/app/mod.rs +++ b/ivy-core/src/app/mod.rs @@ -6,19 +6,16 @@ use std::time::Duration; pub use builder::*; pub use event::*; - use flax::World; +use ivy_assets::{service::FileSystemMapService, AssetCache}; +use self::driver::Driver; use crate::{ components::{self, engine}, layer::events::{Event, EventRegistry}, Layer, LayerDyn, }; -use ivy_assets::{service::FileSystemMapService, AssetCache}; - -use self::driver::Driver; - pub struct App { name: String, diff --git a/ivy-core/src/components/mod.rs b/ivy-core/src/components/mod.rs index 0ae6dd6b..bb38eac6 100644 --- a/ivy-core/src/components/mod.rs +++ b/ivy-core/src/components/mod.rs @@ -26,6 +26,7 @@ flax::component! { pub gizmos: Gizmos, pub async_commandbuffer: AsyncCommandBuffer, + pub request_capture_mouse: bool, pub time: Time, pub delta_time: Duration, diff --git a/ivy-core/src/dir.rs b/ivy-core/src/dir.rs index a6bbf8a3..36683196 100644 --- a/ivy-core/src/dir.rs +++ b/ivy-core/src/dir.rs @@ -1,6 +1,7 @@ -use anyhow::Context; use std::env; +use anyhow::Context; + // Set directory to nth parent of current executable pub fn normalize_dir(nth: usize) -> anyhow::Result<()> { let current_exe = env::current_exe()? diff --git a/ivy-core/src/extent.rs b/ivy-core/src/extent.rs index fad88ea2..d692546b 100644 --- a/ivy-core/src/extent.rs +++ b/ivy-core/src/extent.rs @@ -1,9 +1,10 @@ -use glam::Vec2; use std::{ fmt::Display, ops::{Add, Mul}, }; +use glam::Vec2; + /// Represents a width and height. #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] diff --git a/ivy-core/src/gizmos/traits.rs b/ivy-core/src/gizmos/traits.rs index 2efb56da..751ee947 100644 --- a/ivy-core/src/gizmos/traits.rs +++ b/ivy-core/src/gizmos/traits.rs @@ -1,8 +1,7 @@ use glam::Vec3; -use crate::{Color, ColorExt}; - use super::{GizmosSection, Line, Sphere, DEFAULT_RADIUS}; +use crate::{Color, ColorExt}; pub trait DrawGizmos { /// Draw a set of gizmos using the current section diff --git a/ivy-core/src/layer/mod.rs b/ivy-core/src/layer/mod.rs index 5f8d0208..9b48cda6 100644 --- a/ivy-core/src/layer/mod.rs +++ b/ivy-core/src/layer/mod.rs @@ -1,16 +1,19 @@ #![allow(non_snake_case)] use std::time::{Duration, Instant}; -use crate::components::{async_commandbuffer, engine, gizmos, time}; -use crate::gizmos::Gizmos; -use crate::systems::update_transform_system; -use crate::time::Time; -use crate::AsyncCommandBuffer; -use crate::{app::TickEvent, systems::apply_async_commandbuffers}; use downcast_rs::{impl_downcast, Downcast}; use flax::{Entity, Schedule, World}; use ivy_assets::AssetCache; +use crate::{ + app::TickEvent, + components::{async_commandbuffer, engine, gizmos, request_capture_mouse, time}, + gizmos::Gizmos, + systems::{apply_async_commandbuffers, update_transform_system}, + time::Time, + AsyncCommandBuffer, +}; + pub mod events; use self::events::{EventRegisterContext, EventRegistry}; @@ -101,6 +104,7 @@ impl Layer for EngineLayer { .set(async_commandbuffer(), self.cmd.clone()) .set(gizmos(), Gizmos::new()) .set(time(), Time::new(Instant::now(), Duration::ZERO)) + .set(request_capture_mouse(), false) .append_to(world, engine())?; events.subscribe(|this, world, _, _: &TickEvent| { diff --git a/ivy-core/src/lib.rs b/ivy-core/src/lib.rs index 7d8bc841..d018efe1 100644 --- a/ivy-core/src/lib.rs +++ b/ivy-core/src/lib.rs @@ -39,9 +39,9 @@ pub mod layer; pub mod macros; pub mod subscribers; mod systems; +pub mod time; mod updatable; pub mod update_layer; -pub mod time; use std::f32::consts::PI; diff --git a/ivy-core/src/time.rs b/ivy-core/src/time.rs index 408bbf8f..980113ae 100644 --- a/ivy-core/src/time.rs +++ b/ivy-core/src/time.rs @@ -12,4 +12,12 @@ impl Time { elapsed, } } + + pub fn start_time(&self) -> Instant { + self.start_time + } + + pub fn elapsed(&self) -> Duration { + self.elapsed + } } diff --git a/ivy-game/src/free_camera.rs b/ivy-game/src/free_camera.rs index 4dae4adf..4ee540e0 100644 --- a/ivy-game/src/free_camera.rs +++ b/ivy-game/src/free_camera.rs @@ -1,4 +1,6 @@ -use flax::{BoxedSystem, Component, Entity, FetchExt, ComponentMut, Query, QueryBorrow, System, World}; +use flax::{ + BoxedSystem, Component, ComponentMut, Entity, FetchExt, Query, QueryBorrow, System, World, +}; use glam::{vec3, EulerRot, Quat, Vec2, Vec3}; use ivy_assets::AssetCache; use ivy_core::{ @@ -9,8 +11,8 @@ use ivy_core::{ use ivy_input::{ components::input_state, types::{Key, NamedKey}, - Action, Axis2D, BindingExt, CursorMoveBinding, InputState, KeyBinding, MouseButtonBinding, - ScrollBinding, + Action, Axis2D, Axis3D, BindingExt, CursorMoveBinding, InputState, KeyBinding, + MouseButtonBinding, ScrollBinding, }; use ivy_physics::{ components::{angular_velocity, velocity}, @@ -23,7 +25,7 @@ use ivy_wgpu::{ }; flax::component! { - pub pan_active: i32, + pub pan_active: bool, pub rotation_input: Vec2, pub euler_rotation: Vec3, pub camera_movement: Vec3, @@ -59,38 +61,42 @@ pub fn setup_camera() -> flax::EntityBuilder { move_action.add( KeyBinding::new(Key::Character("w".into())) .analog() - .compose(Vec3::Z), + .compose(Axis3D::Z), ); move_action.add( KeyBinding::new(Key::Character("a".into())) .analog() - .compose(-Vec3::X), + .compose(Axis3D::X) + .amplitude(-1.0), ); move_action.add( KeyBinding::new(Key::Character("s".into())) .analog() - .compose(-Vec3::Z), + .compose(Axis3D::Z) + .amplitude(-1.0), ); move_action.add( KeyBinding::new(Key::Character("d".into())) .analog() - .compose(Vec3::X), + .compose(Axis3D::X), ); move_action.add( KeyBinding::new(Key::Character("c".into())) .analog() - .compose(-Vec3::Y), + .compose(Axis3D::Y) + .amplitude(-1.0), ); move_action.add( KeyBinding::new(Key::Named(NamedKey::Control)) .analog() - .compose(-Vec3::Y), + .compose(Axis3D::Y) + .amplitude(-1.0), ); move_action.add( KeyBinding::new(Key::Named(NamedKey::Space)) .analog() - .compose(Vec3::Y), + .compose(Axis3D::Y), ); let mut rotate_action = Action::new(); @@ -138,11 +144,11 @@ fn cursor_lock_system() -> BoxedSystem { .with_query(Query::new(pan_active())) .with_query(Query::new(window().as_mut()).with(main_window())) .build( - |mut query: QueryBorrow>, + |mut query: QueryBorrow>, mut window: QueryBorrow, _>| { query.iter().for_each(|&pan_active| { if let Some(window) = window.first() { - window.set_cursor_lock(pan_active > 0); + window.set_cursor_lock(pan_active); } }); }, @@ -170,10 +176,10 @@ fn camera_rotation_input_system() -> BoxedSystem { rotation().as_mut(), euler_rotation().as_mut(), rotation_input(), - pan_active(), + pan_active().eq(true), ))) - .for_each(|(rotation, euler_rotation, rotation_input, &pan_active)| { - *euler_rotation += pan_active as f32 * vec3(rotation_input.y, rotation_input.x, 0.0); + .for_each(|(rotation, euler_rotation, rotation_input, _)| { + *euler_rotation += vec3(rotation_input.y, rotation_input.x, 0.0); *rotation = Quat::from_euler(EulerRot::YXZ, -euler_rotation.y, -euler_rotation.x, 0.0); }) .boxed() diff --git a/ivy-game/src/ray_picker.rs b/ivy-game/src/ray_picker.rs index 46e75b88..9635fbc8 100644 --- a/ivy-game/src/ray_picker.rs +++ b/ivy-game/src/ray_picker.rs @@ -1,7 +1,7 @@ use flax::{ component, fetch::{entity_refs, EntityRefs, Source}, - system, BoxedSystem, CommandBuffer, Component, Entity, Fetch, FetchExt, ComponentMut, Query, + system, BoxedSystem, CommandBuffer, Component, ComponentMut, Entity, Fetch, FetchExt, Query, QueryBorrow, System, World, }; use glam::{vec2, vec4, Mat4, Vec2, Vec3, Vec4Swizzles}; @@ -100,7 +100,11 @@ impl PickingState { )) .build(); - cmd.set(self.manipulator, impulse_joint(hit.collider_id), joint.into()); + cmd.set( + self.manipulator, + impulse_joint(hit.collider_id), + joint.into(), + ); self.picked_object = Some((hit.collider_id, anchor, distance)); } @@ -136,10 +140,10 @@ impl PickingState { } component! { - pick_ray_action: i32, + pick_ray_action: bool, cursor_position_action: Vec2, picking_state: PickingState, - ray_distance_modifier: i32, + ray_distance_modifier: f32, } pub struct RayPickingPlugin; @@ -158,8 +162,12 @@ impl Plugin for RayPickingPlugin { cursor_position.add(CursorPositionBinding::new(true)); let mut ray_distance_action = Action::new(); - ray_distance_action.add(KeyBinding::new(Key::Named(NamedKey::ArrowUp))); - ray_distance_action.add(KeyBinding::new(Key::Named(NamedKey::ArrowDown)).amplitude(-1)); + ray_distance_action.add(KeyBinding::new(Key::Named(NamedKey::ArrowUp)).analog()); + ray_distance_action.add( + KeyBinding::new(Key::Named(NamedKey::ArrowDown)) + .analog() + .amplitude(-1.0), + ); let manipulator = Entity::builder() .mount(TransformBundle::default()) @@ -220,7 +228,7 @@ impl Default for CameraQuery { type PickingQuery = ( EntityRefs, - Component, + Component, Component, ComponentMut, ); @@ -268,7 +276,7 @@ pub fn pick_ray_system() -> BoxedSystem { { let world = entity.world(); - if *pick_ray_activation < 1 { + if !pick_ray_activation { state.stop_manipulating(cmd); return Ok(()); } diff --git a/ivy-gltf/src/lib.rs b/ivy-gltf/src/lib.rs index a58103e2..062a85e5 100644 --- a/ivy-gltf/src/lib.rs +++ b/ivy-gltf/src/lib.rs @@ -1,38 +1,20 @@ pub mod animation; pub mod components; +use std::{borrow::Cow, collections::HashMap, fs, future::Future, io, path::Path, sync::Arc}; + use animation::skin::Skin; use anyhow::Context; -use futures::StreamExt; -use futures::TryStreamExt; -use glam::Mat4; -use glam::Quat; -use glam::U16Vec4; -use glam::Vec2; -use glam::Vec3; -use glam::Vec4; -use gltf::buffer; -use image::DynamicImage; -use image::ImageFormat; +use futures::{StreamExt, TryStreamExt}; +use glam::{Mat4, Quat, U16Vec4, Vec2, Vec3, Vec4}; +use gltf::{buffer, Gltf}; +use image::{DynamicImage, ImageFormat}; use itertools::Itertools; -use ivy_assets::fs::AsyncAssetFromPath; -use ivy_assets::AssetDesc; +use ivy_assets::{fs::AsyncAssetFromPath, Asset, AssetCache, AssetDesc}; use ivy_core::components::TransformBundle; -use ivy_graphics::mesh::MeshData; -use ivy_graphics::mesh::TANGENT_ATTRIBUTE; -use ivy_profiling::profile_function; -use ivy_profiling::profile_scope; -use rayon::iter::ParallelBridge; -use rayon::iter::ParallelIterator; -use std::borrow::Cow; -use std::fs; -use std::future::Future; -use std::io; -use std::sync::Arc; -use std::{collections::HashMap, path::Path}; - -use gltf::Gltf; -use ivy_assets::{Asset, AssetCache}; +use ivy_graphics::mesh::{MeshData, TANGENT_ATTRIBUTE}; +use ivy_profiling::{profile_function, profile_scope}; +use rayon::iter::{ParallelBridge, ParallelIterator}; /// An in memory representation of a gltf document and binary buffer data pub struct DocumentData { diff --git a/ivy-graphics/src/mesh.rs b/ivy-graphics/src/mesh.rs index c964dc8c..0c46b465 100644 --- a/ivy-graphics/src/mesh.rs +++ b/ivy-graphics/src/mesh.rs @@ -1,7 +1,7 @@ -use itertools::Itertools; use std::collections::BTreeMap; use glam::{vec2, vec3, U16Vec4, UVec4, Vec2, Vec3, Vec4}; +use itertools::Itertools; use ivy_profiling::profile_function; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/ivy-graphics/src/texture.rs b/ivy-graphics/src/texture.rs index 7649374f..a5d34510 100644 --- a/ivy-graphics/src/texture.rs +++ b/ivy-graphics/src/texture.rs @@ -1,5 +1,5 @@ use image::{DynamicImage, ImageBuffer}; -use ivy_assets::{Asset, AssetDesc, AsyncAssetDesc, DynAsyncAssetDesc, DynAssetDesc}; +use ivy_assets::{Asset, AssetDesc, AsyncAssetDesc, DynAssetDesc, DynAsyncAssetDesc}; use ivy_core::palette::Srgba; #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/ivy-input/src/bindings.rs b/ivy-input/src/bindings.rs index 310f4b85..656ac265 100644 --- a/ivy-input/src/bindings.rs +++ b/ivy-input/src/bindings.rs @@ -8,133 +8,131 @@ use winit::{ use crate::types::{InputEvent, InputKind, KeyboardInput, MouseInput}; -pub trait Binding: Send + Sync { +pub trait Binding: Send + Sync { + type Value; fn apply(&mut self, input: &InputEvent); - fn read(&mut self) -> T; + fn read(&mut self) -> Self::Value; fn binding(&self) -> InputKind; } -pub struct Decompose { - binding: B, - axis: Axis, +pub trait Composable { + type Output; + fn compose(&self, axis: Space) -> Self::Output; } -impl> Binding for Decompose { - fn apply(&mut self, input: &InputEvent) { - self.binding.apply(input); - } +pub trait Decomposable { + type Output; + fn decompose(&self, axis: Space) -> Self::Output; +} - fn read(&mut self) -> f32 { - match self.axis { - Axis2D::X => self.binding.read().x, - Axis2D::Y => self.binding.read().y, - } - } +impl Composable for i32 { + type Output = IVec2; - fn binding(&self) -> InputKind { - self.binding.binding() + fn compose(&self, axis: Axis2D) -> Self::Output { + match axis { + Axis2D::X => IVec2::X * *self, + Axis2D::Y => IVec2::Y * *self, + } } } -impl> Binding for Decompose { - fn apply(&mut self, input: &InputEvent) { - self.binding.apply(input); - } +impl Composable for i32 { + type Output = IVec3; - fn read(&mut self) -> i32 { - match self.axis { - Axis2D::X => self.binding.read().x, - Axis2D::Y => self.binding.read().y, + fn compose(&self, axis: Axis3D) -> Self::Output { + match axis { + Axis3D::X => IVec3::X * *self, + Axis3D::Y => IVec3::Y * *self, + Axis3D::Z => IVec3::Z * *self, } } - - fn binding(&self) -> InputKind { - self.binding.binding() - } } -impl> Binding for Decompose { - fn apply(&mut self, input: &InputEvent) { - self.binding.apply(input) - } +impl Composable for f32 { + type Output = Vec2; - fn read(&mut self) -> f32 { - match self.axis { - Axis3::X => self.binding.read().x, - Axis3::Y => self.binding.read().y, - Axis3::Z => self.binding.read().z, + fn compose(&self, axis: Axis2D) -> Self::Output { + match axis { + Axis2D::X => Vec2::X * *self, + Axis2D::Y => Vec2::Y * *self, } } - - fn binding(&self) -> InputKind { - self.binding.binding() - } } -impl> Binding for Decompose { - fn apply(&mut self, input: &InputEvent) { - self.binding.apply(input) - } +impl Composable for f32 { + type Output = Vec3; - fn read(&mut self) -> i32 { - match self.axis { - Axis3::X => self.binding.read().x, - Axis3::Y => self.binding.read().y, - Axis3::Z => self.binding.read().z, + fn compose(&self, axis: Axis3D) -> Self::Output { + match axis { + Axis3D::X => Vec3::X * *self, + Axis3D::Y => Vec3::Y * *self, + Axis3D::Z => Vec3::Z * *self, } } - - fn binding(&self) -> InputKind { - self.binding.binding() - } } -pub struct Compose { - binding: B, - axis: Axis, -} +impl Decomposable for Vec2 { + type Output = f32; -impl Compose { - pub fn new(binding: B, axis: Axis) -> Self { - Self { binding, axis } + fn decompose(&self, axis: Axis2D) -> Self::Output { + match axis { + Axis2D::X => self.x, + Axis2D::Y => self.y, + } } } -impl> Binding for Compose { - fn apply(&mut self, input: &InputEvent) { - self.binding.apply(input) - } +impl Decomposable for IVec2 { + type Output = i32; - fn read(&mut self) -> Vec2 { - self.axis * self.binding.read() + fn decompose(&self, axis: Axis2D) -> Self::Output { + match axis { + Axis2D::X => self.x, + Axis2D::Y => self.y, + } } +} - fn binding(&self) -> InputKind { - self.binding.binding() +impl Decomposable for Vec3 { + type Output = f32; + + fn decompose(&self, axis: Axis3D) -> Self::Output { + match axis { + Axis3D::X => self.x, + Axis3D::Y => self.y, + Axis3D::Z => self.z, + } } } -impl> Binding for Compose { - fn apply(&mut self, input: &InputEvent) { - self.binding.apply(input) - } +impl Decomposable for IVec3 { + type Output = i32; - fn read(&mut self) -> IVec2 { - self.axis * self.binding.read() + fn decompose(&self, axis: Axis3D) -> Self::Output { + match axis { + Axis3D::X => self.x, + Axis3D::Y => self.y, + Axis3D::Z => self.z, + } } +} - fn binding(&self) -> InputKind { - self.binding.binding() - } +pub struct Decompose { + binding: B, + axis: Axis, } -impl> Binding for Compose { +impl, B: Binding> Binding + for Decompose +{ + type Value = T::Output; + fn apply(&mut self, input: &InputEvent) { - self.binding.apply(input) + self.binding.apply(input); } - fn read(&mut self) -> Vec3 { - self.axis * self.binding.read() + fn read(&mut self) -> Self::Value { + self.binding.read().decompose(self.axis) } fn binding(&self) -> InputKind { @@ -142,31 +140,28 @@ impl> Binding for Compose { } } -impl> Binding for Compose { - fn apply(&mut self, input: &InputEvent) { - self.binding.apply(input) - } - - fn read(&mut self) -> IVec3 { - self.axis * self.binding.read() - } +pub struct Compose { + binding: B, + axis: Axis, +} - fn binding(&self) -> InputKind { - self.binding.binding() +impl Compose { + pub fn new(binding: B, axis: Axis) -> Self { + Self { binding, axis } } } -impl> Binding for Compose { +impl, B: Binding> Binding + for Compose +{ + type Value = T::Output; + fn apply(&mut self, input: &InputEvent) { self.binding.apply(input) } - fn read(&mut self) -> Vec3 { - match self.axis { - Axis3::X => Vec3::X * self.binding.read(), - Axis3::Y => Vec3::Y * self.binding.read(), - Axis3::Z => Vec3::Z * self.binding.read(), - } + fn read(&mut self) -> Self::Value { + self.binding.read().compose(self.axis) } fn binding(&self) -> InputKind { @@ -175,12 +170,19 @@ impl> Binding for Compose { } #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct Amplitude { +pub struct Amplitude { binding: B, - amplitude: T, + amplitude: Rhs, } -impl, T: Send + Sync + Copy + Mul> Binding for Amplitude { +impl Binding for Amplitude +where + B: Binding, + T: Send + Sync + Copy + Mul, + Rhs: Copy + Send + Sync, +{ + type Value = T; + fn apply(&mut self, input: &InputEvent) { self.binding.apply(input) } @@ -209,7 +211,9 @@ impl KeyBinding { } } -impl Binding for KeyBinding { +impl Binding for KeyBinding { + type Value = bool; + fn apply(&mut self, input: &InputEvent) { match input { InputEvent::Keyboard(KeyboardInput { key, state, .. }) if key == &self.key => { @@ -219,8 +223,8 @@ impl Binding for KeyBinding { } } - fn read(&mut self) -> i32 { - self.pressed as i32 + fn read(&mut self) -> bool { + self.pressed } fn binding(&self) -> InputKind { @@ -228,35 +232,44 @@ impl Binding for KeyBinding { } } -pub struct Analog(T); +#[doc(hidden)] +pub trait AsAnalog { + type Output; -impl Binding for Analog -where - T: Binding, -{ - fn apply(&mut self, input: &InputEvent) { - self.0.apply(input); - } + fn as_analog(self) -> Self::Output; +} - fn read(&mut self) -> f32 { - self.0.read() as f32 +impl AsAnalog for bool { + type Output = f32; + + fn as_analog(self) -> Self::Output { + self as i32 as f32 } +} - fn binding(&self) -> InputKind { - self.0.binding() +impl AsAnalog for i32 { + type Output = f32; + + fn as_analog(self) -> Self::Output { + self as f32 } } -impl Binding for Analog +pub struct Analog(T); + +impl Binding for Analog where - T: Binding, + B: Binding, + T: AsAnalog, { + type Value = T::Output; + fn apply(&mut self, input: &InputEvent) { self.0.apply(input); } - fn read(&mut self) -> Vec2 { - self.0.read().as_vec2() + fn read(&mut self) -> Self::Value { + self.0.read().as_analog() } fn binding(&self) -> InputKind { @@ -264,16 +277,20 @@ where } } -impl Binding for Analog +pub struct Integral(T); + +impl Binding for Integral where - T: Binding, + B: Binding, { + type Value = i32; + fn apply(&mut self, input: &InputEvent) { self.0.apply(input); } - fn read(&mut self) -> Vec3 { - self.0.read().as_vec3() + fn read(&mut self) -> Self::Value { + self.0.read() as i32 } fn binding(&self) -> InputKind { @@ -296,7 +313,9 @@ impl MouseButtonBinding { } } -impl Binding for MouseButtonBinding { +impl Binding for MouseButtonBinding { + type Value = bool; + fn apply(&mut self, input: &InputEvent) { match input { InputEvent::MouseButton(MouseInput { button, state, .. }) if button == &self.button => { @@ -306,8 +325,8 @@ impl Binding for MouseButtonBinding { } } - fn read(&mut self) -> i32 { - self.pressed as i32 + fn read(&mut self) -> bool { + self.pressed } fn binding(&self) -> InputKind { @@ -332,7 +351,9 @@ impl Default for CursorMoveBinding { } } -impl Binding for CursorMoveBinding { +impl Binding for CursorMoveBinding { + type Value = Vec2; + fn apply(&mut self, input: &InputEvent) { match input { &InputEvent::CursorDelta(delta) => self.value += delta, @@ -364,7 +385,9 @@ impl CursorPositionBinding { } } -impl Binding for CursorPositionBinding { +impl Binding for CursorPositionBinding { + type Value = Vec2; + fn apply(&mut self, input: &InputEvent) { match input { InputEvent::CursorMoved(v) if self.normalized => self.value = v.normalized_position, @@ -401,7 +424,9 @@ impl Default for ScrollBinding { } } -impl Binding for ScrollBinding { +impl Binding for ScrollBinding { + type Value = Vec2; + fn apply(&mut self, input: &InputEvent) { match input { InputEvent::Scroll(delta) => self.value += delta.delta, @@ -418,18 +443,23 @@ impl Binding for ScrollBinding { } } +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum Axis2D { X, Y, } -pub enum Axis3 { +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum Axis3D { X, Y, Z, } -pub trait BindingExt { +pub trait BindingExt +where + Self: Binding, +{ fn compose(self, axis: T) -> Compose where Self: Sized, @@ -463,7 +493,7 @@ pub trait BindingExt { { RisingEdge { binding: self, - prev_value: 0, + prev_value: false, } } @@ -473,30 +503,39 @@ pub trait BindingExt { { Analog(self) } + + fn integral(self) -> Integral + where + Self: Sized, + { + Integral(self) + } } pub struct RisingEdge { binding: T, - prev_value: i32, + prev_value: bool, } -impl Binding for RisingEdge +impl Binding for RisingEdge where - T: Binding, + T: Binding, { + type Value = bool; + fn apply(&mut self, input: &InputEvent) { self.binding.apply(input); } - fn read(&mut self) -> i32 { + fn read(&mut self) -> bool { let value = self.binding.read(); - if self.prev_value == 0 { + if !self.prev_value { self.prev_value = value; return value; } self.prev_value = value; - 0 + false } fn binding(&self) -> InputKind { @@ -504,4 +543,4 @@ where } } -impl BindingExt for T where T: Binding {} +impl BindingExt for T where T: Binding {} diff --git a/ivy-input/src/lib.rs b/ivy-input/src/lib.rs index 18f355b9..ada88941 100644 --- a/ivy-input/src/lib.rs +++ b/ivy-input/src/lib.rs @@ -5,13 +5,11 @@ pub mod layer; pub mod types; mod vector; -pub use bindings::*; - use std::collections::HashMap; +pub use bindings::*; use flax::{component::ComponentValue, Component, EntityRef}; use glam::{IVec2, IVec3, Vec2, Vec3}; - use types::{InputEvent, InputKind}; pub struct InputState { @@ -36,6 +34,7 @@ impl InputState { pub fn apply(&mut self, event: &InputEvent) { for activation in self.activations.iter_mut() { match activation { + ActionKind::Boolean(_, mapping) => mapping.apply(event), ActionKind::Integral(_, mapping) => mapping.apply(event), ActionKind::Scalar(_, mapping) => mapping.apply(event), ActionKind::Vector2(_, mapping) => mapping.apply(event), @@ -49,6 +48,9 @@ impl InputState { pub fn update(&mut self, entity: &EntityRef) -> anyhow::Result<()> { for activation in &mut self.activations { match activation { + ActionKind::Boolean(target, m) => { + m.update(*target, entity)?; + } ActionKind::Integral(target, m) => { m.update(*target, entity)?; } @@ -81,6 +83,7 @@ impl Default for InputState { } pub enum ActionKind { + Boolean(Component, Action), Integral(Component, Action), Scalar(Component, Action), Vector2(Component, Action), @@ -89,6 +92,12 @@ pub enum ActionKind { IVector3(Component, Action), } +impl From<(Component, Action)> for ActionKind { + fn from(v: (Component, Action)) -> Self { + Self::Boolean(v.0, v.1) + } +} + impl From<(Component, Action)> for ActionKind { fn from(v: (Component, Action)) -> Self { Self::Integral(v.0, v.1) @@ -126,7 +135,7 @@ impl From<(Component, Action)> for ActionKind { } pub struct Action { - bindings: HashMap>>, + bindings: HashMap>>, } impl Action { @@ -136,15 +145,19 @@ impl Action { } } - pub fn add(&mut self, action: impl 'static + Binding) -> &mut Self { - self.bindings - .insert(action.binding(), Box::new(action) as Box>); + pub fn add(&mut self, action: impl 'static + Binding) -> &mut Self { + self.bindings.insert( + action.binding(), + Box::new(action) as Box>, + ); self } - pub fn with_binding(mut self, action: impl 'static + Binding) -> Self { - self.bindings - .insert(action.binding(), Box::new(action) as Box>); + pub fn with_binding(mut self, action: impl 'static + Binding) -> Self { + self.bindings.insert( + action.binding(), + Box::new(action) as Box>, + ); self } @@ -196,6 +209,14 @@ impl Stimulus for f32 { } } +impl Stimulus for bool { + const ZERO: Self = false; + + fn combine(&self, other: &Self) -> Self { + *self || *other + } +} + impl Stimulus for i32 { const ZERO: Self = 0; diff --git a/ivy-physics/src/lib.rs b/ivy-physics/src/lib.rs index c14a769f..645c6a38 100644 --- a/ivy-physics/src/lib.rs +++ b/ivy-physics/src/lib.rs @@ -13,5 +13,4 @@ pub use effector::*; pub use error::*; pub use gltf::*; pub use plugin::*; - pub use rapier3d; diff --git a/ivy-physics/src/plugin.rs b/ivy-physics/src/plugin.rs index 7e41c5c7..76b57fbd 100644 --- a/ivy-physics/src/plugin.rs +++ b/ivy-physics/src/plugin.rs @@ -1,3 +1,11 @@ +use flax::World; +use glam::Vec3; +use ivy_assets::AssetCache; +use ivy_core::{ + components::engine, + update_layer::{Plugin, ScheduleSetBuilder}, +}; + use crate::{ components::{gravity, physics_state}, state::{PhysicsState, PhysicsStateConfiguration}, @@ -7,13 +15,6 @@ use crate::{ unregister_bodies_system, unregister_colliders_system, update_bodies_system, }, }; -use flax::World; -use glam::Vec3; -use ivy_assets::AssetCache; -use ivy_core::{ - components::engine, - update_layer::{Plugin, ScheduleSetBuilder}, -}; #[derive(Default)] pub struct GizmoSettings { diff --git a/ivy-physics/src/state.rs b/ivy-physics/src/state.rs index 627fadeb..c1474c7e 100644 --- a/ivy-physics/src/state.rs +++ b/ivy-physics/src/state.rs @@ -1,3 +1,5 @@ +use flax::{Component, ComponentMut, Entity, Fetch, QueryBorrow}; +use glam::{Quat, Vec3}; use ivy_core::components::{position, rotation}; use nalgebra::Isometry3; use rapier3d::prelude::{ @@ -7,9 +9,6 @@ use rapier3d::prelude::{ RigidBodyHandle, RigidBodySet, }; -use flax::{Component, ComponentMut, Entity, Fetch, QueryBorrow}; -use glam::{Quat, Vec3}; - use crate::components::{angular_velocity, velocity}; #[derive(Debug, Clone)] diff --git a/ivy-physics/src/systems.rs b/ivy-physics/src/systems.rs index 5f4f7940..0e90e4c3 100644 --- a/ivy-physics/src/systems.rs +++ b/ivy-physics/src/systems.rs @@ -1,9 +1,5 @@ use core::f32; -use crate::{ - components::*, - state::{BodyDynamicsQuery, BodyDynamicsQueryMut, PhysicsState}, -}; use anyhow::Context; use flax::{ components::child_of, entity_ids, events::EventSubscriber, fetch::Copied, filter::ChangeFilter, @@ -26,6 +22,11 @@ use rapier3d::{ }, }; +use crate::{ + components::*, + state::{BodyDynamicsQuery, BodyDynamicsQueryMut, PhysicsState}, +}; + #[allow(clippy::type_complexity)] pub fn register_bodies_system() -> BoxedSystem { System::builder() diff --git a/ivy-ui/src/layer.rs b/ivy-ui/src/layer.rs index 0e829ea4..461fc009 100644 --- a/ivy-ui/src/layer.rs +++ b/ivy-ui/src/layer.rs @@ -1,12 +1,17 @@ -use std::{cell::RefCell, ops::Deref, rc::Rc}; +use std::{cell::RefCell, convert::identity, ops::Deref, rc::Rc}; use flax::World; use ivy_assets::AssetCache; use ivy_core::{ - app::TickEvent, layer::events::EventRegisterContext, profiling::profile_function, Layer, + app::TickEvent, components::request_capture_mouse, layer::events::EventRegisterContext, + profiling::profile_function, Layer, WorldExt, }; use ivy_input::types::InputEvent; -use ivy_wgpu::events::{ApplicationReady, ResizedEvent}; +use ivy_wgpu::{ + components::{main_window, window}, + driver::WindowHandle, + events::{ApplicationReady, ResizedEvent}, +}; use violet::{ core::{declare_atom, ScopeRef, Widget}, glam::vec2, @@ -38,6 +43,7 @@ declare_atom! { pub struct UiInputLayer { instance: Rc>, + window: Option, } impl UiInputLayer { @@ -45,10 +51,19 @@ impl UiInputLayer { let instance = AppInstance::new(root); let instance = Rc::new(RefCell::new(instance)); - Self { instance } + Self { + instance, + window: None, + } } - fn on_ready(&mut self, _: &mut World, _: &AssetCache) -> anyhow::Result<()> { + fn on_ready(&mut self, engine_world: &mut World, _: &AssetCache) -> anyhow::Result<()> { + let main_window = engine_world.by_tag(main_window()); + + if let Some(main_window) = main_window { + self.window = Some(main_window.get(window())?.clone()); + } + Ok(()) } @@ -61,6 +76,10 @@ impl UiInputLayer { profile_function!(); let instance = &mut *self.instance.deref().borrow_mut(); + instance + .input_state + .update_external_focus(&mut instance.frame); + // TODO: modifiers changed let mut captured = match event { InputEvent::Keyboard(keyboard_input) => instance.input_state.on_keyboard_input( @@ -94,7 +113,15 @@ impl UiInputLayer { InputEvent::Focus(_) => false, }; - if let Some(focused) = instance.input_state.focused_entity(instance.frame.world()) { + if let Some(focused) = instance.input_state.get_focused(instance.frame.world()) { + let capture_mouse = focused + .get_copy(request_capture_mouse()) + .is_ok_and(identity); + + if let Some(window) = &self.window { + window.set_cursor_lock(capture_mouse); + } + if let Ok(mut handler) = focused.get_mut(on_input_event()) { handler( &ScopeRef::new(&instance.frame, focused), diff --git a/ivy-ui/src/lib.rs b/ivy-ui/src/lib.rs index 744ac420..3ab7c647 100644 --- a/ivy-ui/src/lib.rs +++ b/ivy-ui/src/lib.rs @@ -1,9 +1,10 @@ use std::{cell::RefCell, rc::Rc}; + use violet::wgpu::app::AppInstance; -pub mod layer; -pub mod node; pub mod components; pub mod image; +pub mod layer; +pub mod node; pub type SharedUiInstance = Rc>; diff --git a/ivy-wgpu-types/src/lib.rs b/ivy-wgpu-types/src/lib.rs index b5afd2f8..a6bd9299 100644 --- a/ivy-wgpu-types/src/lib.rs +++ b/ivy-wgpu-types/src/lib.rs @@ -1,11 +1,11 @@ pub mod allocator; mod bind_groups; mod gpu; +pub mod mipmap; pub mod multi_buffer; pub mod shader; pub mod texture; pub mod typed_buffer; -pub mod mipmap; pub use bind_groups::{BindGroupBuilder, BindGroupLayoutBuilder}; pub use gpu::{Gpu, Surface}; diff --git a/ivy-wgpu-types/src/shader.rs b/ivy-wgpu-types/src/shader.rs index e4a1bb05..0334ec2b 100644 --- a/ivy-wgpu-types/src/shader.rs +++ b/ivy-wgpu-types/src/shader.rs @@ -1,10 +1,11 @@ -use crate::Gpu; use itertools::Itertools; use wgpu::{ BindGroupLayout, DepthBiasState, Face, FrontFace, PipelineLayoutDescriptor, RenderPipeline, TextureFormat, VertexBufferLayout, }; +use crate::Gpu; + #[derive(Debug, Clone, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Culling { diff --git a/ivy-wgpu-types/src/texture.rs b/ivy-wgpu-types/src/texture.rs index 6df96db8..1eb627bd 100644 --- a/ivy-wgpu-types/src/texture.rs +++ b/ivy-wgpu-types/src/texture.rs @@ -10,9 +10,8 @@ use wgpu::{ TextureFormat, TextureUsages, }; -use crate::{mipmap::generate_mipmaps, TypedBuffer}; - use super::Gpu; +use crate::{mipmap::generate_mipmaps, TypedBuffer}; #[derive(Debug, Clone)] pub struct TextureFromImageDesc { diff --git a/ivy-wgpu/src/driver.rs b/ivy-wgpu/src/driver.rs index 1c8a7e1f..4e16e2eb 100644 --- a/ivy-wgpu/src/driver.rs +++ b/ivy-wgpu/src/driver.rs @@ -358,7 +358,7 @@ impl WindowHandle { &self.window } - pub fn set_cursor_lock(&mut self, lock: bool) { + pub fn set_cursor_lock(&self, lock: bool) { self.cursor_lock .borrow_mut() .set_cursor_lock(&self.window, lock) diff --git a/ivy-wgpu/src/gltf/node.rs b/ivy-wgpu/src/gltf/node.rs index 139597f9..8b137891 100644 --- a/ivy-wgpu/src/gltf/node.rs +++ b/ivy-wgpu/src/gltf/node.rs @@ -1,2 +1 @@ - diff --git a/ivy-wgpu/src/mesh.rs b/ivy-wgpu/src/mesh.rs index ce1f4bda..1e03b4a7 100644 --- a/ivy-wgpu/src/mesh.rs +++ b/ivy-wgpu/src/mesh.rs @@ -9,9 +9,8 @@ use wgpu::{ util::DeviceExt, vertex_attr_array, Buffer, RenderPass, VertexAttribute, VertexBufferLayout, }; -use crate::material::PbrMaterial; - use super::Gpu; +use crate::material::PbrMaterial; #[repr(C)] #[derive(bytemuck::Pod, bytemuck::Zeroable, Copy, Debug, Clone)] diff --git a/ivy-wgpu/src/mesh_buffer.rs b/ivy-wgpu/src/mesh_buffer.rs index 785c6bee..6ae5ff42 100644 --- a/ivy-wgpu/src/mesh_buffer.rs +++ b/ivy-wgpu/src/mesh_buffer.rs @@ -4,12 +4,11 @@ use bytemuck::Pod; use itertools::Itertools; use wgpu::{BufferUsages, RenderPass}; -use crate::mesh::Vertex; - use super::{ types::multi_buffer::{MultiBuffer, SubBuffer}, Gpu, }; +use crate::mesh::Vertex; pub struct MeshBufferInner {} diff --git a/ivy-wgpu/src/renderer/gizmos_renderer.rs b/ivy-wgpu/src/renderer/gizmos_renderer.rs index 421b24dc..d2d1a0e8 100644 --- a/ivy-wgpu/src/renderer/gizmos_renderer.rs +++ b/ivy-wgpu/src/renderer/gizmos_renderer.rs @@ -15,6 +15,7 @@ use wgpu::{ SamplerDescriptor, ShaderStages, TextureUsages, }; +use super::{get_main_camera_data, CameraData}; use crate::{ mesh::{Mesh, Vertex, VertexDesc}, rendergraph::{ @@ -22,8 +23,6 @@ use crate::{ }, }; -use super::{get_main_camera_data, CameraData}; - pub struct GizmosRendererNode { mesh: Mesh, shader: Option, diff --git a/ivy-wgpu/src/renderer/light_manager.rs b/ivy-wgpu/src/renderer/light_manager.rs index f079fcb0..fb251745 100644 --- a/ivy-wgpu/src/renderer/light_manager.rs +++ b/ivy-wgpu/src/renderer/light_manager.rs @@ -3,21 +3,19 @@ use std::iter::repeat; use flax::{FetchExt, Query}; use glam::{Vec3, Vec4}; use itertools::Itertools; -use ivy_core::{components::world_transform, palette::num::Trigonometry, to_linear_vec3}; +use ivy_core::{components::world_transform, to_linear_vec3}; use ivy_wgpu_types::{BindGroupBuilder, BindGroupLayoutBuilder, Gpu, TypedBuffer}; -use ordered_float::Float; use wgpu::{ BindGroup, BindGroupLayout, BufferUsages, SamplerDescriptor, ShaderStages, TextureViewDescriptor, TextureViewDimension, }; +use super::shadowmapping::LightShadowData; use crate::{ components::{light_kind, light_params, light_shadow_data}, rendergraph::{BufferHandle, NodeUpdateContext, TextureHandle}, }; -use super::shadowmapping::LightShadowData; - pub struct LightManager { layout: BindGroupLayout, bind_group: Option, diff --git a/ivy-wgpu/src/renderer/mesh_renderer.rs b/ivy-wgpu/src/renderer/mesh_renderer.rs index cff8665c..885e6d49 100644 --- a/ivy-wgpu/src/renderer/mesh_renderer.rs +++ b/ivy-wgpu/src/renderer/mesh_renderer.rs @@ -22,6 +22,7 @@ use ivy_wgpu_types::shader::Culling; use slab::Slab; use wgpu::{BindGroup, BindGroupLayout, BufferUsages, RenderPass, ShaderStages}; +use super::{CameraRenderer, ObjectData, TargetDesc}; use crate::{ components::{material, mesh}, material::PbrMaterial, @@ -36,8 +37,6 @@ use crate::{ Gpu, }; -use super::{CameraRenderer, ObjectData, TargetDesc}; - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct BatchKey { pub shader: Asset, diff --git a/ivy-wgpu/src/renderer/mod.rs b/ivy-wgpu/src/renderer/mod.rs index 6720713f..a9a74f23 100644 --- a/ivy-wgpu/src/renderer/mod.rs +++ b/ivy-wgpu/src/renderer/mod.rs @@ -17,6 +17,7 @@ use ivy_core::{ to_linear_vec3, Bundle, }; use ivy_wgpu_types::shader::TargetDesc; +pub use light_manager::LightManager; use wgpu::{ AddressMode, BindGroup, BindGroupLayout, BufferUsages, Extent3d, FilterMode, Operations, Queue, RenderPass, RenderPassColorAttachment, RenderPassDescriptor, ShaderStages, TextureDescriptor, @@ -34,8 +35,6 @@ use crate::{ Gpu, }; -pub use light_manager::LightManager; - pub struct MsaaResolve { final_color: TextureHandle, resolve_target: TextureHandle, diff --git a/ivy-wgpu/src/renderer/shadowmapping.rs b/ivy-wgpu/src/renderer/shadowmapping.rs index c8d07ea9..43d56a33 100644 --- a/ivy-wgpu/src/renderer/shadowmapping.rs +++ b/ivy-wgpu/src/renderer/shadowmapping.rs @@ -1,19 +1,5 @@ use std::{mem::size_of, sync::Arc}; -use crate::{ - components::{cast_shadow, light_kind, light_params, projection_matrix, shadow_pass}, - light::{LightKind, LightParams}, - renderer::{ - mesh_renderer::MeshRenderer, CameraRenderer, RenderContext, RendererStore, UpdateContext, - }, - rendergraph::{ - BufferHandle, Dependency, Node, NodeExecutionContext, NodeUpdateContext, TextureHandle, - UpdateResult, - }, - shader_library::ShaderLibrary, - types::{shader::TargetDesc, BindGroupBuilder, BindGroupLayoutBuilder}, - Gpu, -}; use flax::{entity_ids, filter::With, Component, EntityIds, FetchExt, Query, World}; use glam::{vec2, vec3, Mat4, Vec2, Vec3, Vec4Swizzles}; use itertools::{izip, Itertools}; @@ -30,9 +16,23 @@ use wgpu::{ TextureViewDimension, }; -use crate::components::light_shadow_data; - use super::skinned_mesh_renderer::SkinnedMeshRenderer; +use crate::{ + components::{ + cast_shadow, light_kind, light_params, light_shadow_data, projection_matrix, shadow_pass, + }, + light::{LightKind, LightParams}, + renderer::{ + mesh_renderer::MeshRenderer, CameraRenderer, RenderContext, RendererStore, UpdateContext, + }, + rendergraph::{ + BufferHandle, Dependency, Node, NodeExecutionContext, NodeUpdateContext, TextureHandle, + UpdateResult, + }, + shader_library::ShaderLibrary, + types::{shader::TargetDesc, BindGroupBuilder, BindGroupLayoutBuilder}, + Gpu, +}; #[derive(Debug, Clone, Copy)] pub struct LightShadowData { diff --git a/ivy-wgpu/src/renderer/skinned_mesh_renderer.rs b/ivy-wgpu/src/renderer/skinned_mesh_renderer.rs index 7b747afd..2bd74755 100644 --- a/ivy-wgpu/src/renderer/skinned_mesh_renderer.rs +++ b/ivy-wgpu/src/renderer/skinned_mesh_renderer.rs @@ -13,10 +13,7 @@ use flax::{ use glam::Mat4; use itertools::Itertools; use ivy_assets::{map::AssetMap, stored::Handle, Asset, AssetCache}; -use ivy_core::{ - components::world_transform, - profiling::profile_function, -}; +use ivy_core::{components::world_transform, profiling::profile_function}; use ivy_gltf::{ animation::{player::Animator, skin::Skin}, components::{animator, skin}, @@ -25,6 +22,7 @@ use ivy_wgpu_types::shader::{Culling, TargetDesc}; use slab::Slab; use wgpu::{BindGroup, BindGroupLayout, BufferUsages, DepthBiasState, RenderPass, ShaderStages}; +use super::{mesh_renderer::ShaderFactory, CameraRenderer, ObjectData}; use crate::{ components::{material, mesh}, material::PbrMaterial, @@ -39,8 +37,6 @@ use crate::{ Gpu, }; -use super::{mesh_renderer::ShaderFactory, CameraRenderer, ObjectData}; - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct BatchKey { pub skin: Asset, diff --git a/ivy-wgpu/src/rendergraph/mod.rs b/ivy-wgpu/src/rendergraph/mod.rs index a499713a..ebdb909b 100644 --- a/ivy-wgpu/src/rendergraph/mod.rs +++ b/ivy-wgpu/src/rendergraph/mod.rs @@ -1,17 +1,16 @@ mod resources; -use flax::World; -use ivy_assets::AssetCache; -use ivy_core::profiling::{profile_function, profile_scope}; -pub use resources::*; -use slotmap::{new_key_type, SecondaryMap, SlotMap}; - use std::{ collections::{BTreeSet, HashMap}, mem, }; +use flax::World; use itertools::Itertools; +use ivy_assets::AssetCache; +use ivy_core::profiling::{profile_function, profile_scope}; use ivy_wgpu_types::Gpu; +pub use resources::*; +use slotmap::{new_key_type, SecondaryMap, SlotMap}; use wgpu::{Buffer, BufferUsages, CommandEncoder, Queue, Texture, TextureUsages}; pub struct NodeExecutionContext<'a> { diff --git a/ivy-wgpu/src/rendergraph/resources.rs b/ivy-wgpu/src/rendergraph/resources.rs index 01c8b119..3ec3ac8f 100644 --- a/ivy-wgpu/src/rendergraph/resources.rs +++ b/ivy-wgpu/src/rendergraph/resources.rs @@ -4,7 +4,6 @@ use std::{ sync::Arc, }; -use itertools::Itertools; use ivy_wgpu_types::Gpu; use slotmap::{SecondaryMap, SlotMap}; use wgpu::{ @@ -12,9 +11,8 @@ use wgpu::{ TextureDimension, TextureFormat, TextureUsages, }; -use crate::shader_library::ShaderLibrary; - use super::{Dependency, Node, NodeId, ResourceHandle}; +use crate::shader_library::ShaderLibrary; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub(crate) struct Lifetime { diff --git a/ivy-wgpu/src/shaders.rs b/ivy-wgpu/src/shaders.rs index 94877d4b..c32ac7c8 100644 --- a/ivy-wgpu/src/shaders.rs +++ b/ivy-wgpu/src/shaders.rs @@ -12,10 +12,7 @@ pub struct PbrShaderDesc; impl AssetDesc for PbrShaderDesc { type Error = Infallible; - fn create( - &self, - assets: &ivy_assets::AssetCache, - ) -> Result, Self::Error> { + fn create(&self, assets: &ivy_assets::AssetCache) -> Result, Self::Error> { Ok(assets.insert(ShaderPass { label: "pbr_shader".into(), path: "../../assets/shader/pbr.wgsl".into(), @@ -32,10 +29,7 @@ pub struct SkinnedPbrShaderDesc; impl AssetDesc for SkinnedPbrShaderDesc { type Error = Infallible; - fn create( - &self, - assets: &ivy_assets::AssetCache, - ) -> Result, Self::Error> { + fn create(&self, assets: &ivy_assets::AssetCache) -> Result, Self::Error> { Ok(assets.insert(ShaderPass { label: "skinned_pbr_shader".into(), path: "../../assets/shaders/skinned_pbr.wgsl".into(), @@ -51,10 +45,7 @@ pub struct ShadowShaderDesc; impl AssetDesc for ShadowShaderDesc { type Error = Infallible; - fn create( - &self, - assets: &ivy_assets::AssetCache, - ) -> Result, Self::Error> { + fn create(&self, assets: &ivy_assets::AssetCache) -> Result, Self::Error> { Ok(assets.insert(ShaderPass { label: "shadow_shader".into(), path: "../../assets/shaders/shadow.wgsl".into(), @@ -70,10 +61,7 @@ pub struct SkinnedShadowShaderDesc; impl AssetDesc for SkinnedShadowShaderDesc { type Error = Infallible; - fn create( - &self, - assets: &ivy_assets::AssetCache, - ) -> Result, Self::Error> { + fn create(&self, assets: &ivy_assets::AssetCache) -> Result, Self::Error> { Ok(assets.insert(ShaderPass { label: "skinned_shadow_shader".into(), path: "../../assets/shaders/skinned_shadow.wgsl".into(), diff --git a/src/lib.rs b/src/lib.rs index 050a8380..5f1cce79 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,22 +34,20 @@ //! //! See the documentation for [`ivy-core::Layer`] +pub use flax; pub use ivy_assets; /// Rexports pub use ivy_core; +pub use ivy_core::{components::*, App, Extent, Layer}; pub use ivy_game; pub use ivy_gltf; pub use ivy_graphics; pub use ivy_input as input; +pub use ivy_input::InputState; pub use ivy_physics as physics; +pub use ivy_physics::RigidBodyBundle; pub use ivy_postprocessing as postprocessing; pub use ivy_random as random; pub use ivy_scene as scene; pub use ivy_ui; pub use ivy_wgpu; - -pub use ivy_core::{components::*, App, Extent, Layer}; -pub use ivy_input::InputState; -pub use ivy_physics::RigidBodyBundle; - -pub use flax; diff --git a/violet b/violet index b2a3106a..1929f163 160000 --- a/violet +++ b/violet @@ -1 +1 @@ -Subproject commit b2a3106aee1eb6a1aaedfa44b3e058306f09530b +Subproject commit 1929f163acfd133961fca4b0d403f8bad050b94f