Changed to a single dynamic model

This commit is contained in:
Sam 2022-02-15 13:47:25 -05:00
parent 0542e46e7d
commit cfbb3a5bca
6 changed files with 46 additions and 59 deletions

View File

@ -109,6 +109,10 @@ impl<V: Vertex> Mesh<V> {
pub fn iter_mut(&mut self, vertex_range: Range<usize>) -> std::slice::IterMut<V> {
self.verts[vertex_range].iter_mut()
}
pub fn len(&self) -> usize { self.verts.len() }
pub fn is_empty(&self) -> bool { self.len() == 0 }
}
impl<V: Vertex> IntoIterator for Mesh<V> {

View File

@ -18,6 +18,8 @@ impl Vertex {
attributes: &ATTRIBUTES,
}
}
pub fn zero() -> Self { Self { pos: [0.0; 3] } }
}
impl VertexTrait for Vertex {

View File

@ -1232,6 +1232,7 @@ impl Renderer {
/// Create a new dynamic model with the specified size.
pub fn create_dynamic_model<V: Vertex>(&mut self, size: usize) -> DynamicModel<V> {
self.ensure_sufficient_index_length::<V>(size);
DynamicModel::new(&self.device, size)
}

View File

@ -572,7 +572,7 @@ impl FigureMgr {
pub fn maintain(
&mut self,
renderer: &mut Renderer,
trail_mgr: &TrailMgr,
trail_mgr: &mut TrailMgr,
scene_data: &SceneData,
// Visible chunk data.
visible_psr_bounds: math::Aabr<f32>,
@ -6294,7 +6294,7 @@ impl<S: Skeleton> FigureState<S> {
pub fn update<const N: usize>(
&mut self,
renderer: &mut Renderer,
trail_mgr: Option<&TrailMgr>,
trail_mgr: Option<&mut TrailMgr>,
buf: &mut [anim::FigureBoneData; anim::MAX_BONE_COUNT],
FigureUpdateCommonParameters {
entity,
@ -6458,11 +6458,10 @@ impl<S: Skeleton> FigureState<S> {
});
let offsets_abs_trail_points = weapon_offsets.map(|(a, b)| (a + pos, b + pos));
if let Some(trail_mgr) = trail_mgr {
if let Some(dynamic_model) = entity
if let Some(quad_mesh) = entity
.as_ref()
.and_then(|e| trail_mgr.dynamic_models.get(e))
.and_then(|e| trail_mgr.entity_meshes.get_mut(e))
{
let mut quad_mesh = Mesh::new();
let quad = if let (Some((p1, p2)), Some((p4, p3))) =
(self.abs_trail_points, offsets_abs_trail_points)
{
@ -6490,8 +6489,7 @@ impl<S: Skeleton> FigureState<S> {
let zero = trail::Vertex { pos: [0.0; 3] };
Quad::new(zero, zero, zero, zero)
};
quad_mesh.push_quad(quad);
renderer.update_model(dynamic_model, &quad_mesh, trail_mgr.offset * 4);
quad_mesh.replace_quad(trail_mgr.offset * 4, quad);
}
}
self.abs_trail_points = offsets_abs_trail_points;

View File

@ -698,7 +698,7 @@ impl Scene {
// Maintain the figures.
let _figure_bounds = self.figure_mgr.maintain(
renderer,
&self.trail_mgr,
&mut self.trail_mgr,
scene_data,
visible_psr_bounds,
&self.camera,

View File

@ -1,7 +1,5 @@
use super::SceneData;
use crate::render::{
pipelines::trail, DynamicModel, Mesh, Quad, Renderer, TrailDrawer, TrailVertex,
};
use crate::render::{DynamicModel, Mesh, Quad, Renderer, TrailDrawer, TrailVertex};
use common::comp::CharacterState;
use common_base::span;
use specs::{Entity as EcsEntity, Join, WorldExt};
@ -9,24 +7,24 @@ use std::collections::HashMap;
// use vek::*;
pub struct TrailMgr {
/// Keep track of lifetimes
// trails: Vec<Trail>,
/// GPU vertex buffers
pub dynamic_models: HashMap<EcsEntity, DynamicModel<TrailVertex>>,
/// Meshes for each entity
pub entity_meshes: HashMap<EcsEntity, Mesh<TrailVertex>>,
/// Offset
pub offset: usize,
/// Dynamic model to upload to GPU
dynamic_model: DynamicModel<TrailVertex>,
}
const TRAIL_DYNAMIC_MODEL_SIZE: usize = 15;
impl TrailMgr {
pub fn new(_renderer: &mut Renderer) -> Self {
pub fn new(renderer: &mut Renderer) -> Self {
Self {
// trails: Vec::new(),
dynamic_models: HashMap::new(),
entity_meshes: HashMap::new(),
offset: 0,
dynamic_model: renderer.create_dynamic_model(0),
}
}
@ -34,67 +32,51 @@ impl TrailMgr {
span!(_guard, "maintain", "TrailMgr::maintain");
if scene_data.weapon_trails_enabled {
// remove dead Trails
// self.trails
// .retain(|t| t.alive_until > scene_data.state.get_time());
// Update offset
self.offset = (self.offset + 1) % TRAIL_DYNAMIC_MODEL_SIZE;
// Update dynamic models
// TODO: Automatically make mesh 0 at this offset for all entities
// Create a mesh for each entity that doesn't already have one
let ecs = scene_data.state.ecs();
for (entity, _char_state) in
(&ecs.entities(), &ecs.read_storage::<CharacterState>()).join()
{
if let Ok(model) = self.dynamic_models.try_insert(
entity,
renderer.create_dynamic_model(TRAIL_DYNAMIC_MODEL_SIZE * 4),
) {
let mut mesh = Mesh::new();
let zero = trail::Vertex { pos: [0.0; 3] };
// Result returned doesn't matter, it just needs to only insert if entry didn't
// already exist
if let Ok(mesh) = self.entity_meshes.try_insert(entity, Mesh::new()) {
// Allocate up to necessary length so repalce_quad works as expected elsewhere
let zero = TrailVertex::zero();
for _ in 0..TRAIL_DYNAMIC_MODEL_SIZE {
mesh.push_quad(Quad::new(zero, zero, zero, zero));
}
renderer.update_model(model, &mesh, 0);
}
}
// Clear dynamic models for entities that no longer exist (is this even
// Clear meshes for entities that no longer exist (is this even
// necessary? not sure if this growing too big is a concern)
self.dynamic_models
.retain(|entity, _| ecs.entities().is_alive(*entity))
self.entity_meshes
.retain(|entity, _| ecs.entities().is_alive(*entity));
// Create dynamic model from currently existing meshes
self.dynamic_model = {
let mut big_mesh = Mesh::new();
self.entity_meshes
.values()
.for_each(|mesh| big_mesh.push_mesh(mesh));
let dynamic_model = renderer.create_dynamic_model(big_mesh.len());
renderer.update_model(&dynamic_model, &big_mesh, 0);
dynamic_model
};
} else {
// if !self.trails.is_empty() {
// self.trails.clear();
// }
self.entity_meshes.clear();
}
}
pub fn render<'a>(&'a self, drawer: &mut TrailDrawer<'_, 'a>, scene_data: &SceneData) {
span!(_guard, "render", "TrailMgr::render");
if scene_data.weapon_trails_enabled {
for dynamic_model in self.dynamic_models.values() {
drawer.draw(dynamic_model);
}
drawer.draw(&self.dynamic_model);
}
}
}
// struct Trail {
// entity: EcsEntity,
// pos1: Vec3<f32>,
// pos2: Vec3<f32>,
// alive_until: f64,
// }
// impl Trail {
// pub fn new(entity: EcsEntity, pos1: Vec3<f32>, pos2: Vec3<f32>, time:
// f64) -> Self { const LIFETIME: f64 = 1.0;
// Self {
// entity,
// pos1,
// pos2,
// alive_until: time + LIFETIME,
// }
// }
// }