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 ++++++++++++++++++++++++++++++------ world/src/mesh.rs | 10 +++++++++- 2 files changed, 39 insertions(+), 7 deletions(-) (limited to 'world/src') 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) } 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 . */ -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()); -- cgit v1.2.3-70-g09d2