summaryrefslogtreecommitdiff
path: root/world/src
diff options
context:
space:
mode:
Diffstat (limited to 'world/src')
-rw-r--r--world/src/animation.rs66
-rw-r--r--world/src/main.rs39
2 files changed, 65 insertions, 40 deletions
diff --git a/world/src/animation.rs b/world/src/animation.rs
index 3473371..ee6028e 100644
--- a/world/src/animation.rs
+++ b/world/src/animation.rs
@@ -15,7 +15,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use anyhow::Result;
-use glam::Quat;
+use glam::{Quat, vec3a};
use gltf::{
Animation,
animation::{Property, util::ReadOutputs},
@@ -33,6 +33,7 @@ use weareshared::{
pub fn import_animation<'a>(
a: Animation<'a>,
store: &ResourceStore,
+ transform: Affine3A,
joint_index_to_ibm: &BTreeMap<usize, Affine3A>,
joint_index_to_arm_index: &BTreeMap<usize, usize>,
node_to_meshes: &BTreeMap<usize, Vec<usize>>,
@@ -44,36 +45,39 @@ pub fn import_animation<'a>(
let node = c.target().node().index();
let reader = c.reader(|i| Some(&buffers[i.index()].0));
let inputs: Vec<f32> = reader.read_inputs().unwrap().collect::<Vec<f32>>();
- let outputs: Vec<f32> = if let Some(ibm) = joint_index_to_ibm.get(&node) {
- debug!("pre-applying inverse bind matricies");
- let ibm = ibm.inverse();
- // eprintln!("{:#?}", ibm);
- let (_, ibm_rot, _) = ibm.to_scale_rotation_translation();
- match reader.read_outputs().unwrap() {
- // ReadOutputs::Translations(iter) => iter
- // .flat_map(|[x, y, z]| (ibm.matrix3 * vec3a(x, y, z)).to_array())
- // .collect(),
- ReadOutputs::Rotations(iter) => iter
- .into_f32()
- .map(Quat::from_array)
- .map(|q| ibm_rot.mul_quat(q))
- .map(|q| q.to_array())
- .flatten()
- .collect(),
- // ReadOutputs::Scales(iter) => iter
- // .flat_map(|[x, y, z]| (ibm.matrix3 * vec3a(x, y, z)).to_array())
- // .collect(),
- ReadOutputs::MorphTargetWeights(iter) => iter.into_f32().collect(),
- _ => continue,
- }
- } else {
- match reader.read_outputs().unwrap() {
- ReadOutputs::Translations(iter) => iter.flatten().collect(),
- ReadOutputs::Rotations(iter) => iter.into_f32().flatten().collect(),
- ReadOutputs::Scales(iter) => iter.flatten().collect(),
- ReadOutputs::MorphTargetWeights(iter) => iter.into_f32().collect(),
- }
- };
+ let outputs: Vec<f32> =
+ if joint_index_to_ibm.contains_key(&node) || transform != Affine3A::IDENTITY {
+ let t = transform
+ * joint_index_to_ibm
+ .get(&node)
+ .copied()
+ .unwrap_or_default()
+ .inverse();
+ let (_, rot, _) = t.to_scale_rotation_translation();
+ match reader.read_outputs().unwrap() {
+ ReadOutputs::Translations(iter) => iter
+ .flat_map(|[x, y, z]| (t.matrix3 * vec3a(x, y, z)).to_array())
+ .collect(),
+ ReadOutputs::Rotations(iter) => iter
+ .into_f32()
+ .map(Quat::from_array)
+ .map(|q| rot.mul_quat(q))
+ .map(|q| q.to_array())
+ .flatten()
+ .collect(),
+ ReadOutputs::Scales(iter) => iter
+ .flat_map(|[x, y, z]| (t.matrix3 * vec3a(x, y, z)).to_array())
+ .collect(),
+ ReadOutputs::MorphTargetWeights(iter) => iter.into_f32().collect(),
+ }
+ } else {
+ match reader.read_outputs().unwrap() {
+ ReadOutputs::Translations(iter) => iter.flatten().collect(),
+ ReadOutputs::Rotations(iter) => iter.into_f32().flatten().collect(),
+ ReadOutputs::Scales(iter) => iter.flatten().collect(),
+ ReadOutputs::MorphTargetWeights(iter) => iter.into_f32().collect(),
+ }
+ };
for x in &inputs {
max_time = max_time.max(*x)
}
diff --git a/world/src/main.rs b/world/src/main.rs
index 14a4477..695b4aa 100644
--- a/world/src/main.rs
+++ b/world/src/main.rs
@@ -24,6 +24,7 @@ pub mod vrm;
use animation::import_animation;
use anyhow::{Context, Result, anyhow};
use clap::Parser;
+use glam::Vec3;
use gltf::{Gltf, Node, image::Source, import_buffers, scene::Transform};
use humansize::BINARY;
use image::{ImageReader, codecs::webp::WebPEncoder};
@@ -99,6 +100,12 @@ pub struct Args {
animation: Option<PathBuf>,
#[arg(long)]
animation_bone_map: Option<PathBuf>,
+ #[arg(long)]
+ animation_rotation_y: Option<f32>,
+ #[arg(long)]
+ animation_scale: Option<f32>,
+ #[arg(long)]
+ animation_apply_ibm: bool,
/// Spins the object
#[arg(long)]
@@ -392,7 +399,7 @@ fn main() -> Result<()> {
let anim_name_map = if let Some(ref map_path) = args.animation_bone_map {
let mut map = BTreeMap::new();
for l in read_to_string(map_path)?.lines() {
- if !l.trim().is_empty() {
+ if !l.trim().is_empty() && !l.starts_with(";") {
let (a, b) = l.split_once("=").unwrap();
map.insert(a.to_string(), b.to_string());
}
@@ -423,21 +430,34 @@ fn main() -> Result<()> {
}
}
}
- for s in gltf.skins() {
- let reader = s.reader(|buf| Some(&buffers[buf.index()]));
- if let Some(ibms) = reader.read_inverse_bind_matrices() {
- for (jn, ibm) in s.joints().zip(ibms) {
- joint_index_to_ibm.insert(
- jn.index(),
- transform_to_affine(Transform::Matrix { matrix: ibm }),
- );
+ if args.animation_apply_ibm {
+ for s in gltf.skins() {
+ let reader = s.reader(|buf| Some(&buffers[buf.index()]));
+ if let Some(ibms) = reader.read_inverse_bind_matrices() {
+ for (jn, ibm) in s.joints().zip(ibms) {
+ joint_index_to_ibm.insert(
+ jn.index(),
+ transform_to_affine(Transform::Matrix { matrix: ibm }),
+ );
+ }
}
}
+ debug!("{} joint IBMs found", joint_index_to_ibm.len());
}
+ let transform = args
+ .animation_rotation_y
+ .map(Affine3A::from_rotation_y)
+ .unwrap_or_default()
+ * args
+ .animation_scale
+ .map(Vec3::splat)
+ .map(Affine3A::from_scale)
+ .unwrap_or_default();
for a in gltf.animations() {
prefab.animation.push(import_animation(
a,
&store,
+ transform,
&joint_index_to_ibm,
&anim_joint_index_to_arm_index,
&BTreeMap::new(),
@@ -451,6 +471,7 @@ fn main() -> Result<()> {
prefab.animation.push(import_animation(
a,
&store,
+ Affine3A::IDENTITY,
&BTreeMap::new(),
&joint_index_to_arm_index,
&node_to_meshes,