diff options
Diffstat (limited to 'world/src/main.rs')
-rw-r--r-- | world/src/main.rs | 267 |
1 files changed, 29 insertions, 238 deletions
diff --git a/world/src/main.rs b/world/src/main.rs index ce50cea..bbbe4f9 100644 --- a/world/src/main.rs +++ b/world/src/main.rs @@ -15,10 +15,13 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ #![feature(iter_array_chunks)] +pub mod mesh; + use anyhow::{Result, bail}; use clap::Parser; use gltf::image::Source; -use log::{debug, info}; +use log::info; +use mesh::import_mesh; use rand::random; use std::{ fs::File, @@ -29,9 +32,9 @@ use std::{ time::Duration, }; use weareshared::{ - Affine3A, Vec3A, + Vec3A, packets::{Data, Object, Packet, ReadWrite, Resource}, - resources::{AttributeArray, IndexArray, MeshPart, Prefab}, + resources::{Image, LightPart, Prefab}, store::ResourceStore, vec3a, }; @@ -44,6 +47,8 @@ struct Args { push: bool, #[arg(short, long)] spin: bool, + #[arg(short, long)] + clear: bool, } fn main() -> Result<()> { @@ -61,241 +66,20 @@ fn main() -> Result<()> { let mut prefab = Prefab::default(); for node in gltf.nodes() { if let Some(mesh) = node.mesh() { - for p in mesh.primitives() { - let reader = p.reader(|buf| Some(&buffers[buf.index()])); - - let va_position = reader - .read_positions() - .map(|iter| { - let mut pos_x = vec![]; - let mut pos_y = vec![]; - let mut pos_z = vec![]; - for p in iter { - pos_x.push(p[0]); - pos_y.push(p[1]); - pos_z.push(p[2]); - } - info!("{} vertex positions", pos_x.len()); - Ok::<_, anyhow::Error>([ - store.set(&AttributeArray(pos_x).write_alloc())?, - store.set(&AttributeArray(pos_y).write_alloc())?, - store.set(&AttributeArray(pos_z).write_alloc())?, - ]) - }) - .transpose()?; - - let va_normal = reader - .read_normals() - .map(|iter| { - let mut normal_x = vec![]; - let mut normal_y = vec![]; - let mut normal_z = vec![]; - for p in iter { - normal_x.push(p[0]); - normal_y.push(p[1]); - normal_z.push(p[2]); - } - info!("{} vertex normals", normal_x.len()); - Ok::<_, anyhow::Error>([ - store.set(&AttributeArray(normal_x).write_alloc())?, - store.set(&AttributeArray(normal_y).write_alloc())?, - store.set(&AttributeArray(normal_z).write_alloc())?, - ]) - }) - .transpose()?; - - let va_texcoord = reader - .read_tex_coords(0) - .map(|iter| { - let mut texcoord_u = vec![]; - let mut texcoord_v = vec![]; - for p in iter.into_f32() { - texcoord_u.push(p[0]); - texcoord_v.push(p[1]); - } - info!("{} vertex texture coordinates", texcoord_u.len()); - Ok::<_, anyhow::Error>([ - store.set(&AttributeArray(texcoord_u).write_alloc())?, - store.set(&AttributeArray(texcoord_v).write_alloc())?, - ]) - }) - .transpose()?; - - let va_albedo = reader - .read_colors(0) - .map(|iter| { - let mut color_r = vec![]; - let mut color_g = vec![]; - let mut color_b = vec![]; - for p in iter.into_rgb_f32() { - color_r.push(p[0]); - color_g.push(p[1]); - color_b.push(p[2]); - } - info!("{} vertex colors", color_r.len()); - Ok::<_, anyhow::Error>([ - store.set(&AttributeArray(color_r).write_alloc())?, - store.set(&AttributeArray(color_g).write_alloc())?, - store.set(&AttributeArray(color_b).write_alloc())?, - ]) - }) - .transpose()?; - - let va_transmission = reader - .read_colors(0) - .map(|iter| { - let mut color_a = vec![]; - for p in iter.into_rgba_f32() { - color_a.push(p[3]); - } - let o = if color_a.iter().any(|x| *x != 1.) { - info!("{} vertex transmissions", color_a.len()); - Some(store.set(&AttributeArray(color_a).write_alloc())?) - } else { - debug!("vertex transmission pruned"); - None - }; - Ok::<_, anyhow::Error>(o) - }) - .transpose()? - .flatten(); - - let index = reader - .read_indices() - .unwrap() - .into_u32() - .map(|e| e as u16) - .array_chunks::<3>() - .collect::<Vec<_>>(); - info!("{} indecies", index.len() * 3); - let index = Some(store.set(&IndexArray(index).write_alloc())?); - - let mut tex_albedo = None; - let mut tex_transmission = None; - if let Some(tex) = p.material().pbr_metallic_roughness().base_color_texture() { - let r = load_texture( - "albedo", - &store, - path_base, - &buffers, - &tex.texture().source().source(), - )?; - tex_albedo = Some(r); - tex_transmission = Some(r); - } - let mut tex_normal = None; - if let Some(tex) = p.material().normal_texture() { - tex_normal = Some(load_texture( - "normal", - &store, - path_base, - &buffers, - &tex.texture().source().source(), - )?); - } - let mut tex_emission = None; - if let Some(tex) = p.material().emissive_texture() { - tex_emission = Some(load_texture( - "emission", - &store, - path_base, - &buffers, - &tex.texture().source().source(), - )?); - } - let mut tex_roughness = None; - let mut tex_metallic = None; - if let Some(tex) = p - .material() - .pbr_metallic_roughness() - .metallic_roughness_texture() - { - let r = load_texture( - "metallic+roughness", - &store, - path_base, - &buffers, - &tex.texture().source().source(), - )?; - tex_roughness = Some(r); - tex_metallic = Some(r); - } - - let g_metallic = Some(p.material().pbr_metallic_roughness().metallic_factor()); - let g_roughness = Some(p.material().pbr_metallic_roughness().roughness_factor()); - - let base_color = p.material().pbr_metallic_roughness().base_color_factor(); - - let g_albedo = if base_color[0] != 1. || base_color[1] != 1. || base_color[2] != 1. - { - info!( - "global albedo is r={},g={},b={}", - base_color[0], base_color[1], base_color[2] - ); - Some(Vec3A::new(base_color[0], base_color[1], base_color[2])) - } else { - debug!("global albedo pruned"); - None - }; - let g_transmission = if base_color[3] != 1. { - info!("global transmission is {}", base_color[3]); - Some(base_color[3]) - } else { - debug!("global transmission pruned"); - None - }; - - let emission = p.material().emissive_factor(); - let g_emission = if emission[0] != 0. || emission[1] != 0. || emission[2] != 0. { - info!( - "global emission is r={},g={},b={}", - base_color[0], base_color[1], base_color[2] - ); - Some(Vec3A::new(emission[0], emission[1], emission[2])) - } else { - debug!("global emission pruned"); - None - }; - - let mesh = store.set( - &MeshPart { - g_albedo, - g_transmission, - g_metallic, - g_roughness, - g_emission, - va_position, - va_normal, - va_texcoord, - va_albedo, - va_transmission, - tex_albedo, - tex_normal, - tex_roughness, - tex_metallic, - tex_transmission, - tex_emission, - index, - va_emission: None, // not supported by gltf - va_metallic: None, // not supported by gltf - va_roughness: None, // not supported by gltf - } - .write_alloc(), - )?; - let mat = node.transform().matrix(); - let aff = Affine3A::from_cols_array_2d(&[ - [mat[0][0], mat[0][1], mat[0][2]], - [mat[1][0], mat[1][1], mat[1][2]], - [mat[2][0], mat[2][1], mat[2][2]], - [mat[3][0], mat[3][1], mat[3][2]], - ]); - prefab.mesh.push((aff, mesh)) - } + import_mesh(mesh, &buffers, &store, path_base, &node, &mut prefab)?; } } + prefab.light.push(( + vec3a(5., 5., 5.), + store.set(&LightPart { + emission: Some(vec3a(0.5, 0.1, 1.0)), + radius: Some(0.2), + })?, + )); + let ob = Object::new(); - Packet::Add(ob, store.set(&prefab.write_alloc())?).write(&mut sock)?; + Packet::Add(ob, store.set(&prefab)?).write(&mut sock)?; if args.spin { let mut sock2 = sock.try_clone().unwrap(); @@ -324,11 +108,18 @@ fn main() -> Result<()> { let packet = Packet::read(&mut sock)?; match packet { Packet::RequestResource(hash) => { - if let Some(d) = store.get(hash)? { + if let Some(d) = store.get_raw(hash)? { Packet::RespondResource(Data(d)).write(&mut sock)?; sock.flush()?; } } + Packet::Add(ob_a, _) => { + if ob_a != ob { + info!("removing object {ob_a}"); + Packet::Remove(ob_a).write(&mut sock)?; + sock.flush()?; + } + } _ => (), } } @@ -342,13 +133,13 @@ fn load_texture( path: &Path, buffers: &[gltf::buffer::Data], source: &Source, -) -> Result<Resource> { +) -> Result<Resource<Image>> { match source { gltf::image::Source::View { view, mime_type } => { info!("{name} texture is embedded and of type {mime_type:?}"); let buf = &buffers[view.buffer().index()].0[view.offset()..view.offset() + view.length()]; - return Ok(store.set(buf)?); + return Ok(store.set(&Image(buf.to_vec()))?); } gltf::image::Source::Uri { uri, @@ -358,7 +149,7 @@ fn load_texture( let path = path.join(uri); let mut buf = Vec::new(); File::open(path)?.read_to_end(&mut buf)?; - return Ok(store.set(&buf)?); + return Ok(store.set(&Image(buf))?); } _ => { bail!("texture is external and has no mime type") |