84 lines
2.5 KiB
Rust
84 lines
2.5 KiB
Rust
//! Fixed-room pooling of mesh data.
|
|
|
|
use super::*;
|
|
use std::sync::Arc;
|
|
|
|
/// A mesh that has been allocated in a [MeshGroup].
|
|
pub struct MeshAlloc {
|
|
pub attributes: SmallVec<[(usize, AttrId); MAX_MESH_INLINE_ATTRIBUTES]>,
|
|
}
|
|
|
|
/// A set of GPU-side vertex attribute pools and index pools.
|
|
pub struct MeshGroup {
|
|
id: usize,
|
|
attr_store: Arc<AttrStore>,
|
|
pools: HashMap<AttrId, AttrPool>,
|
|
meshes: Slab<MeshAlloc>,
|
|
}
|
|
|
|
impl MeshGroup {
|
|
pub fn new(id: usize, attr_store: Arc<AttrStore>) -> Self {
|
|
Self {
|
|
id,
|
|
attr_store,
|
|
pools: Default::default(),
|
|
meshes: Default::default(),
|
|
}
|
|
}
|
|
|
|
/// Checks to see if a mesh can be loaded within this group.
|
|
pub fn can_load(&self, buf: &MeshBuffer) -> Result<(), PoolError> {
|
|
for attr in buf.attributes.iter() {
|
|
match self.pools.get(&attr.id) {
|
|
None => {
|
|
match self.attr_store.get_info(&attr.id) {
|
|
Some(_) => {} // new pools of valid attrs can be made
|
|
None => return Err(PoolError::AttrUnregistered),
|
|
};
|
|
}
|
|
Some(pool) => {
|
|
pool.can_load(attr)?;
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Tries to load a [MeshBuffer] into this pool. Returns a [MeshHandle].
|
|
pub fn load(&mut self, buf: &MeshBuffer) -> Result<(MeshHandle, Vec<CopyInfo>), PoolError> {
|
|
self.can_load(&buf)?;
|
|
|
|
let mut allocs = SmallVec::with_capacity(buf.attributes.len());
|
|
let mut copies = Vec::new();
|
|
|
|
for attr in buf.attributes.iter() {
|
|
let id = &attr.id;
|
|
let pool = match self.pools.get_mut(id) {
|
|
Some(pool) => pool,
|
|
None => {
|
|
let info = match self.attr_store.get_info(id) {
|
|
Some(info) => *info,
|
|
None => return Err(PoolError::AttrUnregistered),
|
|
};
|
|
|
|
let new_pool = AttrPool::new(self.id, *id, info)?;
|
|
self.pools.insert(*id, new_pool);
|
|
self.pools.get_mut(id).unwrap()
|
|
}
|
|
};
|
|
|
|
let (alloc, copy) = pool.load(attr)?;
|
|
allocs.push((alloc, attr.id));
|
|
copies.push(copy);
|
|
}
|
|
|
|
let mesh = MeshAlloc { attributes: allocs };
|
|
let sub = self.meshes.insert(mesh);
|
|
let group = self.id;
|
|
let handle = MeshHandle { group, sub };
|
|
|
|
Ok((handle, copies))
|
|
}
|
|
}
|