diff options
author | metamuffin <metamuffin@disroot.org> | 2025-02-03 21:46:29 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-02-03 21:46:29 +0100 |
commit | ae14c194a25e258659104e89553ad48a8ae9ca3b (patch) | |
tree | 793b73af2c045d7acf218912afbc182a6720436f | |
parent | 163e10c9f618f0e4cd7b4456476ad1c2322db5d7 (diff) | |
download | weareserver-ae14c194a25e258659104e89553ad48a8ae9ca3b.tar weareserver-ae14c194a25e258659104e89553ad48a8ae9ca3b.tar.bz2 weareserver-ae14c194a25e258659104e89553ad48a8ae9ca3b.tar.zst |
armatures in prefab
-rw-r--r-- | client/src/armature.rs | 6 | ||||
-rw-r--r-- | doc/resources.md | 5 | ||||
-rw-r--r-- | shared/src/resources.rs | 11 | ||||
-rw-r--r-- | world/src/main.rs | 87 | ||||
-rw-r--r-- | world/src/mesh.rs | 10 |
5 files changed, 57 insertions, 62 deletions
diff --git a/client/src/armature.rs b/client/src/armature.rs index daf2725..1156071 100644 --- a/client/src/armature.rs +++ b/client/src/armature.rs @@ -16,18 +16,18 @@ */ use glam::Mat4; use std::sync::Arc; -use weareshared::resources::Armature; +use weareshared::resources::ArmaturePart; use wgpu::{Buffer, BufferDescriptor, BufferUsages, Device, Queue}; const MAX_JOINTS: usize = 128; pub struct RArmature { pub joint_mat_uniform_buffer: Arc<Buffer>, joint_mat: Vec<Mat4>, - _data: Armature, + _data: ArmaturePart, } impl RArmature { - pub fn new(device: &Device, armature: Armature) -> Self { + pub fn new(device: &Device, armature: ArmaturePart) -> Self { Self { joint_mat_uniform_buffer: Arc::new(device.create_buffer(&BufferDescriptor { label: Some("joint uniform"), diff --git a/doc/resources.md b/doc/resources.md index 53bd3c0..67fca4a 100644 --- a/doc/resources.md +++ b/doc/resources.md @@ -30,6 +30,7 @@ | `mesh` | `Affine3`, `Res<MeshPart>` | Multi key | | `collision` | `Affine3`, `Res<ColliderPart>` | Multi key | | `light` | `Vec3`, `Res<LightPart>` | Multi key | +| `armature` | `Res<ArmaturePart>` | Multi key | | `environment` | `Res<EnvironmentPart>` | | ## MeshPart @@ -43,7 +44,7 @@ white except normals are zero. | -------------------- | ------------------- | ------------------ | | `name` | `String` | | | `index` | `Res<[u32; 3]>` | | -| `armature` | `Res<Armature>` | | +| `armature` | `u32` | | | `g_metallic` | `Float` | | | `g_roughness` | `Float` | | | `g_albedo` | `Vec3` | | @@ -100,7 +101,7 @@ white except normals are zero. - **Static Hint**: Object will not move often. This allows implementations to choose instanced rending when MeshPart are added more than once. -## Armature +## ArmaturePart Armature is used for humanoid avatar rigging and generally follows VRM specification. Joints are arranged in a hierarchy where transforms are diff --git a/shared/src/resources.rs b/shared/src/resources.rs index c96621d..654bfc6 100644 --- a/shared/src/resources.rs +++ b/shared/src/resources.rs @@ -30,6 +30,7 @@ pub struct Prefab { pub mesh: Vec<(Affine3A, Resource<MeshPart>)>, pub collision: Vec<(Affine3A, Resource<CollisionPart>)>, pub light: Vec<(Vec3A, Resource<LightPart>)>, + pub armature: Vec<Resource<ArmaturePart>>, pub environment: Option<Resource<EnvironmentPart>>, } @@ -50,7 +51,7 @@ pub struct EnvironmentPart { pub struct MeshPart { pub name: Option<String>, pub index: Option<Resource<Vec<[u32; 3]>>>, - pub armature: Option<Resource<Armature>>, + pub armature: Option<u32>, pub g_metallic: Option<f32>, pub g_roughness: Option<f32>, pub g_albedo: Option<Vec3A>, @@ -89,7 +90,7 @@ pub struct MeshPart { } #[derive(Debug, Default, Clone)] -pub struct Armature { +pub struct ArmaturePart { pub parent: Option<Vec<u16>>, pub transform: Option<Vec<Affine3A>>, pub name: Option<Vec<String>>, @@ -134,7 +135,7 @@ impl ReadWrite for PrefabIndex { } } -impl ReadWrite for Armature { +impl ReadWrite for ArmaturePart { fn write(&self, w: &mut dyn Write) -> Result<()> { write_kv_opt(w, b"parent", &self.parent)?; write_kv_opt(w, b"transform", &self.transform)?; @@ -200,6 +201,9 @@ impl ReadWrite for Prefab { for x in &self.light { write_kv_opt(w, b"light", &Some(x.clone()))?; } + for x in &self.armature { + write_kv_opt(w, b"armature", &Some(x.clone()))?; + } write_kv_opt(w, b"environment", &self.environment)?; Ok(()) } @@ -210,6 +214,7 @@ impl ReadWrite for Prefab { b"mesh" => Ok(s.mesh.push(read_slice(v)?)), b"collision" => Ok(s.collision.push(read_slice(v)?)), b"light" => Ok(s.light.push(read_slice(v)?)), + b"armature" => Ok(s.armature.push(read_slice(v)?)), b"environment" => Ok(s.environment = Some(read_slice(v)?)), x => Ok(warn!( "unknown prefab key: {:?}", diff --git a/world/src/main.rs b/world/src/main.rs index b0b9dad..67747c8 100644 --- a/world/src/main.rs +++ b/world/src/main.rs @@ -45,7 +45,7 @@ use weareshared::{ Affine3A, Vec3A, helper::ReadWrite, packets::{Data, Object, Packet, Resource}, - resources::{Armature, EnvironmentPart, Image, LightPart, Prefab}, + resources::{ArmaturePart, EnvironmentPart, Image, LightPart, Prefab}, store::ResourceStore, vec3a, }; @@ -126,50 +126,6 @@ fn main() -> Result<()> { traverse(&mut nodes, node, root_affine); } - let armatures = gltf - .skins() - .map(|skin| { - if let Some(root) = skin.skeleton() { - fn traverse( - ars: &mut (&mut Vec<String>, &mut Vec<Affine3A>, &mut Vec<u16>), - trans: Affine3A, - parent: Option<u16>, - node: &Node, - ) { - let trans = trans * transform_to_affine(node.transform()); - let ind = ars.0.len() as u16; - ars.0.push(node.name().unwrap_or("").to_owned()); - ars.1.push(trans); - ars.2.push(parent.unwrap_or(ind)); - for c in node.children() { - traverse(ars, trans, Some(ind), &c); - } - } - let mut name = Vec::new(); - let mut transform = Vec::new(); - let mut parent = Vec::new(); - traverse( - &mut (&mut name, &mut transform, &mut parent), - Affine3A::IDENTITY, - None, - &root, - ); - let armature = Armature { - name: Some(name), - parent: Some(parent), - transform: Some(transform), - }; - // let armature = store.set(&armature)?; - // eprintln!("{armature:?}") - Ok::<_, anyhow::Error>(Some(armature)) - } else { - Ok::<_, anyhow::Error>(None) - } - }) - .collect::<Result<Vec<_>>>()?; - - eprintln!("{armatures:?}"); - let mut prefab = nodes .par_iter() .map(|(trans, node)| { @@ -186,7 +142,6 @@ fn main() -> Result<()> { &mut prefab, &args, &texture_cache, - &armatures, )?; } let (position, _, _) = node.transform().decomposed(); @@ -227,6 +182,46 @@ fn main() -> Result<()> { }, )?; + prefab.armature = gltf + .skins() + .map(|skin| { + if let Some(root) = skin.skeleton() { + fn traverse( + ars: &mut (&mut Vec<String>, &mut Vec<Affine3A>, &mut Vec<u16>), + trans: Affine3A, + parent: Option<u16>, + node: &Node, + ) { + let trans = trans * transform_to_affine(node.transform()); + let ind = ars.0.len() as u16; + ars.0.push(node.name().unwrap_or("").to_owned()); + ars.1.push(trans); + ars.2.push(parent.unwrap_or(ind)); + for c in node.children() { + traverse(ars, trans, Some(ind), &c); + } + } + let mut name = Vec::new(); + let mut transform = Vec::new(); + let mut parent = Vec::new(); + traverse( + &mut (&mut name, &mut transform, &mut parent), + Affine3A::IDENTITY, + None, + &root, + ); + let armature = ArmaturePart { + name: Some(name), + parent: Some(parent), + transform: Some(transform), + }; + store.set(&armature) + } else { + store.set(&ArmaturePart::default()) + } + }) + .collect::<Result<Vec<_>>>()?; + if let Some(skybox) = &args.skybox { let mut buf = Vec::new(); File::open(skybox)?.read_to_end(&mut buf)?; diff --git a/world/src/mesh.rs b/world/src/mesh.rs index 8afefb4..b0b55b7 100644 --- a/world/src/mesh.rs +++ b/world/src/mesh.rs @@ -21,7 +21,7 @@ use log::{debug, info}; use std::path::Path; use weareshared::{ Affine3A, Vec3A, - resources::{Armature, MeshPart, Prefab}, + resources::{MeshPart, Prefab}, store::ResourceStore, vec2, vec3a, vec4, }; @@ -36,7 +36,6 @@ pub fn import_mesh( prefab: &mut Prefab, args: &Args, texture_cache: &TextureCache, - armatures: &[Option<Armature>], ) -> Result<()> { for p in mesh.primitives() { let name = mesh.name().or(node.name()).map(|e| e.to_owned()); @@ -336,12 +335,7 @@ pub fn import_mesh( None }; - let mut armature = None; - if let Some(skin) = node.skin() { - if let Some(a) = &armatures[skin.index()] { - armature = Some(store.set(a)?); - } - } + let armature = node.skin().map(|s| s.index() as u32); let mesh = store.set(&MeshPart { name, |