summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-02-19 23:22:58 +0100
committermetamuffin <metamuffin@disroot.org>2025-02-19 23:22:58 +0100
commit5a8d293e8af90d9b4191865a4087fa3792f8b769 (patch)
treed11ac8b75d4ebb4aed202a8b2961589735be032e
parentdf38d65acb939a363d44faf475632b06d56a936e (diff)
downloadweareserver-5a8d293e8af90d9b4191865a4087fa3792f8b769.tar
weareserver-5a8d293e8af90d9b4191865a4087fa3792f8b769.tar.bz2
weareserver-5a8d293e8af90d9b4191865a4087fa3792f8b769.tar.zst
import vrm first person bone
-rw-r--r--world/src/main.rs31
-rw-r--r--world/src/vrm.rs43
2 files changed, 54 insertions, 20 deletions
diff --git a/world/src/main.rs b/world/src/main.rs
index 1b863bb..c1289e2 100644
--- a/world/src/main.rs
+++ b/world/src/main.rs
@@ -56,8 +56,8 @@ use weareshared::{
helper::ReadWrite,
packets::{Data, Object, Packet, Resource},
resources::{
- AnimationChannel, AnimationPart, ArmaturePart, EnvironmentPart, Image, LightPart,
- ParticlesPart, Prefab,
+ AnimationChannel, AnimationPart, ArmaturePart, AvatarInfoPart, EnvironmentPart, Image,
+ LightPart, ParticlesPart, Prefab,
},
store::ResourceStore,
vec3a,
@@ -109,6 +109,8 @@ pub struct Args {
/// Wiggles joint index 6
#[arg(long)]
debug_armature: bool,
+ #[arg(long)]
+ no_particles: bool,
}
fn main() -> Result<()> {
@@ -278,7 +280,7 @@ fn main() -> Result<()> {
}
}
}
- if extras.get("particles") == Some(&Value::Bool(true)) {
+ if extras.get("particles") == Some(&Value::Bool(true)) && !args.no_particles {
#[derive(Deserialize)]
struct ParticlesAttr {
density: Option<f32>,
@@ -305,11 +307,11 @@ fn main() -> Result<()> {
velocity_spread: attr.velocity_spread,
})?;
- // prefab
- // .lock()
- // .unwrap()
- // .particles
- // .push((transform_to_affine(node.transform()), part));
+ prefab
+ .lock()
+ .unwrap()
+ .particles
+ .push((transform_to_affine(node.transform()), part));
}
if let Some(light) = node.light() {
@@ -402,6 +404,19 @@ fn main() -> Result<()> {
})?);
}
+ if vrm.camera_mount.is_some()
+ || vrm.camera_mount_offset.is_some()
+ || !vrm.bone_node_names.is_empty()
+ {
+ info!("avatar info enabled");
+ prefab.avatar_info = Some(store.set(&AvatarInfoPart {
+ armature: Some(0), // TODO
+ camera_mount: vrm.camera_mount.map(|e| e as u32),
+ camera_mount_offset: vrm.camera_mount_offset,
+ ..Default::default()
+ })?);
+ }
+
prefab.armature = if armature.parent.as_ref().is_some_and(|a| !a.is_empty()) {
vec![store.set(&armature)?]
} else {
diff --git a/world/src/vrm.rs b/world/src/vrm.rs
index 2888ad0..a97323f 100644
--- a/world/src/vrm.rs
+++ b/world/src/vrm.rs
@@ -18,53 +18,60 @@ use anyhow::Result;
use gltf::Gltf;
use serde::Deserialize;
use std::collections::{BTreeMap, BTreeSet};
+use weareshared::Vec3A;
+#[derive(Default)]
pub struct VrmInfo {
pub bone_node_names: Vec<(usize, String)>,
pub hide_first_person: BTreeSet<usize>,
+ pub camera_mount: Option<usize>,
+ pub camera_mount_offset: Option<Vec3A>,
}
pub fn extract_vrm_data(gltf: &Gltf) -> Result<VrmInfo> {
- let mut bone_node_names = Vec::new();
- let mut hide_first_person = BTreeSet::new();
+ let mut o = VrmInfo::default();
if let Some(vrm) = gltf.extension_value("VRM") {
// 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))
+ o.bone_node_names.push((bone.node, bone.bone))
+ }
+ if let Some(fp) = vrm.first_person {
+ o.camera_mount = fp.first_person_bone;
+ o.camera_mount_offset = fp.first_person_bone_offset.map(convert_vrm_vec);
}
}
if let Some(vrm) = gltf.extension_value("VRMC_vrm") {
// 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))
+ o.bone_node_names.push((bone.node, name))
}
if let Some(fp) = vrm.first_person {
+ o.camera_mount = fp.first_person_bone;
+ o.camera_mount_offset = fp.first_person_bone_offset.map(convert_vrm_vec);
for ann in fp.mesh_annotations {
match ann.first_person_flag {
FirstPersonFlag::ThirdPersonOnly => {
- hide_first_person.insert(ann.node);
+ o.hide_first_person.insert(ann.node);
}
_ => (),
}
}
}
}
- Ok(VrmInfo {
- bone_node_names,
- hide_first_person,
- })
+ Ok(o)
}
#[derive(Debug, Deserialize)]
-pub struct Vrm {
- pub humanoid: VrmHumanoid,
+struct Vrm {
+ humanoid: VrmHumanoid,
+ first_person: Option<VrmcFirstPerson>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
-pub struct VrmHumanoid {
+struct VrmHumanoid {
human_bones: Vec<VrmHumanBone>,
}
@@ -85,6 +92,8 @@ struct Vrmc {
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
struct VrmcFirstPerson {
+ first_person_bone: Option<usize>,
+ first_person_bone_offset: Option<VrmVec3>,
mesh_annotations: Vec<VrmcFirstPersonMeshAnnotation>,
}
@@ -117,3 +126,13 @@ struct VrmcHumanoid {
struct VrmcHumanBone {
node: usize,
}
+
+#[derive(Debug, Deserialize)]
+struct VrmVec3 {
+ x: f32,
+ y: f32,
+ z: f32,
+}
+fn convert_vrm_vec(VrmVec3 { x, y, z }: VrmVec3) -> Vec3A {
+ Vec3A::new(x, y, z)
+}