Compare commits
No commits in common. "e2c6b557bb578fe9bc6963b009b027b9e94e4be5" and "8eac563229d9b43373df17e36686286eb1c2ee9b" have entirely different histories.
e2c6b557bb
...
8eac563229
|
@ -1842,7 +1842,6 @@ dependencies = [
|
||||||
"lyra-resource",
|
"lyra-resource",
|
||||||
"lyra-scene",
|
"lyra-scene",
|
||||||
"quote",
|
"quote",
|
||||||
"rustc-hash",
|
|
||||||
"syn 2.0.51",
|
"syn 2.0.51",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::{query::{AsQuery, Query}, Archetype, World};
|
||||||
/// This means that entities that `Q` fetches are skipped, and entities that
|
/// This means that entities that `Q` fetches are skipped, and entities that
|
||||||
/// `Q` does not fetch are not skipped.
|
/// `Q` does not fetch are not skipped.
|
||||||
///
|
///
|
||||||
/// ```nobuild
|
/// ```rust,nobuild
|
||||||
/// // Iterate over entities that has a transform, and are not the origin of a `ChildOf` relationship.
|
/// // Iterate over entities that has a transform, and are not the origin of a `ChildOf` relationship.
|
||||||
/// for (en, pos, _) in world
|
/// for (en, pos, _) in world
|
||||||
/// .view::<(Entities, &Transform, Not<Has<RelationOriginComponent<ChildOf>>>)>()
|
/// .view::<(Entities, &Transform, Not<Has<RelationOriginComponent<ChildOf>>>)>()
|
||||||
|
|
|
@ -36,7 +36,7 @@ impl<'a, Q1: Query, Q2: Query> Fetch<'a> for OrFetch<'a, Q1, Q2> {
|
||||||
///
|
///
|
||||||
/// This checks if `Q1` can fetch before checking `Q2`.
|
/// This checks if `Q1` can fetch before checking `Q2`.
|
||||||
///
|
///
|
||||||
/// ```nobuild
|
/// ```rust,nobuild
|
||||||
/// for (en, pos, _) in world
|
/// for (en, pos, _) in world
|
||||||
/// .view::<(Entities, &Transform, Or<Has<Mesh>, Has<Scene>>)>()
|
/// .view::<(Entities, &Transform, Or<Has<Mesh>, Has<Scene>>)>()
|
||||||
/// .iter()
|
/// .iter()
|
||||||
|
|
|
@ -27,10 +27,6 @@ mod world;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
pub use world::*;
|
pub use world::*;
|
||||||
|
|
||||||
mod optional;
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
pub use optional::*;
|
|
||||||
|
|
||||||
pub mod dynamic;
|
pub mod dynamic;
|
||||||
|
|
||||||
pub mod filter;
|
pub mod filter;
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
use crate::{Archetype, World};
|
|
||||||
|
|
||||||
use super::{AsQuery, Fetch, Query};
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct OptionalFetcher<'a, Q: AsQuery> {
|
|
||||||
fetcher: Option<<Q::Query as Query>::Fetch<'a>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Q: AsQuery> Fetch<'a> for OptionalFetcher<'a, Q> {
|
|
||||||
type Item = Option<<Q::Query as Query>::Item<'a>>;
|
|
||||||
|
|
||||||
fn dangling() -> Self {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn get_item(&mut self, entity: crate::ArchetypeEntityId) -> Self::Item {
|
|
||||||
self.fetcher.as_mut()
|
|
||||||
.map(|f| f.get_item(entity))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn can_visit_item(&mut self, entity: crate::ArchetypeEntityId) -> bool {
|
|
||||||
self.fetcher.as_mut()
|
|
||||||
.map(|f| f.can_visit_item(entity))
|
|
||||||
.unwrap_or(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct Optional<Q: AsQuery> {
|
|
||||||
query: Q::Query,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Q: AsQuery> Copy for Optional<Q> { }
|
|
||||||
|
|
||||||
impl<Q: AsQuery> Clone for Optional<Q> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self { query: self.query.clone() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Q: AsQuery> Query for Optional<Q> {
|
|
||||||
type Item<'a> = Option<<Q::Query as Query>::Item<'a>>;
|
|
||||||
|
|
||||||
type Fetch<'a> = OptionalFetcher<'a, Q>;
|
|
||||||
|
|
||||||
fn new() -> Self {
|
|
||||||
Optional {
|
|
||||||
query: Q::Query::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn can_visit_archetype(&self, _: &Archetype) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn fetch<'a>(&self, world: &'a World, arch: &'a Archetype, tick: crate::Tick) -> Self::Fetch<'a> {
|
|
||||||
let fetcher = if self.query.can_visit_archetype(arch) {
|
|
||||||
Some(self.query.fetch(world, arch, tick))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
OptionalFetcher {
|
|
||||||
fetcher,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Q: AsQuery> AsQuery for Optional<Q> {
|
|
||||||
type Query = Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Q: AsQuery> AsQuery for Option<Q> {
|
|
||||||
type Query = Optional<Q>;
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{any::{Any, TypeId}, collections::HashMap, ptr::NonNull};
|
use std::{any::TypeId, collections::HashMap, ptr::NonNull};
|
||||||
|
|
||||||
use atomic_refcell::{AtomicRef, AtomicRefMut};
|
use atomic_refcell::{AtomicRef, AtomicRefMut};
|
||||||
|
|
||||||
|
@ -128,39 +128,22 @@ impl World {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a component bundle into an existing entity.
|
/// Insert a bundle into an existing entity. If the components are already existing on the
|
||||||
///
|
/// entity, they will be updated, else the entity will be moved to a different Archetype
|
||||||
/// If the components are already existing on the entity, they will be updated, else the
|
/// that can store the entity. That may involve creating a new Archetype.
|
||||||
/// entity will be moved to a different Archetype that can store the entity. That may
|
|
||||||
/// involve creating a new Archetype.
|
|
||||||
pub fn insert<B>(&mut self, entity: Entity, bundle: B)
|
pub fn insert<B>(&mut self, entity: Entity, bundle: B)
|
||||||
where
|
where
|
||||||
B: Bundle
|
B: Bundle
|
||||||
{
|
{
|
||||||
|
// TODO: If the entity already has the components in `bundle`, update the values of the
|
||||||
|
// components with the bundle.
|
||||||
|
|
||||||
let tick = self.tick();
|
let tick = self.tick();
|
||||||
|
|
||||||
let record = self.entities.entity_record(entity).unwrap();
|
let record = self.entities.entity_record(entity).unwrap();
|
||||||
let current_arch = self.archetypes.get(&record.id).unwrap();
|
let current_arch = self.archetypes.get(&record.id).unwrap();
|
||||||
let current_arch_len = current_arch.len();
|
let current_arch_len = current_arch.len();
|
||||||
|
|
||||||
let mut contains_all = true;
|
|
||||||
for id in bundle.type_ids() {
|
|
||||||
contains_all = contains_all && current_arch.get_column(id).is_some();
|
|
||||||
}
|
|
||||||
|
|
||||||
if contains_all {
|
|
||||||
let current_arch = self.archetypes.get_mut(&record.id).unwrap();
|
|
||||||
let entry_idx = *current_arch.entity_indexes()
|
|
||||||
.get(&entity).unwrap();
|
|
||||||
|
|
||||||
bundle.take(|ptr, id, _info| {
|
|
||||||
let col = current_arch.get_column_mut(id).unwrap();
|
|
||||||
unsafe { col.set_at(entry_idx.0 as _, ptr, tick) };
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// contains the type ids for the old component columns + the ids for the new components
|
// contains the type ids for the old component columns + the ids for the new components
|
||||||
let mut combined_column_types: Vec<DynTypeId> = current_arch.columns.iter().map(|c| c.info.type_id()).collect();
|
let mut combined_column_types: Vec<DynTypeId> = current_arch.columns.iter().map(|c| c.info.type_id()).collect();
|
||||||
combined_column_types.extend(bundle.type_ids());
|
combined_column_types.extend(bundle.type_ids());
|
||||||
|
@ -244,7 +227,7 @@ impl World {
|
||||||
/// A method used for debugging implementation details of the ECS.
|
/// A method used for debugging implementation details of the ECS.
|
||||||
///
|
///
|
||||||
/// Here's an example of the output:
|
/// Here's an example of the output:
|
||||||
/// ```nobuild
|
/// ```
|
||||||
/// Entities
|
/// Entities
|
||||||
/// 1 in archetype 0 at 0
|
/// 1 in archetype 0 at 0
|
||||||
/// 0 in archetype 1 at 0
|
/// 0 in archetype 1 at 0
|
||||||
|
@ -288,7 +271,7 @@ impl World {
|
||||||
/// the contents of entities inside the archetypes.
|
/// the contents of entities inside the archetypes.
|
||||||
///
|
///
|
||||||
/// Below is a template of the output:
|
/// Below is a template of the output:
|
||||||
/// ```nobuild
|
/// ```
|
||||||
/// Entities
|
/// Entities
|
||||||
/// %ENTITY_ID% in archetype %ARCHETYPE_ID% at %INDEX%
|
/// %ENTITY_ID% in archetype %ARCHETYPE_ID% at %INDEX%
|
||||||
/// Arch ID -- %ARCHETYPE_LEN% entities
|
/// Arch ID -- %ARCHETYPE_LEN% entities
|
||||||
|
@ -635,6 +618,8 @@ mod tests {
|
||||||
|
|
||||||
insert_and_assert(&mut world, e1, v2s[0], v3s[0]);
|
insert_and_assert(&mut world, e1, v2s[0], v3s[0]);
|
||||||
println!("Entity 1 is good");
|
println!("Entity 1 is good");
|
||||||
|
assert_eq!(world.archetypes.len(), 1);
|
||||||
|
println!("Empty archetype was removed");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -670,21 +655,4 @@ mod tests {
|
||||||
assert!(tick >= world_tick);
|
assert!(tick >= world_tick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tests replacing components using World::insert
|
|
||||||
#[test]
|
|
||||||
fn entity_insert_replace() {
|
|
||||||
let mut world = World::new();
|
|
||||||
let first = world.spawn((Vec2::new(10.0, 10.0),));
|
|
||||||
let second = world.spawn((Vec2::new(5.0, 5.0),));
|
|
||||||
|
|
||||||
world.insert(first, Vec2::new(50.0, 50.0));
|
|
||||||
|
|
||||||
let pos = world.view_one::<&mut Vec2>(first).get().unwrap();
|
|
||||||
assert_eq!(*pos, Vec2::new(50.0, 50.0));
|
|
||||||
drop(pos);
|
|
||||||
|
|
||||||
let pos = world.view_one::<&mut Vec2>(second).get().unwrap();
|
|
||||||
assert_eq!(*pos, Vec2::new(5.0, 5.0));
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -34,7 +34,6 @@ uuid = { version = "1.5.0", features = ["v4", "fast-rng"] }
|
||||||
itertools = "0.11.0"
|
itertools = "0.11.0"
|
||||||
thiserror = "1.0.56"
|
thiserror = "1.0.56"
|
||||||
unique = "0.9.1"
|
unique = "0.9.1"
|
||||||
rustc-hash = "1.1.0"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
tracy = ["dep:tracing-tracy"]
|
tracy = ["dep:tracing-tracy"]
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
use std::collections::{VecDeque, HashSet};
|
use std::collections::{HashMap, VecDeque, HashSet};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use glam::Vec3;
|
use glam::Vec3;
|
||||||
|
use instant::Instant;
|
||||||
use itertools::izip;
|
use itertools::izip;
|
||||||
use lyra_ecs::query::filter::{Has, Not, Or};
|
use lyra_ecs::query::filter::{Has, Not, Or};
|
||||||
use lyra_ecs::relation::{ChildOf, RelationOriginComponent};
|
use lyra_ecs::relation::{ChildOf, RelationOriginComponent};
|
||||||
use lyra_ecs::{Component, Entity};
|
use lyra_ecs::{Entity, Tick};
|
||||||
use lyra_ecs::query::{Entities, Res, TickOf};
|
use lyra_ecs::query::{Entities, TickOf};
|
||||||
use lyra_ecs::World;
|
use lyra_ecs::World;
|
||||||
use lyra_scene::{SceneGraph, WorldTransform};
|
use lyra_scene::{SceneGraph, WorldTransform};
|
||||||
use tracing::{debug, instrument, warn};
|
use tracing::{debug, instrument, warn};
|
||||||
|
@ -21,7 +22,6 @@ use crate::math::Transform;
|
||||||
use crate::render::material::MaterialUniform;
|
use crate::render::material::MaterialUniform;
|
||||||
use crate::render::render_buffer::BufferWrapperBuilder;
|
use crate::render::render_buffer::BufferWrapperBuilder;
|
||||||
use crate::scene::CameraComponent;
|
use crate::scene::CameraComponent;
|
||||||
use crate::DeltaTime;
|
|
||||||
|
|
||||||
use super::camera::{RenderCamera, CameraUniform};
|
use super::camera::{RenderCamera, CameraUniform};
|
||||||
use super::desc_buf_lay::DescVertexBufferLayout;
|
use super::desc_buf_lay::DescVertexBufferLayout;
|
||||||
|
@ -67,10 +67,12 @@ struct MeshBufferStorage {
|
||||||
//transform_index: TransformBufferIndices,
|
//transform_index: TransformBufferIndices,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Component)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct InterpTransform {
|
pub struct CachedTransform {
|
||||||
last_transform: Transform,
|
last_updated_at: Option<Instant>,
|
||||||
alpha: f32,
|
cached_at: Instant,
|
||||||
|
to_transform: Transform,
|
||||||
|
from_transform: Transform,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BasicRenderer {
|
pub struct BasicRenderer {
|
||||||
|
@ -83,12 +85,13 @@ pub struct BasicRenderer {
|
||||||
|
|
||||||
pub clear_color: wgpu::Color,
|
pub clear_color: wgpu::Color,
|
||||||
|
|
||||||
pub render_pipelines: rustc_hash::FxHashMap<u64, Arc<FullRenderPipeline>>,
|
pub render_pipelines: HashMap<u64, Arc<FullRenderPipeline>>,
|
||||||
pub render_jobs: VecDeque<RenderJob>,
|
pub render_jobs: VecDeque<RenderJob>,
|
||||||
|
|
||||||
mesh_buffers: rustc_hash::FxHashMap<uuid::Uuid, MeshBufferStorage>, // TODO: clean up left over buffers from deleted entities/components
|
mesh_buffers: HashMap<uuid::Uuid, MeshBufferStorage>, // TODO: clean up left over buffers from deleted entities/components
|
||||||
material_buffers: rustc_hash::FxHashMap<uuid::Uuid, Rc<Material>>,
|
material_buffers: HashMap<uuid::Uuid, Rc<Material>>,
|
||||||
entity_meshes: rustc_hash::FxHashMap<Entity, uuid::Uuid>,
|
entity_meshes: HashMap<Entity, uuid::Uuid>,
|
||||||
|
entity_last_transforms: HashMap<Entity, CachedTransform>,
|
||||||
|
|
||||||
transform_buffers: TransformBuffers,
|
transform_buffers: TransformBuffers,
|
||||||
|
|
||||||
|
@ -220,11 +223,11 @@ impl BasicRenderer {
|
||||||
b: 0.3,
|
b: 0.3,
|
||||||
a: 1.0,
|
a: 1.0,
|
||||||
},
|
},
|
||||||
render_pipelines: Default::default(),
|
render_pipelines: HashMap::new(),
|
||||||
render_jobs: Default::default(),
|
render_jobs: VecDeque::new(),
|
||||||
mesh_buffers: Default::default(),
|
mesh_buffers: HashMap::new(),
|
||||||
material_buffers: Default::default(),
|
material_buffers: HashMap::new(),
|
||||||
entity_meshes: Default::default(),
|
entity_meshes: HashMap::new(),
|
||||||
|
|
||||||
render_limits,
|
render_limits,
|
||||||
transform_buffers,
|
transform_buffers,
|
||||||
|
@ -235,6 +238,7 @@ impl BasicRenderer {
|
||||||
bgl_texture,
|
bgl_texture,
|
||||||
default_texture,
|
default_texture,
|
||||||
depth_buffer_texture: depth_texture,
|
depth_buffer_texture: depth_texture,
|
||||||
|
entity_last_transforms: HashMap::new(),
|
||||||
|
|
||||||
light_buffers: light_uniform_buffers,
|
light_buffers: light_uniform_buffers,
|
||||||
material_buffer: mat_buffer,
|
material_buffer: mat_buffer,
|
||||||
|
@ -242,7 +246,7 @@ impl BasicRenderer {
|
||||||
};
|
};
|
||||||
|
|
||||||
// create the default pipelines
|
// create the default pipelines
|
||||||
let mut pipelines = rustc_hash::FxHashMap::default();
|
let mut pipelines = HashMap::new();
|
||||||
pipelines.insert(0, Arc::new(FullRenderPipeline::new(&s.device, &s.config, &shader,
|
pipelines.insert(0, Arc::new(FullRenderPipeline::new(&s.device, &s.config, &shader,
|
||||||
vec![super::vertex::Vertex::desc(),],
|
vec![super::vertex::Vertex::desc(),],
|
||||||
vec![&s.bgl_texture, &s.transform_buffers.bindgroup_layout,
|
vec![&s.bgl_texture, &s.transform_buffers.bindgroup_layout,
|
||||||
|
@ -394,68 +398,64 @@ impl BasicRenderer {
|
||||||
true
|
true
|
||||||
} else { false }
|
} else { false }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(self, now, transform, entity))]
|
||||||
|
fn interpolate_transforms(&mut self, now: Instant, last_epoch: Tick, entity: Entity, transform: &Transform, transform_epoch: Tick) -> Transform {
|
||||||
|
let cached = match self.entity_last_transforms.get_mut(&entity) {
|
||||||
|
Some(last) if transform_epoch == last_epoch => {
|
||||||
|
last.from_transform = last.to_transform;
|
||||||
|
last.to_transform = *transform;
|
||||||
|
last.last_updated_at = Some(last.cached_at);
|
||||||
|
last.cached_at = now;
|
||||||
|
|
||||||
|
last.clone()
|
||||||
|
},
|
||||||
|
Some(last) => last.clone(),
|
||||||
|
None => {
|
||||||
|
let cached = CachedTransform {
|
||||||
|
last_updated_at: None,
|
||||||
|
cached_at: now,
|
||||||
|
from_transform: *transform,
|
||||||
|
to_transform: *transform,
|
||||||
|
};
|
||||||
|
self.entity_last_transforms.insert(entity, cached.clone());
|
||||||
|
cached
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let fixed_time = match cached.last_updated_at {
|
||||||
|
Some(last_updated_at) => cached.cached_at - last_updated_at,
|
||||||
|
None => now - cached.cached_at
|
||||||
|
}.as_secs_f32();
|
||||||
|
let accumulator = (now - cached.cached_at).as_secs_f32();
|
||||||
|
let alpha = accumulator / fixed_time;
|
||||||
|
|
||||||
|
cached.from_transform.lerp(cached.to_transform, alpha)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer for BasicRenderer {
|
impl Renderer for BasicRenderer {
|
||||||
#[instrument(skip(self, main_world))]
|
#[instrument(skip(self, main_world))]
|
||||||
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 view = main_world.view_iter::<(
|
let view = main_world.view_iter::<(Entities, &Transform, TickOf<Transform>,
|
||||||
Entities,
|
Or<(&MeshHandle, TickOf<MeshHandle>), (&SceneHandle, TickOf<SceneHandle>)>)>();
|
||||||
&Transform,
|
|
||||||
TickOf<Transform>,
|
|
||||||
Or<
|
|
||||||
(&MeshHandle, TickOf<MeshHandle>),
|
|
||||||
(&SceneHandle, TickOf<SceneHandle>)
|
|
||||||
>,
|
|
||||||
Option<&mut InterpTransform>,
|
|
||||||
Res<DeltaTime>,
|
|
||||||
)>();
|
|
||||||
|
|
||||||
// used to store InterpTransform components to add to entities later
|
for (entity, transform, transform_epoch, (mesh_pair, scene_pair)) in view {
|
||||||
let mut component_queue: Vec<(Entity, InterpTransform)> = vec![];
|
|
||||||
|
|
||||||
for (
|
|
||||||
entity,
|
|
||||||
transform,
|
|
||||||
_transform_epoch,
|
|
||||||
(
|
|
||||||
mesh_pair,
|
|
||||||
scene_pair
|
|
||||||
),
|
|
||||||
interp_tran,
|
|
||||||
delta_time,
|
|
||||||
) in view
|
|
||||||
{
|
|
||||||
alive_entities.insert(entity);
|
alive_entities.insert(entity);
|
||||||
|
|
||||||
let interp_transform = match interp_tran {
|
|
||||||
Some(mut interp_transform) => {
|
|
||||||
// found in https://youtu.be/YJB1QnEmlTs?t=472
|
|
||||||
interp_transform.alpha = 1.0 - interp_transform.alpha.powf(**delta_time);
|
|
||||||
|
|
||||||
interp_transform.last_transform = interp_transform.last_transform.lerp(*transform, interp_transform.alpha);
|
|
||||||
interp_transform.last_transform
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
let interp = InterpTransform {
|
|
||||||
last_transform: *transform,
|
|
||||||
alpha: 0.5,
|
|
||||||
};
|
|
||||||
component_queue.push((entity, interp));
|
|
||||||
|
|
||||||
*transform
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some((mesh_han, mesh_epoch)) = mesh_pair {
|
if let Some((mesh_han, mesh_epoch)) = mesh_pair {
|
||||||
|
// TODO: speed up interpolating transforms
|
||||||
|
let interop_pos = *transform; //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() {
|
||||||
// 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, interp_transform, &*mesh, mesh_han.uuid())
|
if !self.process_mesh(entity, interop_pos, &*mesh, mesh_han.uuid())
|
||||||
&& mesh_epoch == last_epoch {
|
&& mesh_epoch == last_epoch {
|
||||||
self.check_mesh_buffers(entity, &mesh_han);
|
self.check_mesh_buffers(entity, &mesh_han);
|
||||||
}
|
}
|
||||||
|
@ -466,7 +466,7 @@ impl Renderer for BasicRenderer {
|
||||||
|
|
||||||
let group = TransformGroup::EntityRes(entity, mesh_han.uuid());
|
let group = TransformGroup::EntityRes(entity, mesh_han.uuid());
|
||||||
let transform_id = self.transform_buffers.update_or_push(&self.device, &self.queue, &self.render_limits,
|
let transform_id = self.transform_buffers.update_or_push(&self.device, &self.queue, &self.render_limits,
|
||||||
group, interp_transform.calculate_mat4(), glam::Mat3::from_quat(interp_transform.rotation));
|
group, interop_pos.calculate_mat4(), glam::Mat3::from_quat(interop_pos.rotation));
|
||||||
|
|
||||||
let material = mesh.material.as_ref().unwrap()
|
let material = mesh.material.as_ref().unwrap()
|
||||||
.data_ref().unwrap();
|
.data_ref().unwrap();
|
||||||
|
@ -483,9 +483,12 @@ impl Renderer for BasicRenderer {
|
||||||
lyra_scene::system_update_world_transforms(scene.world(), view).unwrap();
|
lyra_scene::system_update_world_transforms(scene.world(), view).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: speed up interpolating transforms
|
||||||
|
let interpo_pos = *transform; //self.interpolate_transforms(now_inst, last_epoch, entity, &transform, transform_epoch);
|
||||||
|
|
||||||
for (mesh_han, pos) in scene.world().view_iter::<(&MeshHandle, &WorldTransform)>() {
|
for (mesh_han, pos) in scene.world().view_iter::<(&MeshHandle, &WorldTransform)>() {
|
||||||
if let Some(mesh) = mesh_han.data_ref() {
|
if let Some(mesh) = mesh_han.data_ref() {
|
||||||
let mesh_interpo = interp_transform + **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
|
||||||
|
@ -515,10 +518,6 @@ impl Renderer for BasicRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (en, interp) in component_queue {
|
|
||||||
main_world.insert(en, interp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// collect dead entities
|
// collect dead entities
|
||||||
self.transform_buffers.send_to_gpu(&self.queue);
|
self.transform_buffers.send_to_gpu(&self.queue);
|
||||||
|
|
||||||
|
@ -532,9 +531,10 @@ impl Renderer for BasicRenderer {
|
||||||
self.mesh_buffers.retain(|u, _| !removed_entities.contains(u));
|
self.mesh_buffers.retain(|u, _| !removed_entities.contains(u));
|
||||||
}
|
}
|
||||||
|
|
||||||
// update camera uniform
|
|
||||||
if let Some(camera) = main_world.view_iter::<&mut CameraComponent>().next() {
|
if let Some(camera) = main_world.view_iter::<&mut CameraComponent>().next() {
|
||||||
let uniform = self.inuse_camera.calc_view_projection(&camera);
|
let uniform = self.inuse_camera.calc_view_projection(&camera);
|
||||||
|
//let pos = camera.transform.translation;
|
||||||
|
//let uniform = CameraUniform::new(view_mat, *view_proj, pos);
|
||||||
self.camera_buffer.write_buffer(&self.queue, 0, &[uniform]);
|
self.camera_buffer.write_buffer(&self.queue, 0, &[uniform]);
|
||||||
} else {
|
} else {
|
||||||
warn!("Missing camera!");
|
warn!("Missing camera!");
|
||||||
|
|
Loading…
Reference in New Issue