From 7ead3dfc316fb109f8f30eea1aa00eb01a4ce1a6 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Fri, 17 Jan 2025 17:51:27 +0100 Subject: world: texture cache uri to res --- world/src/main.rs | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) (limited to 'world/src/main.rs') 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>>>>; 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>> { - 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) } -- cgit v1.2.3-70-g09d2