summaryrefslogtreecommitdiff
path: root/world
diff options
context:
space:
mode:
Diffstat (limited to 'world')
-rw-r--r--world/src/main.rs35
-rw-r--r--world/src/mesh.rs14
-rw-r--r--world/src/vrm.rs10
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,