From cf5e85c57ac8f69ffdf599e0c14aa6a8ec304184 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Sat, 22 Feb 2025 20:46:47 +0100 Subject: inverse bind mats --- doc/resources.md | 11 ++++++----- shared/src/resources.rs | 1 + world/src/main.rs | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/doc/resources.md b/doc/resources.md index 761a6fa..7d06e71 100644 --- a/doc/resources.md +++ b/doc/resources.md @@ -125,11 +125,12 @@ Armature is used for humanoid avatar rigging and generally follows VRM specification. Joints are arranged in a hierarchy where transforms are inherited. Attribute values are zipped similar to vertex attributes. -| Key | Value Type | | -| ----------- | ----------- | -------------------------------------- | -| `parent` | `[u16]` | Parent indecies, Root points to itself | -| `transform` | `[Affine3]` | | -| `name` | `[String]` | Each string prefixed with u16 length | +| Key | Value Type | | +| ---------------- | ----------- | -------------------------------------- | +| `parent` | `[u16]` | Parent indecies, Root points to itself | +| `transform` | `[Affine3]` | | +| `rest_transform` | `[Affine3]` | | +| `name` | `[String]` | Each string prefixed with u16 length | - **Names**: Indirectly controlled joints have an empty name. All other bones are named like in [VRMC_vrm]. diff --git a/shared/src/resources.rs b/shared/src/resources.rs index 4460feb..f502485 100644 --- a/shared/src/resources.rs +++ b/shared/src/resources.rs @@ -179,6 +179,7 @@ resource_dicts!( pub struct ArmaturePart { parent: Vec, transform: Vec, + rest_transform: Vec, name: Vec, } diff --git a/world/src/main.rs b/world/src/main.rs index a56ea74..16ed941 100644 --- a/world/src/main.rs +++ b/world/src/main.rs @@ -170,9 +170,18 @@ fn main() -> Result<()> { let mut name = Vec::new(); let mut parent_pre_map = Vec::new(); let mut transform = Vec::new(); + let mut rest = Vec::new(); for skin in gltf.skins() { + let mut inverse_bind_mat = skin + .reader(|buf| Some(&buffers[buf.index()])) + .read_inverse_bind_matrices(); for (j_ind, j) in skin.joints().enumerate() { + let ibm = if let Some(x) = &mut inverse_bind_mat { + Some(x.next().unwrap()) + } else { + None + }; let a_ind = match joint_index_to_arm_index.get(&j.index()) { Some(i) => *i, None => { @@ -185,6 +194,10 @@ fn main() -> Result<()> { .find(|n| n.children().any(|c| c.index() == j.index())) .map(|n| n.index()), ); + rest.push( + ibm.map(|a| transform_to_affine(Transform::Matrix { matrix: a })) + .unwrap_or(Affine3A::IDENTITY), + ); joint_index_to_arm_index.insert(j.index(), a_ind); a_ind @@ -218,6 +231,7 @@ fn main() -> Result<()> { name: Some(name), parent: Some(parent), transform: Some(transform), + rest_transform: Some(rest), } }; -- cgit v1.2.3-70-g09d2