summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-12-14 16:35:37 -0500
committerpommicket <pommicket@gmail.com>2022-12-14 16:35:37 -0500
commite45cbe4744c76a160e012a4d9bcf8d46340821d8 (patch)
tree2cf8ebf531241be734b867fd097046d70d3d3a97
parenteff66f8056b01a732df9523cb3a3d06b2d69c750 (diff)
generating random sdfs
-rw-r--r--src/main.rs21
-rw-r--r--src/sdf.rs46
2 files changed, 55 insertions, 12 deletions
diff --git a/src/main.rs b/src/main.rs
index 3e0a55d..a9e9909 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -65,16 +65,17 @@ impl View {
}
fn try_main() -> Result<(), String> {
- use sdf::{Constant, R3ToR, R3ToR3, RToR};
- let _test = Constant::gen_thread_random();
- println!("{_test:?}");
-
- let funciton = R3ToR::compose(
- R3ToR3::InfiniteMirrors(Constant::from(2.0)),
- R3ToR::sphere_f32(0.2),
- RToR::Identity,
- );
- let my_sdf = sdf::Sdf::from_function(funciton);
+// use sdf::{Constant, R3ToR, R3ToR3, RToR};
+// let _test = Constant::gen_thread_random();
+// println!("{_test:?}");
+//
+// let funciton = R3ToR::compose(
+// R3ToR3::InfiniteMirrors(Constant::from(2.0)),
+// R3ToR::sphere_f32(0.2),
+// RToR::Identity,
+// );
+ let my_sdf = sdf::Sdf::gen_thread_random_max_depth(6);
+ println!("{my_sdf:?}");
let mut window = win::Window::new("AutoSDF", 1280, 720, true)
.map_err(|e| format!("Error creating window: {e}"))?;
diff --git a/src/sdf.rs b/src/sdf.rs
index 7456d25..3c54d34 100644
--- a/src/sdf.rs
+++ b/src/sdf.rs
@@ -16,7 +16,7 @@ macro_rules! write_str {
pub enum Constant {
#[prob = 0.5]
F32(f32),
- #[prob = 0.5]
+ #[prob = 0]
Time(f32, f32),
}
@@ -36,6 +36,7 @@ impl Display for Constant {
}
}
+#[derive(GenRandom, Debug)]
pub struct Constant3(Constant, Constant, Constant);
impl From<(Constant, Constant, Constant)> for Constant3 {
@@ -51,26 +52,43 @@ impl Display for Constant3 {
}
}
+#[derive(GenRandom, Debug)]
pub enum R3ToR3 {
+ #[prob = 0]
Identity,
+ #[prob = 6]
Compose(Box<R3ToR3>, Box<R3ToR3>),
+ #[prob = 1]
Translate(Constant3),
+ #[prob = 2]
Sin(Constant),
+ #[prob = 2]
InfiniteMirrors(Constant),
}
+#[derive(GenRandom, Debug)]
pub enum RToR {
+ #[prob = 0]
Identity,
+ #[prob = 2]
Compose(Box<RToR>, Box<RToR>),
+ #[prob = 2]
Add(Constant),
}
+#[derive(GenRandom, Debug)]
pub enum R3ToR {
+ #[prob = 1]
Sphere(Constant),
+ #[prob = 1]
Cube(Constant),
+ #[prob = 8]
Compose(Box<R3ToR3>, Box<R3ToR>, Box<RToR>),
+ #[prob = 4]
Mix(Box<R3ToR>, Box<R3ToR>, Constant),
+ #[prob = 2]
SmoothMin(Box<R3ToR>, Box<R3ToR>),
+ #[prob = 2]
Min(Box<R3ToR>, Box<R3ToR>),
}
@@ -148,6 +166,7 @@ impl VarCounter {
}
}
+#[derive(Debug)]
pub struct Sdf {
distance_function: R3ToR,
}
@@ -279,6 +298,29 @@ impl Function for R3ToR {
}
}
+impl GenRandom for Sdf {
+ fn gen_random_max_depth(rng: &mut impl rand::Rng, max_depth: isize) -> Self {
+ // to make sure the SDF isn't too boring or too slow,
+ // we'll generate a bunch then take the one with the median code length.
+ let mut distance_functions = vec![];
+ for _i in 0..20 {
+ let f = R3ToR::gen_random_max_depth(rng, max_depth);
+ let mut code = String::new();
+ let mut var = VarCounter::new();
+ let _ = f.to_glsl(var.next(), &mut code, &mut var);
+ let len = code.len();
+
+ distance_functions.push((len, f));
+ }
+ distance_functions.sort_by_key(|x| x.0);
+ let distance_function = distance_functions.remove(distance_functions.len() / 2).1;
+
+ Sdf {
+ distance_function
+ }
+ }
+}
+
impl Sdf {
/// test sphere
pub fn sphere(r: f32) -> Self {
@@ -286,7 +328,7 @@ impl Sdf {
distance_function: R3ToR::Sphere(Constant::F32(r)),
}
}
-
+
pub fn from_function(distance_function: R3ToR) -> Self {
Self { distance_function }
}