Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions inox2d/src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::node::{
components::{DeformSource, DeformStack, Mesh, TransformStore, ZSort},
InoxNodeUuid,
};
use crate::puppet::{Puppet, World};
use crate::puppet::{InoxNodeTree, Puppet, World};

/// Parameter binding to a node. This allows to animate a node based on the value of the parameter that owns it.
pub struct Binding {
Expand Down Expand Up @@ -75,7 +75,7 @@ impl Param {
///
/// End users may repeatedly apply a same parameter for multiple times in between frames,
/// but other facilities should be present to make sure this `apply()` is only called once per parameter.
pub(crate) fn apply(&self, val: Vec2, comps: &mut World) {
pub(crate) fn apply(&self, val: Vec2, nodes: &InoxNodeTree, comps: &mut World) {
let val = val.clamp(self.min, self.max);
let val_normed = (val - self.min) / (self.max - self.min);

Expand Down Expand Up @@ -196,12 +196,16 @@ impl Param {

// deform specified by a parameter must be direct, i.e., in the form of displacements of all vertices
let direct_deform = {
let mesh = comps.get::<Mesh>(binding.node).unwrap_or_else(|| {
panic!(
"Deform param target must have an associated Mesh. (Binding Node ID: {:?})",
let Some(mesh) = comps.get::<Mesh>(binding.node) else {
let target_name = nodes.get_node(binding.node).map(|n| n.name.as_str());
tracing::error!(
"Deform param target must have an associated Mesh. (Param: {}, Binding Node: {} ({:?}))",
self.name,
target_name.unwrap_or("<NO NAME>"),
binding.node.0
)
});
);
continue;
};

let vert_len = mesh.vertices.len();
let mut direct_deform: Vec<Vec2> = Vec::with_capacity(vert_len);
Expand Down Expand Up @@ -261,12 +265,12 @@ impl ParamCtx {
}

/// Modify components as specified by all params. Must be called ONCE per frame.
pub(crate) fn apply(&self, params: &HashMap<String, Param>, comps: &mut World) {
pub(crate) fn apply(&self, params: &HashMap<String, Param>, nodes: &InoxNodeTree, comps: &mut World) {
// a correct implementation should not care about the order of `.apply()`
for (param_name, val) in self.values.iter() {
// TODO: a correct implementation should not fail on param value (0, 0)
if *val != Vec2::ZERO {
params.get(param_name).unwrap().apply(*val, comps);
params.get(param_name).unwrap().apply(*val, nodes, comps);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions inox2d/src/puppet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl Puppet {
/// Provide elapsed time for physics, if initialized, to run. Provide `0` for the first call.
pub fn end_frame(&mut self, dt: f32) {
if let Some(param_ctx) = self.param_ctx.as_mut() {
param_ctx.apply(&self.params, &mut self.node_comps);
param_ctx.apply(&self.params, &self.nodes, &mut self.node_comps);
}

if let Some(transform_ctx) = self.transform_ctx.as_mut() {
Expand Down Expand Up @@ -158,7 +158,7 @@ impl Puppet {
.set(param_name, *value)
.expect("Param name returned by .step() must exist.");
}
param_ctx.apply(&self.params, &mut self.node_comps);
param_ctx.apply(&self.params, &self.nodes, &mut self.node_comps);

transform_ctx.update(&self.nodes, &mut self.node_comps);
}
Expand Down
Loading