summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-02-07 17:46:11 +0100
committermetamuffin <metamuffin@disroot.org>2025-02-07 17:46:11 +0100
commitcdbb04b49e04716387eda47e72eadc6ef24c40ff (patch)
tree455d60aeeb8dfd65dc389f3956030bce35ec008d
parent111b2e89fec8d035dc5cbb54cd0a4197c18b947e (diff)
downloadweareserver-cdbb04b49e04716387eda47e72eadc6ef24c40ff.tar
weareserver-cdbb04b49e04716387eda47e72eadc6ef24c40ff.tar.bz2
weareserver-cdbb04b49e04716387eda47e72eadc6ef24c40ff.tar.zst
vrm bone names
-rw-r--r--Cargo.lock6
-rw-r--r--shared/src/packets.rs6
-rw-r--r--world/Cargo.toml2
-rw-r--r--world/src/main.rs36
-rw-r--r--world/src/vrm.rs38
5 files changed, 80 insertions, 8 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c2452cc..07493b0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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,
+}