diff options
author | metamuffin <metamuffin@disroot.org> | 2025-01-17 17:51:27 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-01-17 17:51:27 +0100 |
commit | 7ead3dfc316fb109f8f30eea1aa00eb01a4ce1a6 (patch) | |
tree | 4c838cc71b563004cb0fdc970bf7920e67fe50b9 | |
parent | 0f0dc1045c224ba36e95c5cef06c3f9561e07599 (diff) | |
download | weareserver-7ead3dfc316fb109f8f30eea1aa00eb01a4ce1a6.tar weareserver-7ead3dfc316fb109f8f30eea1aa00eb01a4ce1a6.tar.bz2 weareserver-7ead3dfc316fb109f8f30eea1aa00eb01a4ce1a6.tar.zst |
world: texture cache uri to res
-rw-r--r-- | world/src/main.rs | 36 | ||||
-rw-r--r-- | world/src/mesh.rs | 10 |
2 files changed, 39 insertions, 7 deletions
diff --git a/world/src/main.rs b/world/src/main.rs index 4845db3..c32b810 100644 --- a/world/src/main.rs +++ b/world/src/main.rs @@ -30,11 +30,13 @@ use rand::random; use rayon::iter::{ParallelBridge, ParallelIterator}; use std::{ borrow::Cow, + collections::HashMap, fs::File, io::{Cursor, Read, Write}, marker::PhantomData, net::{SocketAddr, TcpStream}, path::{Path, PathBuf}, + sync::{Arc, Mutex}, thread::{self, sleep}, time::Duration, }; @@ -88,6 +90,7 @@ fn main() -> Result<()> { let store = ResourceStore::new_memory(); let mut prefabs = Vec::new(); + let texture_cache = Arc::new(Mutex::new(HashMap::new())); for scenepath in &args.scene { let path_base = scenepath.parent().unwrap(); @@ -101,7 +104,16 @@ fn main() -> Result<()> { .map(|node| { let mut prefab = Prefab::default(); if let Some(mesh) = node.mesh() { - import_mesh(mesh, &buffers, &store, path_base, &node, &mut prefab, &args)?; + import_mesh( + mesh, + &buffers, + &store, + path_base, + &node, + &mut prefab, + &args, + &texture_cache, + )?; } let (position, _, _) = node.transform().decomposed(); if let Some(light) = node.light() { @@ -237,6 +249,7 @@ fn main() -> Result<()> { Ok(()) } +pub type TextureCache = Arc<Mutex<HashMap<String, Resource<Image<'static>>>>>; fn load_texture( name: &str, store: &ResourceStore, @@ -244,33 +257,40 @@ fn load_texture( buffers: &[gltf::buffer::Data], source: &Source, webp: bool, + texture_cache: &TextureCache, ) -> Result<Resource<Image<'static>>> { - let mut image = match source { + let (mut image, uri) = match source { gltf::image::Source::View { view, mime_type } => { debug!("{name} texture is embedded and of type {mime_type:?}"); let buf = &buffers[view.buffer().index()].0[view.offset()..view.offset() + view.length()]; - Image(Cow::Borrowed(buf)) + (Image(Cow::Borrowed(buf)), None) } gltf::image::Source::Uri { uri, mime_type: Some(mime_type), } => { debug!("{name} texture is {uri:?} and of type {mime_type:?}"); + if let Some(res) = texture_cache.lock().unwrap().get(*uri) { + return Ok(res.to_owned()); + } let path = path.join(uri); let mut buf = Vec::new(); File::open(path)?.read_to_end(&mut buf)?; - Image(buf.into()) + (Image(buf.into()), Some(uri.to_string())) } gltf::image::Source::Uri { uri, mime_type: None, } => { debug!("{name} texture is {uri:?} and has no type"); + if let Some(res) = texture_cache.lock().unwrap().get(*uri) { + return Ok(res.to_owned()); + } let path = path.join(uri); let mut buf = Vec::new(); File::open(path)?.read_to_end(&mut buf)?; - Image(buf.into()) + (Image(buf.into()), Some(uri.to_string())) } }; @@ -285,5 +305,9 @@ fn load_texture( debug!("webp encode: {len} -> {}", image_out.len()); image = Image(Cow::Owned(image_out)); } - Ok(Resource(store.set(&image)?.0, PhantomData)) + let res = Resource(store.set(&image)?.0, PhantomData); + if let Some(uri) = uri { + texture_cache.lock().unwrap().insert(uri, res.clone()); + } + Ok(res) } diff --git a/world/src/mesh.rs b/world/src/mesh.rs index de4617f..2bcf4c0 100644 --- a/world/src/mesh.rs +++ b/world/src/mesh.rs @@ -14,7 +14,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. */ -use crate::{Args, load_texture}; +use crate::{Args, TextureCache, load_texture}; use anyhow::Result; use gltf::{Mesh, Node, buffer::Data}; use log::{debug, info}; @@ -34,6 +34,7 @@ pub fn import_mesh( node: &Node, prefab: &mut Prefab, args: &Args, + texture_cache: &TextureCache, ) -> Result<()> { Ok(for p in mesh.primitives() { let name = mesh.name().or(node.name()).map(|e| e.to_owned()); @@ -121,6 +122,7 @@ pub fn import_mesh( &buffers, &tex.texture().source().source(), args.webp, + texture_cache, )?; tex_albedo = Some(r.clone()); tex_alpha = Some(r.clone()); @@ -134,6 +136,7 @@ pub fn import_mesh( &buffers, &tex.texture().source().source(), args.webp, + texture_cache, )?); } let mut tex_emission = None; @@ -145,6 +148,7 @@ pub fn import_mesh( &buffers, &tex.texture().source().source(), args.webp, + texture_cache, )?); } let mut tex_transmission = None; @@ -161,6 +165,7 @@ pub fn import_mesh( &buffers, &tex.texture().source().source(), args.webp, + texture_cache, )?); } let mut tex_thickness = None; @@ -177,6 +182,7 @@ pub fn import_mesh( &buffers, &tex.texture().source().source(), args.webp, + texture_cache, )?); } let mut tex_occlusion = None; @@ -188,6 +194,7 @@ pub fn import_mesh( &buffers, &tex.texture().source().source(), args.webp, + texture_cache, )?); } let mut tex_roughness = None; @@ -204,6 +211,7 @@ pub fn import_mesh( &buffers, &tex.texture().source().source(), args.webp, + texture_cache, )?; tex_roughness = Some(r.clone()); tex_metallic = Some(r.clone()); |