diff options
author | metamuffin <metamuffin@disroot.org> | 2025-02-11 23:43:58 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-02-11 23:43:58 +0100 |
commit | ae9e813eaf5b04c8dddc9da1a1f5d50da1f5bddb (patch) | |
tree | b49dc88fa527bf12c6efe9a3aa3eb7d8923b43ee | |
parent | 174f668c437a83bdb7787a828b0c4fb7f2521aa1 (diff) | |
download | weareserver-ae9e813eaf5b04c8dddc9da1a1f5d50da1f5bddb.tar weareserver-ae9e813eaf5b04c8dddc9da1a1f5d50da1f5bddb.tar.bz2 weareserver-ae9e813eaf5b04c8dddc9da1a1f5d50da1f5bddb.tar.zst |
set first person hint based on head bones in joint_index
-rw-r--r-- | world/src/main.rs | 35 | ||||
-rw-r--r-- | world/src/mesh.rs | 14 | ||||
-rw-r--r-- | world/src/vrm.rs | 10 |
3 files changed, 42 insertions, 17 deletions
diff --git a/world/src/main.rs b/world/src/main.rs index e3c365a..00a5913 100644 --- a/world/src/main.rs +++ b/world/src/main.rs @@ -189,17 +189,29 @@ fn main() -> Result<()> { } } - if !parent.is_empty() { - Some(store.set(&ArmaturePart { - name: Some(name), - parent: Some(parent), - transform: Some(transform), - })?) - } else { - None + ArmaturePart { + name: Some(name), + parent: Some(parent), + transform: Some(transform), } }; + let head_bones = { + let pa = armature.parent.clone().unwrap_or_default(); + let na = armature.name.clone().unwrap_or_default(); + (0..pa.len()) + .filter(|&(mut i)| { + let mut f = false; + while pa[i] as usize != i { + f |= na[i] == "head"; + i = pa[i] as usize; + } + f + }) + .map(|e| e as u32) + .collect::<Vec<_>>() + }; + let mut prefab = nodes .par_iter() .map(|(trans, node)| { @@ -219,6 +231,7 @@ fn main() -> Result<()> { &texture_cache, &skin_index_to_arm_index, &vrm, + &head_bones, )?; } } @@ -260,7 +273,11 @@ fn main() -> Result<()> { }, )?; - prefab.armature = armature.into_iter().collect(); + prefab.armature = if armature.parent.as_ref().is_some_and(|a| !a.is_empty()) { + vec![store.set(&armature)?] + } else { + vec![] + }; if let Some(skybox) = &args.skybox { let mut buf = Vec::new(); diff --git a/world/src/mesh.rs b/world/src/mesh.rs index 78ec919..4067fb8 100644 --- a/world/src/mesh.rs +++ b/world/src/mesh.rs @@ -38,6 +38,7 @@ pub fn import_mesh( texture_cache: &TextureCache, joint_index_map: &BTreeMap<(usize, u16), u32>, vrm: &VrmInfo, + head_bones: &[u32], ) -> Result<()> { for p in mesh.primitives() { let name = mesh.name().or(node.name()).map(|e| e.to_owned()); @@ -80,6 +81,7 @@ pub fn import_mesh( }) .transpose()?; + let mut many_head_bones = false; let va_joint_index = reader .read_joints(0) .map(|iter| { @@ -88,7 +90,17 @@ pub fn import_mesh( .into_u16() .map(|x| x.map(|x| joint_index_map[&(si, x)])) .collect::<Vec<_>>(); + + let head_bone_count = a + .iter() + .flatten() + .filter(|b| head_bones.contains(*b)) + .count(); + many_head_bones |= head_bone_count > a.len() / 2; debug!("{} vertex joint indecies", a.len()); + if many_head_bones { + debug!("many joints are head bones"); + } if a.len() != num_vertex { warn!("joint index count does not vertex count") } @@ -341,7 +353,7 @@ pub fn import_mesh( let g_double_sided = bool_to_opt(p.material().double_sided(), "double sided"); let hint_hide_first_person = bool_to_opt( - vrm.hide_first_person.contains(&node.index()), + many_head_bones | vrm.hide_first_person.contains(&node.index()), "hide first person hint", ); diff --git a/world/src/vrm.rs b/world/src/vrm.rs index 1b89642..2888ad0 100644 --- a/world/src/vrm.rs +++ b/world/src/vrm.rs @@ -17,10 +17,7 @@ use anyhow::Result; use gltf::Gltf; use serde::Deserialize; -use std::{ - collections::{BTreeMap, BTreeSet}, - fs::File, -}; +use std::collections::{BTreeMap, BTreeSet}; pub struct VrmInfo { pub bone_node_names: Vec<(usize, String)>, @@ -31,14 +28,14 @@ pub fn extract_vrm_data(gltf: &Gltf) -> Result<VrmInfo> { let mut bone_node_names = Vec::new(); let mut hide_first_person = BTreeSet::new(); if let Some(vrm) = gltf.extension_value("VRM") { - serde_json::to_writer(File::create("/tmp/vrm").unwrap(), vrm).unwrap(); + // serde_json::to_writer(std::fs::File::create("/tmp/vrm").unwrap(), vrm).unwrap(); let vrm: Vrm = serde_json::from_value(vrm.clone())?; for bone in vrm.humanoid.human_bones { bone_node_names.push((bone.node, bone.bone)) } } if let Some(vrm) = gltf.extension_value("VRMC_vrm") { - serde_json::to_writer(File::create("/tmp/vrmc").unwrap(), vrm).unwrap(); + // serde_json::to_writer(std::fs::File::create("/tmp/vrmc").unwrap(), vrm).unwrap(); let vrm: Vrmc = serde_json::from_value(vrm.clone())?; for (name, bone) in vrm.humanoid.human_bones { bone_node_names.push((bone.node, name)) @@ -54,7 +51,6 @@ pub fn extract_vrm_data(gltf: &Gltf) -> Result<VrmInfo> { } } } - eprintln!("hide {hide_first_person:?}"); Ok(VrmInfo { bone_node_names, hide_first_person, |