render: use WorldTransforms in the renderer
ci/woodpecker/push/debug Pipeline failed
Details
ci/woodpecker/push/debug Pipeline failed
Details
This commit is contained in:
parent
12c8ece418
commit
25aa902e02
|
@ -97,9 +97,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.79"
|
||||
version = "1.0.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
|
||||
checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
|
@ -1865,6 +1865,7 @@ dependencies = [
|
|||
name = "lyra-scene"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lyra-ecs",
|
||||
"lyra-math",
|
||||
]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::{ptr::NonNull, thread, time::Duration};
|
||||
|
||||
use lyra_engine::{assets::gltf::Gltf, change_tracker::Ct, ecs::{query::{Res, View}, system::{Criteria, CriteriaSchedule, IntoSystem}, Component, World}, game::Game, input::{Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput}, math::{self, Quat, Transform, Vec3}, render::{light::{directional::DirectionalLight, PointLight, SpotLight}, window::{CursorGrabMode, WindowOptions}}, scene::{CameraComponent, FreeFlyCamera, FreeFlyCameraPlugin, ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN}, DeltaTime};
|
||||
use lyra_engine::{assets::gltf::Gltf, change_tracker::Ct, ecs::{query::{Res, View}, system::{Criteria, CriteriaSchedule, IntoSystem}, Component, World}, game::Game, input::{Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource, InputActionPlugin, KeyCode, LayoutId, MouseAxis, MouseInput}, math::{self, Quat, Transform, Vec3}, render::{light::{directional::DirectionalLight, PointLight, SpotLight}, window::{CursorGrabMode, WindowOptions}}, scene::{self, CameraComponent, FreeFlyCamera, FreeFlyCameraPlugin, WorldTransform, ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN}, DeltaTime};
|
||||
use lyra_engine::assets::ResourceManager;
|
||||
|
||||
struct FixedTimestep {
|
||||
|
@ -97,6 +97,7 @@ async fn main() {
|
|||
|
||||
world.spawn((
|
||||
sponza_scene.clone(),
|
||||
WorldTransform::default(),
|
||||
Transform::from_xyz(0.0, 0.0, 0.0),
|
||||
));
|
||||
|
||||
|
@ -117,6 +118,15 @@ async fn main() {
|
|||
}
|
||||
|
||||
{
|
||||
let t = Transform::new(
|
||||
//Vec3::new(-5.0, 1.0, -1.28),
|
||||
Vec3::new(-5.0, 1.0, -0.0),
|
||||
//Vec3::new(-10.0, 0.94, -0.28),
|
||||
|
||||
Quat::IDENTITY,
|
||||
Vec3::new(0.25, 0.25, 0.25),
|
||||
);
|
||||
|
||||
world.spawn((
|
||||
PointLight {
|
||||
enabled: true,
|
||||
|
@ -125,16 +135,19 @@ async fn main() {
|
|||
range: 2.0,
|
||||
..Default::default()
|
||||
},
|
||||
Transform::new(
|
||||
//Vec3::new(-5.0, 1.0, -1.28),
|
||||
Vec3::new(-5.0, 1.0, -0.0),
|
||||
WorldTransform::from(t),
|
||||
t,
|
||||
cube_mesh.clone(),
|
||||
));
|
||||
|
||||
let t = Transform::new(
|
||||
Vec3::new(-3.0, 0.2, -1.5),
|
||||
//Vec3::new(-5.0, 1.0, -0.28),
|
||||
//Vec3::new(-10.0, 0.94, -0.28),
|
||||
|
||||
Quat::IDENTITY,
|
||||
Vec3::new(0.25, 0.25, 0.25),
|
||||
),
|
||||
cube_mesh.clone(),
|
||||
));
|
||||
Vec3::new(0.15, 0.15, 0.15),
|
||||
);
|
||||
|
||||
world.spawn((
|
||||
PointLight {
|
||||
|
@ -144,16 +157,19 @@ async fn main() {
|
|||
range: 1.0,
|
||||
..Default::default()
|
||||
},
|
||||
Transform::new(
|
||||
Vec3::new(-3.0, 0.2, -1.5),
|
||||
WorldTransform::from(t),
|
||||
t,
|
||||
cube_mesh.clone(),
|
||||
));
|
||||
|
||||
let t = Transform::new(
|
||||
Vec3::new(0.0, 0.2, -1.5),
|
||||
//Vec3::new(-5.0, 1.0, -0.28),
|
||||
//Vec3::new(-10.0, 0.94, -0.28),
|
||||
|
||||
Quat::IDENTITY,
|
||||
Vec3::new(0.15, 0.15, 0.15),
|
||||
),
|
||||
cube_mesh.clone(),
|
||||
));
|
||||
);
|
||||
|
||||
world.spawn((
|
||||
SpotLight {
|
||||
|
@ -164,14 +180,8 @@ async fn main() {
|
|||
//cutoff: math::Angle::Degrees(45.0),
|
||||
..Default::default()
|
||||
},
|
||||
Transform::new(
|
||||
Vec3::new(0.0, 0.2, -1.5),
|
||||
//Vec3::new(-5.0, 1.0, -0.28),
|
||||
//Vec3::new(-10.0, 0.94, -0.28),
|
||||
|
||||
Quat::IDENTITY,
|
||||
Vec3::new(0.15, 0.15, 0.15),
|
||||
),
|
||||
WorldTransform::from(t),
|
||||
t,
|
||||
cube_mesh.clone(),
|
||||
));
|
||||
}
|
||||
|
@ -245,6 +255,7 @@ async fn main() {
|
|||
};
|
||||
|
||||
game.with_system("camera_debug_trigger", sys, &[]);
|
||||
game.with_system("update_world_transforms", scene::system_update_world_transforms, &[]);
|
||||
};
|
||||
|
||||
let action_handler_plugin = |game: &mut Game| {
|
||||
|
|
|
@ -1,4 +1,36 @@
|
|||
use crate::{query::{AsQuery, Query}, Archetype, World};
|
||||
use crate::{query::{AsQuery, Fetch, Query}, Archetype, World};
|
||||
|
||||
pub struct OrFetch<'a, Q1: Query, Q2: Query> {
|
||||
left: Option<Q1::Fetch<'a>>,
|
||||
right: Option<Q2::Fetch<'a>>,
|
||||
}
|
||||
|
||||
impl<'a, Q1: Query, Q2: Query> Fetch<'a> for OrFetch<'a, Q1, Q2> {
|
||||
type Item = (Option<Q1::Item<'a>>, Option<Q2::Item<'a>>);
|
||||
|
||||
fn dangling() -> Self {
|
||||
Self {
|
||||
left: None,
|
||||
right: None,
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn get_item(&mut self, entity: crate::ArchetypeEntityId) -> Self::Item {
|
||||
let mut res = (None, None);
|
||||
|
||||
if let Some(left) = self.left.as_mut() {
|
||||
let i = left.get_item(entity);
|
||||
res.0 = Some(i);
|
||||
}
|
||||
|
||||
if let Some(right) = self.right.as_mut() {
|
||||
let i = right.get_item(entity);
|
||||
res.1 = Some(i);
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
/// A filter query returning when either `Q1` or `Q2` returns.
|
||||
///
|
||||
|
@ -25,25 +57,34 @@ use crate::{query::{AsQuery, Query}, Archetype, World};
|
|||
pub struct Or<Q1: AsQuery, Q2: AsQuery> {
|
||||
left: Q1::Query,
|
||||
right: Q2::Query,
|
||||
can_visit_left: bool,
|
||||
can_visit_right: bool,
|
||||
}
|
||||
|
||||
impl<Q1: AsQuery, Q2: AsQuery> Copy for Or<Q1, Q2> {}
|
||||
|
||||
impl<Q1: AsQuery, Q2: AsQuery> Clone for Or<Q1, Q2> {
|
||||
fn clone(&self) -> Self {
|
||||
Self { left: self.left.clone(), right: self.right.clone() }
|
||||
Self {
|
||||
left: self.left.clone(),
|
||||
right: self.right.clone(),
|
||||
can_visit_left: self.can_visit_left,
|
||||
can_visit_right: self.can_visit_right,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q1: AsQuery, Q2: AsQuery> Query for Or<Q1, Q2> {
|
||||
type Item<'a> = ();
|
||||
type Item<'a> = (Option<<Q1::Query as Query>::Item<'a>>, Option<<Q2::Query as Query>::Item<'a>>);
|
||||
|
||||
type Fetch<'a> = ();
|
||||
type Fetch<'a> = OrFetch<'a, Q1::Query, Q2::Query>;
|
||||
|
||||
fn new() -> Self {
|
||||
Or {
|
||||
left: Q1::Query::new(),
|
||||
right: Q2::Query::new(),
|
||||
can_visit_left: false,
|
||||
can_visit_right: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,8 +92,19 @@ impl<Q1: AsQuery, Q2: AsQuery> Query for Or<Q1, Q2> {
|
|||
self.left.can_visit_archetype(archetype) || self.right.can_visit_archetype(archetype)
|
||||
}
|
||||
|
||||
unsafe fn fetch<'a>(&self, _world: &'a World, _: &'a Archetype, _: crate::Tick) -> Self::Fetch<'a> {
|
||||
()
|
||||
unsafe fn fetch<'a>(&self, world: &'a World, archetype: &'a Archetype, tick: crate::Tick) -> Self::Fetch<'a> {
|
||||
let mut f = OrFetch::<Q1::Query, Q2::Query>::dangling();
|
||||
|
||||
// TODO: store the result of Self::can_visit_archetype so this isn't ran twice
|
||||
if self.left.can_visit_archetype(archetype) {
|
||||
f.left = Some(self.left.fetch(world, archetype, tick));
|
||||
}
|
||||
|
||||
if self.right.can_visit_archetype(archetype) {
|
||||
f.right = Some(self.right.fetch(world, archetype, tick));
|
||||
}
|
||||
|
||||
f
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,11 +6,12 @@ use std::borrow::Cow;
|
|||
use glam::Vec3;
|
||||
use instant::Instant;
|
||||
use itertools::izip;
|
||||
use lyra_ecs::query::filter::{Has, Or};
|
||||
use lyra_ecs::query::filter::{Has, Not, Or};
|
||||
use lyra_ecs::relation::{ChildOf, RelationOriginComponent};
|
||||
use lyra_ecs::{Entity, Tick};
|
||||
use lyra_ecs::query::{Entities, TickOf};
|
||||
use lyra_ecs::World;
|
||||
use lyra_scene::SceneGraph;
|
||||
use lyra_scene::{SceneGraph, WorldTransform};
|
||||
use tracing::{debug, warn};
|
||||
use uuid::Uuid;
|
||||
use wgpu::{BindGroupLayout, Limits};
|
||||
|
@ -430,17 +431,16 @@ impl BasicRenderer {
|
|||
impl Renderer for BasicRenderer {
|
||||
fn prepare(&mut self, main_world: &mut World) {
|
||||
let last_epoch = main_world.current_tick();
|
||||
|
||||
let now_inst = Instant::now();
|
||||
let mut alive_entities = HashSet::new();
|
||||
|
||||
let now_inst = Instant::now();
|
||||
let view = main_world.view_iter::<(Entities, &Transform, TickOf<Transform>,
|
||||
Or<(&MeshHandle, TickOf<MeshHandle>), (&SceneHandle, TickOf<SceneHandle>)>)>();
|
||||
|
||||
let view = main_world.filtered_view_iter::<(Entities, &Transform, TickOf<Transform>), Or<Has<MeshHandle>, Has<SceneHandle>>>();
|
||||
for (entity, transform, transform_epoch) in view {
|
||||
for (entity, transform, transform_epoch, (mesh_pair, scene_pair)) in view {
|
||||
alive_entities.insert(entity);
|
||||
|
||||
let mesh_view = main_world.view_one::<(&MeshHandle, TickOf<MeshHandle>)>(entity);
|
||||
if let Some((mesh_han, mesh_epoch)) = mesh_view.get() {
|
||||
if let Some((mesh_han, mesh_epoch)) = mesh_pair {
|
||||
let interop_pos = self.interpolate_transforms(now_inst, last_epoch, entity, &transform, transform_epoch);
|
||||
|
||||
if let Some(mesh) = mesh_han.data_ref() {
|
||||
|
@ -464,17 +464,16 @@ impl Renderer for BasicRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
let scene_view = main_world.view_one::<(&SceneHandle, TickOf<SceneHandle>)>(entity);
|
||||
if let Some((scene_han, scene_epoch)) = scene_view.get() {
|
||||
// TODO: Rendering scenes
|
||||
|
||||
if let Some((scene_han, scene_epoch)) = scene_pair {
|
||||
if let Some(scene) = scene_han.data_ref() {
|
||||
let view = scene.world().view::<(Entities, &mut WorldTransform, &Transform, Not<Has<RelationOriginComponent<ChildOf>>>)>();
|
||||
lyra_scene::system_update_world_transforms(scene.world(), view).unwrap();
|
||||
|
||||
let interpo_pos = self.interpolate_transforms(now_inst, last_epoch, entity, &transform, transform_epoch);
|
||||
|
||||
scene.traverse_down(|sw: &World, mesh_han, pos| {
|
||||
if let Some(mesh_han) = sw.view_one::<&MeshHandle>(mesh_han.entity()).get() {
|
||||
for (mesh_han, pos) in scene.world().view_iter::<(&MeshHandle, &WorldTransform)>() {
|
||||
if let Some(mesh) = mesh_han.data_ref() {
|
||||
let mesh_interpo = interpo_pos + pos;
|
||||
let mesh_interpo = interpo_pos + **pos;
|
||||
|
||||
// if process mesh did not just create a new mesh, and the epoch
|
||||
// shows that the scene has changed, verify that the mesh buffers
|
||||
|
@ -496,7 +495,6 @@ impl Renderer for BasicRenderer {
|
|||
self.render_jobs.push_back(job);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -567,7 +565,14 @@ impl Renderer for BasicRenderer {
|
|||
render_pass.set_pipeline(pipeline.get_wgpu_pipeline());
|
||||
|
||||
// get the mesh (containing vertices) and the buffers from storage
|
||||
let buffers = self.mesh_buffers.get(&job.mesh_uuid).unwrap();
|
||||
let buffers = self.mesh_buffers.get(&job.mesh_uuid);
|
||||
if buffers.is_none() {
|
||||
warn!("Skipping job since its mesh is missing {:?}", job.mesh_uuid);
|
||||
continue;
|
||||
}
|
||||
let buffers = buffers.unwrap();
|
||||
/* let buffers = self.mesh_buffers.get(&job.mesh_uuid)
|
||||
.expect("missing render job mesh"); */
|
||||
|
||||
// Bind the optional texture
|
||||
if let Some(tex) = buffers.material.as_ref()
|
||||
|
|
|
@ -6,3 +6,5 @@ pub use camera::*;
|
|||
|
||||
pub mod free_fly_camera;
|
||||
pub use free_fly_camera::*;
|
||||
|
||||
pub use lyra_scene::*;
|
|
@ -2,8 +2,9 @@ use std::{ffi::OsStr, path::{Path, PathBuf}, sync::Arc};
|
|||
|
||||
use glam::{Quat, Vec3};
|
||||
use instant::Instant;
|
||||
use lyra_ecs::query;
|
||||
use lyra_math::Transform;
|
||||
use lyra_scene::{SceneGraph, SceneNode};
|
||||
use lyra_scene::{SceneGraph, SceneNode, WorldTransform};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::{loader::{LoaderError, PinedBoxLoaderFuture, ResourceLoader}, util, ResHandle, ResourceData, ResourceManager, ResourceStorage};
|
||||
|
@ -76,7 +77,7 @@ impl ModelLoader {
|
|||
};
|
||||
node.name = gnode.name().map(str::to_string);
|
||||
|
||||
let scene_node = scene.add_node_under(scene_parent, node.transform, ());
|
||||
let scene_node = scene.add_node_under(scene_parent, (WorldTransform::from(node.transform), node.transform));
|
||||
|
||||
if let Some(mesh) = gnode.mesh() {
|
||||
let mut new_mesh = Mesh::default();
|
||||
|
@ -225,6 +226,10 @@ impl ResourceLoader for ModelLoader {
|
|||
}
|
||||
}
|
||||
|
||||
for en in graph.world().view_iter::<query::Entities>() {
|
||||
graph.world().view_one::<(&WorldTransform, &Transform)>(en).get().expect("Scene node is missing world and local transform bundle!");
|
||||
}
|
||||
|
||||
let graph = ResHandle::new_ready(Some(path.as_str()), graph);
|
||||
gltf_out.scenes.push(graph);
|
||||
|
||||
|
@ -268,6 +273,7 @@ impl ResourceLoader for ModelLoader {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use lyra_ecs::{query::Entities, relation::ChildOf};
|
||||
use lyra_scene::WorldTransform;
|
||||
|
||||
use crate::tests::busy_wait_resource;
|
||||
|
||||
|
@ -293,7 +299,9 @@ mod tests {
|
|||
.data_ref().unwrap();
|
||||
|
||||
let mut node = None;
|
||||
scene.traverse_down(|_, no, _tran| {
|
||||
//scene.world().view::<SceneNodeFlag()
|
||||
scene.traverse_down::<_, &WorldTransform>(|_, no, tran| {
|
||||
tran.get().expect("scene node is missing a WorldTransform");
|
||||
node = Some(no.clone());
|
||||
});
|
||||
|
||||
|
|
|
@ -22,6 +22,12 @@ impl Deref for WorldTransform {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<Transform> for WorldTransform {
|
||||
fn from(value: Transform) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
/// A system that updates the [`WorldTransform`]'s for entities and their children.
|
||||
///
|
||||
/// For entities without parents, this will update world transform to match local transform.
|
||||
|
@ -47,7 +53,8 @@ fn recurse_update_trans(world: &World, parent_transform: &WorldTransform, entity
|
|||
.relates_to::<ChildOf>(entity)
|
||||
.into_iter()
|
||||
{
|
||||
world_tran.0 = parent_transform.0 + *tran;
|
||||
world_tran.0 = *tran;
|
||||
world_tran.0.translation = parent_transform.0.translation + tran.translation;
|
||||
next_entities.push((en, world_tran.0.clone()));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue