diff options
author | metamuffin <metamuffin@disroot.org> | 2025-02-07 17:46:11 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-02-07 17:46:11 +0100 |
commit | cdbb04b49e04716387eda47e72eadc6ef24c40ff (patch) | |
tree | 455d60aeeb8dfd65dc389f3956030bce35ec008d | |
parent | 111b2e89fec8d035dc5cbb54cd0a4197c18b947e (diff) | |
download | weareserver-cdbb04b49e04716387eda47e72eadc6ef24c40ff.tar weareserver-cdbb04b49e04716387eda47e72eadc6ef24c40ff.tar.bz2 weareserver-cdbb04b49e04716387eda47e72eadc6ef24c40ff.tar.zst |
vrm bone names
-rw-r--r-- | Cargo.lock | 6 | ||||
-rw-r--r-- | shared/src/packets.rs | 6 | ||||
-rw-r--r-- | world/Cargo.toml | 2 | ||||
-rw-r--r-- | world/src/main.rs | 36 | ||||
-rw-r--r-- | world/src/vrm.rs | 38 |
5 files changed, 80 insertions, 8 deletions
@@ -2785,9 +2785,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.134" +version = "1.0.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" dependencies = [ "itoa", "memchr", @@ -3476,6 +3476,8 @@ dependencies = [ "log", "rand 0.9.0-beta.1", "rayon", + "serde", + "serde_json", "weareshared", ] diff --git a/shared/src/packets.rs b/shared/src/packets.rs index 021fcd0..3cc9ea9 100644 --- a/shared/src/packets.rs +++ b/shared/src/packets.rs @@ -114,7 +114,7 @@ impl Packet { Packet::Pose(object, vec) => { w.write_all(&[0x06])?; w.write_all(&object.0.to_le_bytes())?; - w.write_all(&(vec.len() as u16).to_le_bytes())?; + w.write_all(&(vec.len() as u32).to_le_bytes())?; for (i, a) in vec { i.write(w)?; a.write(w)?; @@ -191,9 +191,9 @@ fn read_u128(r: &mut dyn Read) -> Result<u128> { } fn read_params(r: &mut dyn Read) -> Result<Vec<(u16, Affine3A)>> { - let mut size = [0; 2]; + let mut size = [0; 4]; r.read_exact(&mut size)?; - let size = u16::from_le_bytes(size); + let size = u32::from_le_bytes(size); let mut v = Vec::with_capacity(size as usize); for _ in 0..size { v.push((u16::read(r)?, Affine3A::read(r)?)); diff --git a/world/Cargo.toml b/world/Cargo.toml index db199bc..cb47c70 100644 --- a/world/Cargo.toml +++ b/world/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" anyhow = "1.0.95" clap = { version = "4.5.23", features = ["derive"] } env_logger = "0.11.6" +serde = { version = "1.0.217", features = ["derive"] } gltf = { version = "1.4.1", features = [ "extras", "names", @@ -23,3 +24,4 @@ rand = "0.9.0-beta.1" image = "0.25.5" rayon = "1.10.0" humansize = "2.1.3" +serde_json = "1.0.138" diff --git a/world/src/main.rs b/world/src/main.rs index 081aa09..c3fb959 100644 --- a/world/src/main.rs +++ b/world/src/main.rs @@ -18,6 +18,7 @@ #![allow(clippy::too_many_arguments, clippy::type_complexity)] pub mod mesh; pub mod physics; +pub mod vrm; use anyhow::{Result, anyhow}; use clap::Parser; @@ -41,6 +42,7 @@ use std::{ thread::{self, sleep}, time::Duration, }; +use vrm::{Vrm, Vrmc}; use weareshared::{ Affine3A, Vec3A, helper::ReadWrite, @@ -110,6 +112,8 @@ fn main() -> Result<()> { root_affine.matrix3 *= args.scale.unwrap_or(1.); root_affine.translation *= args.scale.unwrap_or(1.); + let mut debug_bone = (0, Affine3A::IDENTITY); + for scenepath in &args.scene { let path_base = scenepath.parent().unwrap(); let mut gltf = Gltf::from_reader_without_validation(File::open(scenepath)?)?; @@ -169,6 +173,27 @@ fn main() -> Result<()> { }) .collect::<Vec<_>>(); + if let Some(vrm) = gltf.extension_value("VRM") { + let vrm: Vrm = serde_json::from_value(vrm.clone())?; + for bone in vrm.humanoid.human_bones { + let ind = joint_index_to_arm_index[&bone.node]; + name[ind] = bone.bone; + } + } + if let Some(vrm) = gltf.extension_value("VRMC_vrm") { + let vrm: Vrmc = serde_json::from_value(vrm.clone())?; + for (bname, bone) in vrm.humanoid.human_bones { + let ind = joint_index_to_arm_index[&bone.node]; + name[ind] = bname; + } + } + + for (i, (name, tr)) in name.iter().zip(transform.iter()).enumerate() { + if name == "head" { + debug_bone = (i, *tr); + } + } + if !parent.is_empty() { Some(store.set(&ArmaturePart { name: Some(name), @@ -317,10 +342,15 @@ fn main() -> Result<()> { thread::spawn(move || { let mut x = 0f32; loop { - let a = Affine3A::from_rotation_y(x.sin()); - Packet::Pose(ob, vec![(6, a)]).write(&mut sock2).unwrap(); + let a = Affine3A::IDENTITY + * Affine3A::from_rotation_x(x.cos() * 0.3) + * Affine3A::from_rotation_y(x.sin() * 0.5) + * debug_bone.1; + Packet::Pose(ob, vec![(debug_bone.0 as u16, a)]) + .write(&mut sock2) + .unwrap(); sock2.flush().unwrap(); - x += 0.1; + x += 0.2; sleep(Duration::from_millis(50)); } }); diff --git a/world/src/vrm.rs b/world/src/vrm.rs new file mode 100644 index 0000000..a9ea6f4 --- /dev/null +++ b/world/src/vrm.rs @@ -0,0 +1,38 @@ +use std::collections::BTreeMap; + +use serde::Deserialize; + +#[derive(Debug, Deserialize)] +pub struct Vrm { + pub humanoid: VrmHumanoid, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct VrmHumanoid { + pub human_bones: Vec<VrmHumanBone>, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct VrmHumanBone { + pub bone: String, + pub node: usize, +} + +#[derive(Debug, Deserialize)] +pub struct Vrmc { + pub humanoid: VrmcHumanoid, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct VrmcHumanoid { + pub human_bones: BTreeMap<String, VrmcHumanBone>, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct VrmcHumanBone { + pub node: usize, +} |