aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2025-12-27 11:44:32 +0000
committers-ol <s+removethis@s-ol.nu>2025-12-27 11:44:32 +0000
commit568f6818a0b5453dea25faff4ffa46c0e8c66530 (patch)
tree8ef95bcaf2b5ad57cedfd7d52c98794c2e73b09a /src
parentNodeIndex type (diff)
downloadnodetoy-568f6818a0b5453dea25faff4ffa46c0e8c66530.tar.gz
nodetoy-568f6818a0b5453dea25faff4ffa46c0e8c66530.zip
expand and organize builtin functions
Diffstat (limited to 'src')
-rw-r--r--src/library.rs328
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),
}
}
}