diff options
Diffstat (limited to 'world')
-rw-r--r-- | world/src/main.rs | 8 | ||||
-rw-r--r-- | world/src/mesh.rs | 95 | ||||
-rw-r--r-- | world/src/physics.rs | 73 |
3 files changed, 112 insertions, 64 deletions
diff --git a/world/src/main.rs b/world/src/main.rs index 5dbfd06..c90ff0c 100644 --- a/world/src/main.rs +++ b/world/src/main.rs @@ -16,6 +16,7 @@ */ #![feature(iter_array_chunks)] pub mod mesh; +pub mod physics; use anyhow::{Result, bail}; use clap::Parser; @@ -23,6 +24,7 @@ use gltf::{Gltf, image::Source, import_buffers}; use image::{ImageReader, codecs::webp::WebPEncoder}; use log::info; use mesh::import_mesh; +use physics::import_physics; use rand::random; use std::{ fs::File, @@ -93,6 +95,7 @@ fn main() -> Result<()> { for node in gltf.nodes() { if let Some(mesh) = node.mesh() { + info!("--- MESH ---"); import_mesh( mesh, &buffers, @@ -105,7 +108,11 @@ fn main() -> Result<()> { } let (position, _, _) = node.transform().decomposed(); if let Some(light) = node.light() { + info!("--- LIGHT ---"); let emission = Some(Vec3A::from_array(light.color()) * light.intensity()); + if let Some(e) = emission { + info!("emission is {e}"); + } prefab.light.push(( Vec3A::from_array(position), store.set(&LightPart { @@ -114,6 +121,7 @@ fn main() -> Result<()> { })?, )); } + import_physics(&gltf, &node, &mut prefab, &store, &buffers)?; } if let Some(skybox) = args.skybox { diff --git a/world/src/mesh.rs b/world/src/mesh.rs index c621753..67f86ad 100644 --- a/world/src/mesh.rs +++ b/world/src/mesh.rs @@ -21,8 +21,9 @@ use log::{debug, info}; use std::path::Path; use weareshared::{ Affine3A, Vec3A, - resources::{AttributeArray, IndexArray, MeshPart, Prefab}, + resources::{MeshPart, Prefab}, store::ResourceStore, + vec2, vec3a, }; pub fn import_mesh( @@ -40,77 +41,39 @@ pub fn import_mesh( 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))?, - store.set(&AttributeArray(pos_y))?, - store.set(&AttributeArray(pos_z))?, - ]) + let a = iter.map(|[x, y, z]| vec3a(x, y, z)).collect::<Vec<_>>(); + info!("{} vertex positions", a.len()); + Ok::<_, anyhow::Error>(store.set(&a)?) }) .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))?, - store.set(&AttributeArray(normal_y))?, - store.set(&AttributeArray(normal_z))?, - ]) + let a = iter.map(|[x, y, z]| vec3a(x, y, z)).collect::<Vec<_>>(); + info!("{} vertex normals", a.len()); + Ok::<_, anyhow::Error>(store.set(&a)?) }) .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))?, - store.set(&AttributeArray(texcoord_v))?, - ]) + let a = iter.into_f32().map(|[x, y]| vec2(x, y)).collect::<Vec<_>>(); + info!("{} vertex texture coordinates", a.len()); + Ok::<_, anyhow::Error>(store.set(&a)?) }) .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))?, - store.set(&AttributeArray(color_g))?, - store.set(&AttributeArray(color_b))?, - ]) + let a = iter + .into_rgb_f32() + .map(|[x, y, z]| vec3a(x, y, z)) + .collect::<Vec<_>>(); + info!("{} vertex colors", a.len()); + Ok::<_, anyhow::Error>(store.set(&a)?) }) .transpose()?; @@ -123,7 +86,7 @@ pub fn import_mesh( } let o = if color_a.iter().any(|x| *x != 1.) { info!("{} vertex transmissions", color_a.len()); - Some(store.set(&AttributeArray(color_a))?) + Some(store.set(&color_a)?) } else { debug!("vertex transmission pruned"); None @@ -141,7 +104,7 @@ pub fn import_mesh( .array_chunks::<3>() .collect::<Vec<_>>(); info!("{} indecies", index.len() * 3); - let index = Some(store.set(&IndexArray(index))?); + let index = Some(store.set(&index)?); let mut tex_albedo = None; let mut tex_alpha = None; @@ -370,13 +333,17 @@ pub fn import_mesh( va_metallic: None, va_roughness: None, })?; - 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)) + + prefab.mesh.push((node_transform_to_affine(node), mesh)) }) } + +pub fn node_transform_to_affine(node: &Node) -> Affine3A { + let mat = node.transform().matrix(); + 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]], + ]) +} diff --git a/world/src/physics.rs b/world/src/physics.rs new file mode 100644 index 0000000..82bb28f --- /dev/null +++ b/world/src/physics.rs @@ -0,0 +1,73 @@ +use anyhow::{Result, anyhow}; +use gltf::{Gltf, Node, buffer::Data, json::Value}; +use log::info; +use weareshared::{ + resources::{CollisionPart, Prefab}, + store::ResourceStore, + vec3a, +}; + +use crate::mesh::node_transform_to_affine; + +pub fn import_physics( + gltf: &Gltf, + node: &Node, + prefab: &mut Prefab, + store: &ResourceStore, + buffers: &[Data], +) -> Result<()> { + if let Some(physics) = node + .extensions() + .map(|e| e.get("KHR_physics_rigid_bodies")) + .flatten() + { + info!("--- COLLISION ---"); + if let Some(collider) = physics.get("collider") { + if let Some(geometry) = collider.get("geometry") { + if geometry.get("convexHull") == Some(&Value::Bool(true)) { + let node = geometry + .get("node") + .map(|n| n.as_u64()) + .flatten() + .ok_or(anyhow!("convexHull node missing"))?; + let node = gltf + .nodes() + .nth(node as usize) + .ok_or(anyhow!("convexHull node reference invalid"))?; + let mesh = node.mesh().ok_or(anyhow!("convexHull node has no mesh"))?; + for p in mesh.primitives() { + let reader = p.reader(|buf| Some(&buffers[buf.index()])); + + let index = reader + .read_indices() + .ok_or(anyhow!("convexHull no index buffer"))? + .into_u32() + .map(|e| e as u16) + .array_chunks::<3>() + .collect::<Vec<_>>(); + let position = reader + .read_positions() + .ok_or(anyhow!("convexHull no positions"))? + .map(|[x, y, z]| vec3a(x, y, z)) + .collect::<Vec<_>>(); + + info!( + "convex hull has {} indecies and {} positions", + index.len(), + position.len() + ); + + prefab.collision.push(( + node_transform_to_affine(&node), + store.set(&CollisionPart { + sh_mesh: Some((store.set(&index)?, store.set(&position)?)), + ..Default::default() + })?, + )); + } + } + } + } + } + Ok(()) +} |