Skip to content

Commit

Permalink
WIP Blendshapes (#45)
Browse files Browse the repository at this point in the history
* WIP Blendshapes

* Greatly overhauled how code works

* Stripped almost everything out and simplified code

---------

Co-authored-by: Ryan Butler <thebutlah@gmail.com>
  • Loading branch information
loucass003 and TheButlah authored Nov 23, 2023
1 parent 6c5ca18 commit c974c51
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
.idea
.envrc
.direnv
.vscode
15 changes: 11 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ members = [
"skills/openxr-6dof",
"skills/xr-ik-mirror",
"skills/entity-inspector",
"skills/blendshapes",
]

# These settings will apply to all members of the workspace that opt in to them
Expand Down
10 changes: 10 additions & 0 deletions skills/blendshapes/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "blendshapes"
version.workspace = true
license.workspace = true
repository.workspace = true
edition.workspace = true
rust-version.workspace = true

[dependencies]
bevy.workspace = true
9 changes: 9 additions & 0 deletions skills/blendshapes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Blendshapes and Morph Targets

Demonstrates how to use morph targets to animate the blend shapes. For example
to make a gltf avatar blink.

To run the code:
```bash
cargo run -p blendshapes
```
64 changes: 64 additions & 0 deletions skills/blendshapes/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use bevy::prelude::*;

/// The blendshape/morph target corresponding to a blink is at this index
const BLINK_MORPH_IDX: usize = 13;
const FACE_ENTITY_NAME: &str = "Face";
const ASSET_FOLDER: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../assets/");

fn main() {
// This will take like 5 seconds to load the gltf/vrm model, don't worry, just wait.
App::new()
.insert_resource(AmbientLight {
color: Color::WHITE,
brightness: 1.0 / 5.0f32,
})
.add_plugins(DefaultPlugins.set(AssetPlugin {
file_path: ASSET_FOLDER.to_string(),
..default()
}))
.add_systems(Startup, setup)
.add_systems(Update, animate_blink)
.run()
}

fn setup(mut commands: Commands, assets: Res<AssetServer>) {
commands
.spawn(SpatialBundle::default())
.with_children(|parent| {
parent.spawn(Camera3dBundle {
transform: Transform::from_xyz(0.0, 1.45, 0.5)
.looking_at(Vec3::new(0.0, 1.45, 0.0), Vec3::Y),
projection: bevy::render::camera::Projection::Perspective(
PerspectiveProjection {
fov: std::f32::consts::FRAC_PI_4,
aspect_ratio: 1.0,
near: 0.1,
far: 100.0,
},
),
..default()
});
});

commands.spawn(SceneBundle {
scene: assets.load("malek.gltf#Scene0"),
transform: Transform::from_xyz(0.0, 0.0, 0.0).with_rotation(Quat::from_euler(
EulerRot::XYZ,
0.0,
180.0_f32.to_radians(),
0.0,
)),
..default()
});
}

fn animate_blink(mut morphs: Query<(&Name, &mut MorphWeights)>, time: Res<Time>) {
let Some((_, mut weights)) = morphs
.iter_mut()
.find(|(name, _)| name.as_str() == FACE_ENTITY_NAME)
else {
return;
};
weights.weights_mut()[BLINK_MORPH_IDX] =
(f32::sin(time.elapsed_seconds() * 10.0) + 1.) / 2.;
}

0 comments on commit c974c51

Please sign in to comment.