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]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.79"
|
version = "1.0.81"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
|
checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayref"
|
name = "arrayref"
|
||||||
|
@ -1865,6 +1865,7 @@ dependencies = [
|
||||||
name = "lyra-scene"
|
name = "lyra-scene"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"lyra-ecs",
|
"lyra-ecs",
|
||||||
"lyra-math",
|
"lyra-math",
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{ptr::NonNull, thread, time::Duration};
|
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;
|
use lyra_engine::assets::ResourceManager;
|
||||||
|
|
||||||
struct FixedTimestep {
|
struct FixedTimestep {
|
||||||
|
@ -97,6 +97,7 @@ async fn main() {
|
||||||
|
|
||||||
world.spawn((
|
world.spawn((
|
||||||
sponza_scene.clone(),
|
sponza_scene.clone(),
|
||||||
|
WorldTransform::default(),
|
||||||
Transform::from_xyz(0.0, 0.0, 0.0),
|
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((
|
world.spawn((
|
||||||
PointLight {
|
PointLight {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
@ -125,17 +135,20 @@ async fn main() {
|
||||||
range: 2.0,
|
range: 2.0,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
Transform::new(
|
WorldTransform::from(t),
|
||||||
//Vec3::new(-5.0, 1.0, -1.28),
|
t,
|
||||||
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),
|
|
||||||
),
|
|
||||||
cube_mesh.clone(),
|
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.15, 0.15, 0.15),
|
||||||
|
);
|
||||||
|
|
||||||
world.spawn((
|
world.spawn((
|
||||||
PointLight {
|
PointLight {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
@ -144,17 +157,20 @@ async fn main() {
|
||||||
range: 1.0,
|
range: 1.0,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
Transform::new(
|
WorldTransform::from(t),
|
||||||
Vec3::new(-3.0, 0.2, -1.5),
|
t,
|
||||||
//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(),
|
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),
|
||||||
|
);
|
||||||
|
|
||||||
world.spawn((
|
world.spawn((
|
||||||
SpotLight {
|
SpotLight {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
@ -164,14 +180,8 @@ async fn main() {
|
||||||
//cutoff: math::Angle::Degrees(45.0),
|
//cutoff: math::Angle::Degrees(45.0),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
Transform::new(
|
WorldTransform::from(t),
|
||||||
Vec3::new(0.0, 0.2, -1.5),
|
t,
|
||||||
//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(),
|
cube_mesh.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -245,6 +255,7 @@ async fn main() {
|
||||||
};
|
};
|
||||||
|
|
||||||
game.with_system("camera_debug_trigger", sys, &[]);
|
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| {
|
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.
|
/// 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> {
|
pub struct Or<Q1: AsQuery, Q2: AsQuery> {
|
||||||
left: Q1::Query,
|
left: Q1::Query,
|
||||||
right: Q2::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> Copy for Or<Q1, Q2> {}
|
||||||
|
|
||||||
impl<Q1: AsQuery, Q2: AsQuery> Clone for Or<Q1, Q2> {
|
impl<Q1: AsQuery, Q2: AsQuery> Clone for Or<Q1, Q2> {
|
||||||
fn clone(&self) -> Self {
|
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> {
|
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 {
|
fn new() -> Self {
|
||||||
Or {
|
Or {
|
||||||
left: Q1::Query::new(),
|
left: Q1::Query::new(),
|
||||||
right: Q2::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)
|
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 glam::Vec3;
|
||||||
use instant::Instant;
|
use instant::Instant;
|
||||||
use itertools::izip;
|
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::{Entity, Tick};
|
||||||
use lyra_ecs::query::{Entities, TickOf};
|
use lyra_ecs::query::{Entities, TickOf};
|
||||||
use lyra_ecs::World;
|
use lyra_ecs::World;
|
||||||
use lyra_scene::SceneGraph;
|
use lyra_scene::{SceneGraph, WorldTransform};
|
||||||
use tracing::{debug, warn};
|
use tracing::{debug, warn};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use wgpu::{BindGroupLayout, Limits};
|
use wgpu::{BindGroupLayout, Limits};
|
||||||
|
@ -430,17 +431,16 @@ impl BasicRenderer {
|
||||||
impl Renderer for BasicRenderer {
|
impl Renderer for BasicRenderer {
|
||||||
fn prepare(&mut self, main_world: &mut World) {
|
fn prepare(&mut self, main_world: &mut World) {
|
||||||
let last_epoch = main_world.current_tick();
|
let last_epoch = main_world.current_tick();
|
||||||
|
let now_inst = Instant::now();
|
||||||
let mut alive_entities = HashSet::new();
|
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, (mesh_pair, scene_pair)) in view {
|
||||||
for (entity, transform, transform_epoch) in view {
|
|
||||||
alive_entities.insert(entity);
|
alive_entities.insert(entity);
|
||||||
|
|
||||||
let mesh_view = main_world.view_one::<(&MeshHandle, TickOf<MeshHandle>)>(entity);
|
if let Some((mesh_han, mesh_epoch)) = mesh_pair {
|
||||||
if let Some((mesh_han, mesh_epoch)) = mesh_view.get() {
|
|
||||||
let interop_pos = self.interpolate_transforms(now_inst, last_epoch, entity, &transform, transform_epoch);
|
let interop_pos = self.interpolate_transforms(now_inst, last_epoch, entity, &transform, transform_epoch);
|
||||||
|
|
||||||
if let Some(mesh) = mesh_han.data_ref() {
|
if let Some(mesh) = mesh_han.data_ref() {
|
||||||
|
@ -464,39 +464,37 @@ impl Renderer for BasicRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let scene_view = main_world.view_one::<(&SceneHandle, TickOf<SceneHandle>)>(entity);
|
if let Some((scene_han, scene_epoch)) = scene_pair {
|
||||||
if let Some((scene_han, scene_epoch)) = scene_view.get() {
|
|
||||||
// TODO: Rendering scenes
|
|
||||||
|
|
||||||
if let Some(scene) = scene_han.data_ref() {
|
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);
|
let interpo_pos = self.interpolate_transforms(now_inst, last_epoch, entity, &transform, transform_epoch);
|
||||||
|
|
||||||
scene.traverse_down(|sw: &World, mesh_han, pos| {
|
for (mesh_han, pos) in scene.world().view_iter::<(&MeshHandle, &WorldTransform)>() {
|
||||||
if let Some(mesh_han) = sw.view_one::<&MeshHandle>(mesh_han.entity()).get() {
|
if let Some(mesh) = mesh_han.data_ref() {
|
||||||
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
|
// if process mesh did not just create a new mesh, and the epoch
|
||||||
// shows that the scene has changed, verify that the mesh buffers
|
// shows that the scene has changed, verify that the mesh buffers
|
||||||
// dont need to be resent to the gpu.
|
// dont need to be resent to the gpu.
|
||||||
if !self.process_mesh(entity, mesh_interpo, &*mesh, mesh_han.uuid())
|
if !self.process_mesh(entity, mesh_interpo, &*mesh, mesh_han.uuid())
|
||||||
&& scene_epoch == last_epoch {
|
&& scene_epoch == last_epoch {
|
||||||
self.check_mesh_buffers(entity, &mesh_han);
|
self.check_mesh_buffers(entity, &mesh_han);
|
||||||
}
|
|
||||||
|
|
||||||
let scene_mesh_group = TransformGroup::Res(scene_han.uuid(), mesh_han.uuid());
|
|
||||||
let group = TransformGroup::OwnedGroup(entity, scene_mesh_group.into());
|
|
||||||
let transform_id = self.transform_buffers.update_or_push(&self.queue, &self.render_limits,
|
|
||||||
group, || ( mesh_interpo.calculate_mat4(), glam::Mat3::from_quat(mesh_interpo.rotation) ));
|
|
||||||
|
|
||||||
let material = mesh.material.as_ref().unwrap()
|
|
||||||
.data_ref().unwrap();
|
|
||||||
let shader = material.shader_uuid.unwrap_or(0);
|
|
||||||
let job = RenderJob::new(entity, shader, mesh_han.uuid(), transform_id);
|
|
||||||
self.render_jobs.push_back(job);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let scene_mesh_group = TransformGroup::Res(scene_han.uuid(), mesh_han.uuid());
|
||||||
|
let group = TransformGroup::OwnedGroup(entity, scene_mesh_group.into());
|
||||||
|
let transform_id = self.transform_buffers.update_or_push(&self.queue, &self.render_limits,
|
||||||
|
group, || ( mesh_interpo.calculate_mat4(), glam::Mat3::from_quat(mesh_interpo.rotation) ));
|
||||||
|
|
||||||
|
let material = mesh.material.as_ref().unwrap()
|
||||||
|
.data_ref().unwrap();
|
||||||
|
let shader = material.shader_uuid.unwrap_or(0);
|
||||||
|
let job = RenderJob::new(entity, shader, mesh_han.uuid(), transform_id);
|
||||||
|
self.render_jobs.push_back(job);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -567,7 +565,14 @@ impl Renderer for BasicRenderer {
|
||||||
render_pass.set_pipeline(pipeline.get_wgpu_pipeline());
|
render_pass.set_pipeline(pipeline.get_wgpu_pipeline());
|
||||||
|
|
||||||
// get the mesh (containing vertices) and the buffers from storage
|
// 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
|
// Bind the optional texture
|
||||||
if let Some(tex) = buffers.material.as_ref()
|
if let Some(tex) = buffers.material.as_ref()
|
||||||
|
|
|
@ -6,3 +6,5 @@ pub use camera::*;
|
||||||
|
|
||||||
pub mod free_fly_camera;
|
pub mod free_fly_camera;
|
||||||
pub use 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 glam::{Quat, Vec3};
|
||||||
use instant::Instant;
|
use instant::Instant;
|
||||||
|
use lyra_ecs::query;
|
||||||
use lyra_math::Transform;
|
use lyra_math::Transform;
|
||||||
use lyra_scene::{SceneGraph, SceneNode};
|
use lyra_scene::{SceneGraph, SceneNode, WorldTransform};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::{loader::{LoaderError, PinedBoxLoaderFuture, ResourceLoader}, util, ResHandle, ResourceData, ResourceManager, ResourceStorage};
|
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);
|
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() {
|
if let Some(mesh) = gnode.mesh() {
|
||||||
let mut new_mesh = Mesh::default();
|
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);
|
let graph = ResHandle::new_ready(Some(path.as_str()), graph);
|
||||||
gltf_out.scenes.push(graph);
|
gltf_out.scenes.push(graph);
|
||||||
|
|
||||||
|
@ -268,6 +273,7 @@ impl ResourceLoader for ModelLoader {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use lyra_ecs::{query::Entities, relation::ChildOf};
|
use lyra_ecs::{query::Entities, relation::ChildOf};
|
||||||
|
use lyra_scene::WorldTransform;
|
||||||
|
|
||||||
use crate::tests::busy_wait_resource;
|
use crate::tests::busy_wait_resource;
|
||||||
|
|
||||||
|
@ -293,7 +299,9 @@ mod tests {
|
||||||
.data_ref().unwrap();
|
.data_ref().unwrap();
|
||||||
|
|
||||||
let mut node = None;
|
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());
|
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.
|
/// 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.
|
/// 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)
|
.relates_to::<ChildOf>(entity)
|
||||||
.into_iter()
|
.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()));
|
next_entities.push((en, world_tran.0.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue