#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use super::texture::TextureChannel;
use crate::fieldgraph::FieldId;
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct ConstantParams {
pub value: f32,
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct TextureParams {
pub texture_id: String,
pub channel: TextureChannel,
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct ClampParams {
pub min: f32,
pub max: f32,
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct SmoothStepParams {
pub edge0: f32,
pub edge1: f32,
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct ScaleParams {
pub factor: f32,
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct PowParams {
pub exp: f32,
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub struct EdtNormalizeParams {
pub threshold: f32,
pub d_max: f32,
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
pub enum NodeSpec {
Constant {
params: ConstantParams,
},
Texture {
params: TextureParams,
},
Add {
inputs: Vec<FieldId>,
},
Sub {
inputs: Vec<FieldId>,
},
Mul {
inputs: Vec<FieldId>,
},
Min {
inputs: Vec<FieldId>,
},
Max {
inputs: Vec<FieldId>,
},
Invert {
inputs: Vec<FieldId>,
},
Scale {
inputs: Vec<FieldId>,
params: ScaleParams,
},
Clamp {
inputs: Vec<FieldId>,
params: ClampParams,
},
SmoothStep {
inputs: Vec<FieldId>,
params: SmoothStepParams,
},
Pow {
inputs: Vec<FieldId>,
params: PowParams,
},
EdtNormalize {
inputs: Vec<FieldId>,
params: EdtNormalizeParams,
},
}
impl NodeSpec {
pub fn inputs(&self) -> &[FieldId] {
match self {
NodeSpec::Add { inputs }
| NodeSpec::Sub { inputs }
| NodeSpec::Mul { inputs }
| NodeSpec::Min { inputs }
| NodeSpec::Max { inputs }
| NodeSpec::Invert { inputs }
| NodeSpec::Scale { inputs, .. }
| NodeSpec::Clamp { inputs, .. }
| NodeSpec::SmoothStep { inputs, .. }
| NodeSpec::Pow { inputs, .. }
| NodeSpec::EdtNormalize { inputs, .. } => inputs,
NodeSpec::Constant { .. } | NodeSpec::Texture { .. } => &[],
}
}
pub fn constant(value: f32) -> Self {
NodeSpec::Constant {
params: ConstantParams { value },
}
}
pub fn texture(id: impl Into<String>, channel: TextureChannel) -> Self {
NodeSpec::Texture {
params: TextureParams {
texture_id: id.into(),
channel,
},
}
}
pub fn add(inputs: Vec<FieldId>) -> Self {
NodeSpec::Add { inputs }
}
pub fn sub(inputs: Vec<FieldId>) -> Self {
NodeSpec::Sub { inputs }
}
pub fn mul(inputs: Vec<FieldId>) -> Self {
NodeSpec::Mul { inputs }
}
pub fn min(inputs: Vec<FieldId>) -> Self {
NodeSpec::Min { inputs }
}
pub fn max(inputs: Vec<FieldId>) -> Self {
NodeSpec::Max { inputs }
}
pub fn invert(input: FieldId) -> Self {
NodeSpec::Invert {
inputs: vec![input],
}
}
pub fn scale(input: FieldId, factor: f32) -> Self {
NodeSpec::Scale {
inputs: vec![input],
params: ScaleParams { factor },
}
}
pub fn clamp(input: FieldId, min: f32, max: f32) -> Self {
NodeSpec::Clamp {
inputs: vec![input],
params: ClampParams { min, max },
}
}
pub fn smoothstep(input: FieldId, edge0: f32, edge1: f32) -> Self {
NodeSpec::SmoothStep {
inputs: vec![input],
params: SmoothStepParams { edge0, edge1 },
}
}
pub fn pow(input: FieldId, exp: f32) -> Self {
NodeSpec::Pow {
inputs: vec![input],
params: PowParams { exp },
}
}
pub fn edt_normalize(input: FieldId, threshold: f32, d_max: f32) -> Self {
NodeSpec::EdtNormalize {
inputs: vec![input],
params: EdtNormalizeParams { threshold, d_max },
}
}
}