Compare commits

...

3 Commits

Author SHA1 Message Date
SeanOMik 4816b7333e
Make system_update_world_transforms also update world transforms for SceneGraphs
CI / build (push) Failing after 2m53s Details
Before this couldn't be done since lyra-scene could not depend on lyra-resource, it would have caused a cyclic dependency. The last commit, where I created lyra-gltf from code inside lyra-resource, made this possible
2024-11-01 19:45:29 -04:00
SeanOMik 5542467d7e
separate GLTF loader to its own crate 2024-11-01 12:09:01 -04:00
SeanOMik 3ce9ab6fb3
move crates into 'crates' folder 2024-11-01 11:17:36 -04:00
287 changed files with 471 additions and 365 deletions

4
.gitmodules vendored
View File

@ -1,6 +1,6 @@
[submodule "lyra-scripting/elua"] [submodule "lyra-scripting/elua"]
path = lyra-scripting/elua path = crates/lyra-scripting/elua
url = ../elua.git # git@git.seanomik.net:SeanOMik/elua.git url = ../elua.git # git@git.seanomik.net:SeanOMik/elua.git
[submodule "wgsl-preprocessor"] [submodule "wgsl-preprocessor"]
path = wgsl-preprocessor path = crates/wgsl-preprocessor
url = git@git.seanomik.net:SeanOMik/wgsl-preprocessor.git url = git@git.seanomik.net:SeanOMik/wgsl-preprocessor.git

44
Cargo.lock generated
View File

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "ab_glyph" name = "ab_glyph"
@ -854,6 +854,16 @@ dependencies = [
"crypto-common", "crypto-common",
] ]
[[package]]
name = "dim_2d"
version = "0.1.0"
dependencies = [
"anyhow",
"async-std",
"lyra-engine",
"tracing",
]
[[package]] [[package]]
name = "dispatch" name = "dispatch"
version = "0.2.0" version = "0.2.0"
@ -1819,6 +1829,7 @@ dependencies = [
"itertools 0.13.0", "itertools 0.13.0",
"lyra-ecs", "lyra-ecs",
"lyra-game-derive", "lyra-game-derive",
"lyra-gltf",
"lyra-math", "lyra-math",
"lyra-reflect", "lyra-reflect",
"lyra-resource", "lyra-resource",
@ -1850,6 +1861,34 @@ dependencies = [
"syn 2.0.77", "syn 2.0.77",
] ]
[[package]]
name = "lyra-gltf"
version = "0.0.1"
dependencies = [
"anyhow",
"async-std",
"base64 0.21.7",
"crossbeam",
"glam",
"gltf",
"image",
"infer",
"instant",
"lyra-ecs",
"lyra-math",
"lyra-reflect",
"lyra-resource",
"lyra-scene",
"mime",
"notify",
"notify-debouncer-full",
"percent-encoding",
"rand",
"thiserror",
"tracing",
"uuid",
]
[[package]] [[package]]
name = "lyra-math" name = "lyra-math"
version = "0.1.0" version = "0.1.0"
@ -1884,14 +1923,12 @@ dependencies = [
"base64 0.21.7", "base64 0.21.7",
"crossbeam", "crossbeam",
"glam", "glam",
"gltf",
"image", "image",
"infer", "infer",
"instant", "instant",
"lyra-ecs", "lyra-ecs",
"lyra-math", "lyra-math",
"lyra-reflect", "lyra-reflect",
"lyra-scene",
"mime", "mime",
"notify", "notify",
"notify-debouncer-full", "notify-debouncer-full",
@ -1910,6 +1947,7 @@ dependencies = [
"lyra-ecs", "lyra-ecs",
"lyra-math", "lyra-math",
"lyra-reflect", "lyra-reflect",
"lyra-resource",
] ]
[[package]] [[package]]

View File

