summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-02-03 21:46:29 +0100
committermetamuffin <metamuffin@disroot.org>2025-02-03 21:46:29 +0100
commitae14c194a25e258659104e89553ad48a8ae9ca3b (patch)
tree793b73af2c045d7acf218912afbc182a6720436f
parent163e10c9f618f0e4cd7b4456476ad1c2322db5d7 (diff)
downloadweareserver-ae14c194a25e258659104e89553ad48a8ae9ca3b.tar
weareserver-ae14c194a25e258659104e89553ad48a8ae9ca3b.tar.bz2
weareserver-ae14c194a25e258659104e89553ad48a8ae9ca3b.tar.zst
armatures in prefab
-rw-r--r--client/src/armature.rs6
-rw-r--r--doc/resources.md5
-rw-r--r--shared/src/resources.rs11
-rw-r--r--world/src/main.rs87
-rw-r--r--world/src/mesh.rs10
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,