Skip to main content

nightshade_api/
morph.rs

1//! Morph target (blend shape) weights for imported models. A glTF model with
2//! blend shapes gets a `MorphWeights` component on import, and these drive it at
3//! runtime: facial expressions, muscle flex, anything authored as a shape key.
4
5use nightshade::prelude::*;
6
7/// Sets one morph target's weight on an entity by index. A weight of 0.0 is the
8/// base mesh, 1.0 is the full target. Does nothing if the entity has no morph
9/// targets or the index is out of range.
10pub fn set_morph_weight(world: &mut World, entity: Entity, index: u32, weight: f32) {
11    if let Some(weights) = world.get_mut::<nightshade::ecs::morph::components::MorphWeights>(entity)
12    {
13        weights.set_weight(index as usize, weight);
14    }
15}
16
17/// Reads one morph target's weight by index, or 0.0 if absent.
18pub fn morph_weight(world: &World, entity: Entity, index: u32) -> f32 {
19    world
20        .get::<nightshade::ecs::morph::components::MorphWeights>(entity)
21        .map(|weights| weights.get_weight(index as usize))
22        .unwrap_or(0.0)
23}
24
25/// The number of morph targets the entity has.
26pub fn morph_target_count(world: &World, entity: Entity) -> usize {
27    world
28        .get::<nightshade::ecs::morph::components::MorphWeights>(entity)
29        .map(|weights| weights.weight_count())
30        .unwrap_or(0)
31}
32
33/// Sets every morph weight at once, in target order.
34pub fn set_morph_weights(world: &mut World, entity: Entity, weights: &[f32]) {
35    if let Some(component) =
36        world.get_mut::<nightshade::ecs::morph::components::MorphWeights>(entity)
37    {
38        for (index, value) in weights.iter().enumerate() {
39            component.set_weight(index, *value);
40        }
41    }
42}