diff options
| author | s-ol <s+removethis@s-ol.nu> | 2025-12-27 11:44:32 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-12-27 11:44:32 +0000 |
| commit | 568f6818a0b5453dea25faff4ffa46c0e8c66530 (patch) | |
| tree | 8ef95bcaf2b5ad57cedfd7d52c98794c2e73b09a /src | |
| parent | NodeIndex type (diff) | |
| download | nodetoy-568f6818a0b5453dea25faff4ffa46c0e8c66530.tar.gz nodetoy-568f6818a0b5453dea25faff4ffa46c0e8c66530.zip | |
expand and organize builtin functions
Diffstat (limited to 'src')
| -rw-r--r-- | src/library.rs | 328 |
1 files changed, 319 insertions, 9 deletions
diff --git a/src/library.rs b/src/library.rs index 3402382..18c0ef9 100644 --- a/src/library.rs +++ b/src/library.rs @@ -45,17 +45,16 @@ pub trait NodeIndex: Sized + fmt::Display { fn all() -> impl Iterator<Item = Self>; fn pick_node(ui: &mut egui::Ui) -> Option<Self> { + let mut res: Option<Self> = None; ui.menu_button(Self::TITLE, |ui| { for node in Self::all() { if ui.button(format!("{node}")).clicked() { - return Some(node); + res = Some(node); } } + }); - None - }) - .inner - .unwrap_or(None) + res } } @@ -80,9 +79,11 @@ trait FixedNode: fmt::Debug { writeln!(f, "{typ} {name};")?; } - let func = format!("{self:?}").to_lowercase(); + let func = format!("{self:?}"); + let first = func[..1].to_lowercase(); + let rest = func[1..].to_string(); let params = inputs.iter().chain(outputs.iter().skip(1)).join(", "); - writeln!(f, "{out_typ} {out_name} = {func}({params});") + writeln!(f, "{out_typ} {out_name} = {first}{rest}({params});") } } @@ -222,6 +223,31 @@ impl FixedNode for BinArithmetic { /// 1-1 thru operations #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] pub enum Thru1 { + // trig + Radians, + Degrees, + Sin, + Cos, + Tan, + Asin, + Acos, + Atan, + Sinh, + Cosh, + Tanh, + Asinh, + Acosh, + Atanh, + + // exponential + Exp, + Log, + Exp2, + Log2, + Sqrt, + Inverseqrt, + + // common Abs, Sign, Floor, @@ -230,6 +256,14 @@ pub enum Thru1 { RoundEven, Ceil, Fract, + + // geometric + Normalize, + + // derivative + DFdx, + DFdy, + Fwidth, } impl Thru1 { pub fn all() -> impl Iterator<Item = Self> { @@ -242,6 +276,30 @@ impl Thru1 { Self::RoundEven, Self::Ceil, Self::Fract, + Self::DFdx, + Self::DFdy, + Self::Fwidth, + Self::Sqrt, + Self::Inverseqrt, + Self::Exp, + Self::Log, + Self::Exp2, + Self::Log2, + Self::Radians, + Self::Degrees, + Self::Sin, + Self::Cos, + Self::Tan, + Self::Asin, + Self::Acos, + Self::Atan, + Self::Sinh, + Self::Cosh, + Self::Tanh, + Self::Asinh, + Self::Acosh, + Self::Atanh, + Self::Normalize, ] .into_iter() } @@ -252,7 +310,28 @@ impl FixedNode for Thru1 { fn all_signatures(&self) -> Box<dyn Iterator<Item = TypeSignature>> { Box::new( match self { - Thru1::Abs | Thru1::Sign => vec![GEN_F_TYPES, GEN_I_TYPES, GEN_D_TYPES], + Self::Abs | Self::Sign => vec![GEN_F_TYPES, GEN_I_TYPES, GEN_D_TYPES], + Self::DFdx + | Self::DFdy + | Self::Fwidth + | Self::Exp + | Self::Log + | Self::Exp2 + | Self::Log2 + | Self::Radians + | Self::Degrees + | Self::Sin + | Self::Cos + | Self::Tan + | Self::Asin + | Self::Acos + | Self::Atan + | Self::Sinh + | Self::Cosh + | Self::Tanh + | Self::Asinh + | Self::Acosh + | Self::Atanh => vec![GEN_F_TYPES], _ => vec![GEN_F_TYPES, GEN_D_TYPES], } .into_iter() @@ -264,6 +343,26 @@ impl FixedNode for Thru1 { /// Modulo #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Pow; +impl Pow { + pub fn all() -> impl Iterator<Item = Self> { + std::iter::once(Pow) + } +} +impl FixedNode for Pow { + const NI: usize = 2; + const NO: usize = 1; + fn all_signatures(&self) -> Box<dyn Iterator<Item = TypeSignature>> { + Box::new( + GEN_F_TYPES + .into_iter() + .map(|t| TypeSignature::new([t, t], [t])), + ) + } +} + +/// Modulo +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct Mod; impl Mod { pub fn all() -> impl Iterator<Item = Self> { @@ -369,7 +468,7 @@ impl FixedNode for Clamp { pub struct Mix; impl Mix { pub fn all() -> impl Iterator<Item = Self> { - std::iter::once(Mix) + std::iter::once(Self) } } impl FixedNode for Mix { @@ -398,6 +497,121 @@ impl FixedNode for Mix { } } +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Step; +impl Step { + pub fn all() -> impl Iterator<Item = Self> { + std::iter::once(Self) + } +} +impl FixedNode for Step { + const NI: usize = 2; + const NO: usize = 1; + fn all_signatures(&self) -> Box<dyn Iterator<Item = TypeSignature>> { + Box::new( + [GEN_F_TYPES, GEN_D_TYPES] + .into_iter() + .flatten() + .flat_map(|t| { + [ + TypeSignature::new([t.scalar(), t], [t]), + TypeSignature::new([t, t], [t]), + ] + }) + .dedup(), + ) + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Smoothstep; +impl Smoothstep { + pub fn all() -> impl Iterator<Item = Self> { + std::iter::once(Self) + } +} +impl FixedNode for Smoothstep { + const NI: usize = 3; + const NO: usize = 1; + fn all_signatures(&self) -> Box<dyn Iterator<Item = TypeSignature>> { + Box::new( + [GEN_F_TYPES, GEN_D_TYPES] + .into_iter() + .flatten() + .flat_map(|t| { + [ + TypeSignature::new([t.scalar(), t.scalar(), t], [t]), + TypeSignature::new([t, t, t], [t]), + ] + }) + .dedup(), + ) + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Length; +impl Length { + pub fn all() -> impl Iterator<Item = Self> { + std::iter::once(Self) + } +} +impl FixedNode for Length { + const NI: usize = 1; + const NO: usize = 1; + fn all_signatures(&self) -> Box<dyn Iterator<Item = TypeSignature>> { + Box::new( + [GEN_F_TYPES, GEN_D_TYPES] + .into_iter() + .flatten() + .map(|t| TypeSignature::new([t], [t.scalar()])), + ) + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum VecVecToScalar { + Distance, + Dot, +} +impl VecVecToScalar { + pub fn all() -> impl Iterator<Item = Self> { + [Self::Distance, Self::Dot].into_iter() + } +} +impl FixedNode for VecVecToScalar { + const NI: usize = 2; + const NO: usize = 1; + fn all_signatures(&self) -> Box<dyn Iterator<Item = TypeSignature>> { + Box::new( + [GEN_F_TYPES, GEN_D_TYPES] + .into_iter() + .flatten() + .map(|t| TypeSignature::new([t, t], [t.scalar()])), + ) + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Cross; +impl Cross { + pub fn all() -> impl Iterator<Item = Self> { + std::iter::once(Self) + } +} +impl FixedNode for Cross { + const NI: usize = 2; + const NO: usize = 1; + fn all_signatures(&self) -> Box<dyn Iterator<Item = TypeSignature>> { + Box::new( + [GEN_F_TYPES, GEN_D_TYPES] + .into_iter() + .flatten() + .map(|t| TypeSignature::new([t, t], [t])), + ) + } +} + #[enum_dispatch(ConcreteNode)] #[derive(Copy, Clone, PartialEq, Serialize, Deserialize)] pub enum BuiltinFunction { @@ -407,7 +621,13 @@ pub enum BuiltinFunction { Modf(Modf), MinMax(MinMax), Clamp(Clamp), + Pow(Pow), Mix(Mix), + Step(Step), + Smoothstep(Smoothstep), + Length(Length), + VecVecToScalar(VecVecToScalar), + Cross(Cross), } impl NodeIndex for BuiltinFunction { @@ -422,6 +642,90 @@ impl NodeIndex for BuiltinFunction { .chain(MinMax::all().map(Self::from)) .chain(Clamp::all().map(Self::from)) .chain(Mix::all().map(Self::from)) + .chain(Step::all().map(Self::from)) + .chain(Smoothstep::all().map(Self::from)) + .chain(Pow::all().map(Self::from)) + .chain(Length::all().map(Self::from)) + .chain(VecVecToScalar::all().map(Self::from)) + .chain(Cross::all().map(Self::from)) + } + + fn pick_node(ui: &mut egui::Ui) -> Option<Self> { + let mut res: Option<Self> = None; + ui.menu_button(Self::TITLE, |ui| { + for (title, nodes) in [ + ("Operators", BinArithmetic::all().map(Self::from).collect()), + ( + "Trigonometry", + vec![ + Self::from(Thru1::Radians), + Self::from(Thru1::Degrees), + Self::from(Thru1::Sin), + Self::from(Thru1::Cos), + Self::from(Thru1::Tan), + Self::from(Thru1::Asin), + Self::from(Thru1::Acos), + Self::from(Thru1::Atan), + Self::from(Thru1::Sinh), + Self::from(Thru1::Cosh), + Self::from(Thru1::Tanh), + Self::from(Thru1::Asinh), + Self::from(Thru1::Acosh), + Self::from(Thru1::Atanh), + ], + ), + ( + "Exponential", + vec![ + Self::from(Pow), + Self::from(Thru1::Exp), + Self::from(Thru1::Log), + Self::from(Thru1::Exp2), + Self::from(Thru1::Log2), + Self::from(Thru1::Sqrt), + Self::from(Thru1::Inverseqrt), + ], + ), + ( + "Common", + vec![ + Self::from(Thru1::Abs), + Self::from(Thru1::Sign), + Self::from(Thru1::Floor), + Self::from(Thru1::Trunc), + Self::from(Thru1::Round), + Self::from(Thru1::RoundEven), + Self::from(Thru1::Ceil), + Self::from(Thru1::Fract), + Self::from(Mod), + Self::from(Modf), + Self::from(Mix), + Self::from(Step), + Self::from(Smoothstep), + ], + ), + ( + "Geometric", + vec![ + Self::from(Thru1::Normalize), + Self::from(Length), + Self::from(VecVecToScalar::Distance), + Self::from(VecVecToScalar::Dot), + Self::from(Cross), + ], + ), + ] { + ui.menu_button(title, |ui| { + for node in nodes { + if ui.button(format!("{node}")).clicked() { + res = Some(node); + } + } + }); + } + }); + + res } } @@ -435,6 +739,12 @@ impl fmt::Display for BuiltinFunction { Self::MinMax(x) => fmt::Debug::fmt(x, f), Self::Clamp(x) => fmt::Debug::fmt(x, f), Self::Mix(x) => fmt::Debug::fmt(x, f), + Self::Step(x) => fmt::Debug::fmt(x, f), + Self::Smoothstep(x) => fmt::Debug::fmt(x, f), + Self::Pow(x) => fmt::Debug::fmt(x, f), + Self::Length(x) => fmt::Debug::fmt(x, f), + Self::VecVecToScalar(x) => fmt::Debug::fmt(x, f), + Self::Cross(x) => fmt::Debug::fmt(x, f), } } } |