@ -5,20 +5,15 @@ edition = "2021"
[workspace] [workspace]
members = [ members = [
"lyra-resource", "crates/*",
"lyra-ecs",
"lyra-reflect", "examples/2d",
"lyra-scripting",
"lyra-game",
"lyra-math",
"lyra-scene",
"examples/testbed",
"examples/many-lights",
"examples/fixed-timestep-rotating-model", "examples/fixed-timestep-rotating-model",
"examples/lua-scripting", "examples/lua-scripting",
"examples/simple_scene", "examples/many-lights",
"examples/shadows", "examples/shadows",
"examples/simple_scene",
"examples/testbed",
] ]
[features] [features]
@ -27,11 +22,11 @@ lua_scripting = ["scripting", "lyra-scripting/lua"]
tracy = ["lyra-game/tracy"] tracy = ["lyra-game/tracy"]
[dependencies] [dependencies]
lyra-game = { path = "lyra-game" } lyra-game = { path = "crates/lyra-game" }
lyra-scripting = { path = "lyra-scripting", optional = true } lyra-scripting = { path = "crates/lyra-scripting", optional = true }
#[profile.dev] #[profile.dev]
#opt-level = 1 #opt-level = 1
[profile.release] [profile.release]
debug = true debug = true

View File

@ -90,7 +90,7 @@ impl<T: Component> AsQuery for Changed<T> {
type Query = Self; type Query = Self;
} }
impl<'a, T: Component> Filter for Changed<T> { } impl<T: Component> Filter for Changed<T> { }
impl<T: Component> AsFilter for Changed<T> { impl<T: Component> AsFilter for Changed<T> {
type Filter = Self; type Filter = Self;

View File

@ -1,6 +1,8 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use crate::{query::{AsQuery, Query}, Archetype, Component, DynTypeId, World}; use crate::{query::{AsFilter, AsQuery, Filter, Query}, Archetype, Component, DynTypeId, World};
use super::StaticFetcher;
/// A filter query that fetches when the entity has the component `C`. /// A filter query that fetches when the entity has the component `C`.
/// ///
@ -20,9 +22,8 @@ impl<C: Component> Clone for Has<C> {
} }
impl<C: Component> Query for Has<C> { impl<C: Component> Query for Has<C> {
type Item<'a> = (); type Item<'a> = bool;
type Fetch<'a> = StaticFetcher<bool>;
type Fetch<'a> = ();
fn new() -> Self { fn new() -> Self {
Has { Has {
@ -35,10 +36,17 @@ impl<C: Component> Query for Has<C> {
} }
unsafe fn fetch<'a>(&self, _world: &'a World, _: &'a Archetype, _: crate::Tick) -> Self::Fetch<'a> { unsafe fn fetch<'a>(&self, _world: &'a World, _: &'a Archetype, _: crate::Tick) -> Self::Fetch<'a> {
() // if fetch is called, it means that 'can_visit_archetype' returned true
StaticFetcher::new(true)
} }
} }
impl<C: Component> AsQuery for Has<C> { impl<C: Component> AsQuery for Has<C> {
type Query = Self; type Query = Self;
}
impl<C: Component> Filter for Has<C> { }
impl<C: Component> AsFilter for Has<C> {
type Filter = Self;
} }

View File

@ -0,0 +1,44 @@
mod has;
use std::marker::PhantomData;
pub use has::*;
mod or;
pub use or::*;
mod not;
pub use not::*;
mod changed;
pub use changed::*;
use super::Fetch;
/// A fetcher that just returns a provided value
pub struct StaticFetcher<T: Clone> {
value: T,
}
impl<'a, T: Clone> StaticFetcher<T> {
pub fn new(value: T) -> Self {
Self {
value
}
}
}
impl<'a, T> Fetch<'a> for StaticFetcher<T>
where
T: Clone + 'a,
{
type Item = T;
fn dangling() -> Self {
unreachable!()
}
unsafe fn get_item(&mut self, _: crate::world::ArchetypeEntityId) -> Self::Item {
self.value.clone()
}
}

View File

@ -1,4 +1,6 @@
use crate::{query::{AsQuery, Query}, Archetype, World}; use crate::{query::{AsFilter, AsQuery, Filter, Query}, Archetype, World};
use super::StaticFetcher;
/// A filter query that fetches the inverse of `Q`. /// A filter query that fetches the inverse of `Q`.
/// ///
@ -20,9 +22,8 @@ pub struct Not<Q: Query> {
} }
impl<Q: Query> Query for Not<Q> { impl<Q: Query> Query for Not<Q> {
type Item<'a> = (); type Item<'a> = bool;
type Fetch<'a> = StaticFetcher<bool>;
type Fetch<'a> = ();
fn new() -> Self { fn new() -> Self {
Not { Not {
@ -35,10 +36,17 @@ impl<Q: Query> Query for Not<Q> {
} }
unsafe fn fetch<'a>(&self, _world: &'a World, _: &'a Archetype, _: crate::Tick) -> Self::Fetch<'a> { unsafe fn fetch<'a>(&self, _world: &'a World, _: &'a Archetype, _: crate::Tick) -> Self::Fetch<'a> {
() // if fetch is called, it means that 'can_visit_archetype' returned true
StaticFetcher::new(true)
} }
} }
impl<Q: Query> AsQuery for Not<Q> { impl<Q: Query> AsQuery for Not<Q> {
type Query = Self; type Query = Self;
}
impl<Q: Query> Filter for Not<Q> { }
impl<Q: Query> AsFilter for Not<Q> {
type Filter = Self;
} }

View File

@ -10,6 +10,7 @@ lyra-ecs = { path = "../lyra-ecs", features = [ "math" ] }
lyra-reflect = { path = "../lyra-reflect", features = [ "math" ] } lyra-reflect = { path = "../lyra-reflect", features = [ "math" ] }
lyra-math = { path = "../lyra-math" } lyra-math = { path = "../lyra-math" }
lyra-scene = { path = "../lyra-scene" } lyra-scene = { path = "../lyra-scene" }
lyra-gltf = { path = "../lyra-gltf" }
wgsl_preprocessor = { path = "../wgsl-preprocessor" } wgsl_preprocessor = { path = "../wgsl-preprocessor" }
winit = "0.30.5" winit = "0.30.5"

View File

@ -29,5 +29,6 @@ pub use lyra_resource as assets;
pub use lyra_ecs as ecs; pub use lyra_ecs as ecs;
pub use lyra_math as math; pub use lyra_math as math;
pub use lyra_reflect as reflect; pub use lyra_reflect as reflect;
pub use lyra_gltf as gltf;
pub use plugin::DefaultPlugins; pub use plugin::DefaultPlugins;

View File

@ -1,4 +1,6 @@
use lyra_ecs::query::ResMut;
use lyra_ecs::CommandQueue; use lyra_ecs::CommandQueue;
use lyra_gltf::GltfLoader;
use lyra_resource::ResourceManager; use lyra_resource::ResourceManager;
use crate::game::App; use crate::game::App;
@ -113,6 +115,7 @@ impl Plugin for DefaultPlugins {
CommandQueuePlugin.setup(app); CommandQueuePlugin.setup(app);
InputPlugin.setup(app); InputPlugin.setup(app);
ResourceManagerPlugin.setup(app); ResourceManagerPlugin.setup(app);
GltfPlugin.setup(app);
WindowPlugin::default().setup(app); WindowPlugin::default().setup(app);
DeltaTimePlugin.setup(app); DeltaTimePlugin.setup(app);
} }
@ -127,4 +130,14 @@ impl Plugin for CommandQueuePlugin {
fn setup(&mut self, app: &mut App) { fn setup(&mut self, app: &mut App) {
app.world.add_resource(CommandQueue::default()); app.world.add_resource(CommandQueue::default());
} }
}
#[derive(Default)]
pub struct GltfPlugin;
impl Plugin for GltfPlugin {
fn setup(&mut self, app: &mut App) {
let man: ResMut<ResourceManager> = app.world.get_resource_or_default();
man.register_loader::<GltfLoader>();
}
} }

View File

Before

Width:  |  Height:  |  Size: 545 B

After

Width:  |  Height:  |  Size: 545 B

View File

@ -12,7 +12,8 @@ use lyra_ecs::{
Entity, ResourceObject, World, Entity, ResourceObject, World,
}; };
use lyra_game_derive::RenderGraphLabel; use lyra_game_derive::RenderGraphLabel;
use lyra_resource::{gltf::Mesh, ResHandle}; use lyra_resource::ResHandle;
use lyra_gltf::Mesh;
use lyra_scene::SceneGraph; use lyra_scene::SceneGraph;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use tracing::{debug, instrument}; use tracing::{debug, instrument};
@ -93,10 +94,10 @@ impl MeshPrepNode {
if let Some(index_buffer) = buffers.buffer_indices.as_ref() { if let Some(index_buffer) = buffers.buffer_indices.as_ref() {
let aligned_indices = match mesh.indices.as_ref().unwrap() { let aligned_indices = match mesh.indices.as_ref().unwrap() {
// U16 indices need to be aligned to u32, for wpgu, which are 4-bytes in size. // U16 indices need to be aligned to u32, for wpgu, which are 4-bytes in size.
lyra_resource::gltf::MeshIndices::U16(v) => { lyra_gltf::MeshIndices::U16(v) => {
bytemuck::pod_align_to::<u16, u32>(v).1 bytemuck::pod_align_to::<u16, u32>(v).1
} }
lyra_resource::gltf::MeshIndices::U32(v) => { lyra_gltf::MeshIndices::U32(v) => {
bytemuck::pod_align_to::<u32, u32>(v).1 bytemuck::pod_align_to::<u32, u32>(v).1
} }
}; };
@ -137,10 +138,10 @@ impl MeshPrepNode {
let indices = match mesh.indices.as_ref() { let indices = match mesh.indices.as_ref() {
Some(indices) => { Some(indices) => {
let (idx_type, len, contents) = match indices { let (idx_type, len, contents) = match indices {
lyra_resource::gltf::MeshIndices::U16(v) => { lyra_gltf::MeshIndices::U16(v) => {
(wgpu::IndexFormat::Uint16, v.len(), bytemuck::cast_slice(v)) (wgpu::IndexFormat::Uint16, v.len(), bytemuck::cast_slice(v))
} }
lyra_resource::gltf::MeshIndices::U32(v) => { lyra_gltf::MeshIndices::U32(v) => {
(wgpu::IndexFormat::Uint32, v.len(), bytemuck::cast_slice(v)) (wgpu::IndexFormat::Uint32, v.len(), bytemuck::cast_slice(v))
} }
}; };
@ -518,7 +519,7 @@ impl GpuMaterial {
device: &wgpu::Device, device: &wgpu::Device,
queue: &wgpu::Queue, queue: &wgpu::Queue,
layout: &Arc<wgpu::BindGroupLayout>, layout: &Arc<wgpu::BindGroupLayout>,
mat: &lyra_resource::gltf::Material, mat: &lyra_gltf::Material,
) -> Self { ) -> Self {
//let specular = mat.specular.as_ref().unwrap_or_default(); //let specular = mat.specular.as_ref().unwrap_or_default();
//let specular_ //let specular_

View File

@ -1,9 +1,8 @@
use lyra_ecs::{ use lyra_ecs::{
query::{ query::{
filter::{Has, Not, Or}, filter::Or,
Entities, TickOf, Entities,
}, },
relation::{ChildOf, RelationOriginComponent},
Component, Entity, Component, Entity,
}; };
use lyra_game_derive::RenderGraphLabel; use lyra_game_derive::RenderGraphLabel;
@ -64,7 +63,6 @@ fn update_transforms(
buffers: &mut TransformBuffers, buffers: &mut TransformBuffers,
parent_transform: Transform, parent_transform: Transform,
) { ) {
let current_tick = world.current_tick();
let mut component_queue = vec![]; let mut component_queue = vec![];
let view = world.view_iter::<( let view = world.view_iter::<(
@ -72,7 +70,7 @@ fn update_transforms(
Or<&WorldTransform, &Transform>, Or<&WorldTransform, &Transform>,
Option<&mut InterpTransform>, Option<&mut InterpTransform>,
Option<&TransformIndex>, Option<&TransformIndex>,
Option<(&ResHandle<SceneGraph>, TickOf<ResHandle<SceneGraph>>)>, Option<&ResHandle<SceneGraph>>,
)>(); )>();
for (entity, transform, interp_tran, transform_index, scene_graph) in view { for (entity, transform, interp_tran, transform_index, scene_graph) in view {
@ -141,20 +139,8 @@ fn update_transforms(
glam::Mat3::from_quat(transform.rotation), glam::Mat3::from_quat(transform.rotation),
); );
if let Some((scene, scene_tick)) = scene_graph { if let Some(scene) = scene_graph {
if let Some(mut scene) = scene.data_mut() { if let Some(mut scene) = scene.data_mut() {
if *scene_tick + 1 >= *current_tick {
// Must manually call the world transform update system for scenes
// TODO: Separate gltf from lyra-resource so lyra-scene can depend on resource to
// query for scenes in the system.
let view = scene.world().view::<(
Entities,
&mut WorldTransform,
&Transform,
Not<Has<RelationOriginComponent<ChildOf>>>,
)>();
lyra_scene::system_update_world_transforms(scene.world(), view).unwrap();
}
update_transforms( update_transforms(
device, device,

View File

@ -21,7 +21,7 @@ fn texture_to_render(device: &wgpu::Device, queue: &wgpu::Queue, bg_layout: &Arc
} }
impl MaterialSpecular { impl MaterialSpecular {
pub fn from_resource(device: &wgpu::Device, queue: &wgpu::Queue, bg_layout: Arc<wgpu::BindGroupLayout>, value: &lyra_resource::gltf::Specular) -> Self { pub fn from_resource(device: &wgpu::Device, queue: &wgpu::Queue, bg_layout: Arc<wgpu::BindGroupLayout>, value: &lyra_gltf::Specular) -> Self {
let tex = texture_to_render(device, queue, &bg_layout, &value.texture); let tex = texture_to_render(device, queue, &bg_layout, &value.texture);
let color_tex = texture_to_render(device, queue, &bg_layout, &value.color_texture); let color_tex = texture_to_render(device, queue, &bg_layout, &value.color_texture);
@ -46,7 +46,7 @@ pub struct Material {
} }
impl Material { impl Material {
pub fn from_resource(device: &wgpu::Device, queue: &wgpu::Queue, bg_layout: Arc<wgpu::BindGroupLayout>, value: &lyra_resource::gltf::Material) -> Self { pub fn from_resource(device: &wgpu::Device, queue: &wgpu::Queue, bg_layout: Arc<wgpu::BindGroupLayout>, value: &lyra_gltf::Material) -> Self {
let diffuse_texture = texture_to_render(device, queue, &bg_layout, &value.base_color_texture); let diffuse_texture = texture_to_render(device, queue, &bg_layout, &value.base_color_texture);
let specular = value.specular.as_ref().map(|s| MaterialSpecular::from_resource(device, queue, bg_layout.clone(), s)); let specular = value.specular.as_ref().map(|s| MaterialSpecular::from_resource(device, queue, bg_layout.clone(), s));

Some files were not shown because too many files have changed in this diff Show More