summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-12-15 11:33:32 -0500
committerpommicket <pommicket@gmail.com>2022-12-15 11:33:32 -0500
commit4f48f02f91f2134b4452729dd96524ea1814efb2 (patch)
tree2af6a435a33119bb2169cdec48da7a71c6bf0437 /src
parente45cbe4744c76a160e012a4d9bcf8d46340821d8 (diff)
various fixes
Diffstat (limited to 'src')
-rw-r--r--src/main.rs13
-rw-r--r--src/sdf.rs114
2 files changed, 95 insertions, 32 deletions
diff --git a/src/main.rs b/src/main.rs
index a9e9909..79b9d1f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,7 @@
/*
@TODO:
+- auto-select level set by sampling a bunch of points
+- Params instead of depth
- fullscreen key
- mathematical analysis
- options for:
@@ -65,16 +67,7 @@ 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::gen_thread_random_max_depth(6);
+ let my_sdf = sdf::Sdf::gen_thread_random_max_depth(7);
println!("{my_sdf:?}");
let mut window = win::Window::new("AutoSDF", 1280, 720, true)
diff --git a/src/sdf.rs b/src/sdf.rs
index 3c54d34..e6811ec 100644
--- a/src/sdf.rs
+++ b/src/sdf.rs
@@ -1,4 +1,3 @@
-#![allow(dead_code)] // @TODO @TEMPORARY
extern crate gen_random_proc_macro;
extern crate rand;
@@ -12,20 +11,47 @@ macro_rules! write_str {
}
/// these are constant across 3D space, not across time/user input/etc.
-#[derive(GenRandom, Debug)]
+#[derive(Debug, GenRandom)]
pub enum Constant {
- #[prob = 0.5]
+ #[prob(0.5)]
F32(f32),
- #[prob = 0]
- Time(f32, f32),
+ #[prob(0.5)]
+ Time(
+ #[scale(0.2)]
+ #[bias(-0.1)]
+ f32, f32),
}
+
+
impl From<f32> for Constant {
fn from(x: f32) -> Self {
Self::F32(x)
}
}
+impl std::ops::Add<f32> for Constant {
+ type Output = Self;
+ fn add(self, a: f32) -> Self::Output {
+ use Constant::*;
+ match self {
+ F32(x) => F32(x + a),
+ Time(s, b) => Time(s, b + a),
+ }
+ }
+}
+
+impl std::ops::Mul<f32> for Constant {
+ type Output = Self;
+ fn mul(self, m: f32) -> Self::Output {
+ use Constant::*;
+ match self {
+ F32(x) => F32(x * m),
+ Time(s, b) => Time(s * m, b * m),
+ }
+ }
+}
+
impl Display for Constant {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
use Constant::*;
@@ -39,6 +65,20 @@ impl Display for Constant {
#[derive(GenRandom, Debug)]
pub struct Constant3(Constant, Constant, Constant);
+impl std::ops::Add<f32> for Constant3 {
+ type Output = Self;
+ fn add(self, a: f32) -> Self::Output {
+ Self(self.0 + a, self.1 + a, self.2 + a)
+ }
+}
+
+impl std::ops::Mul<f32> for Constant3 {
+ type Output = Self;
+ fn mul(self, m: f32) -> Self::Output {
+ Self(self.0 * m, self.1 * m, self.2 * m)
+ }
+}
+
impl From<(Constant, Constant, Constant)> for Constant3 {
fn from(x: (Constant, Constant, Constant)) -> Self {
Self(x.0, x.1, x.2)
@@ -54,41 +94,46 @@ impl Display for Constant3 {
#[derive(GenRandom, Debug)]
pub enum R3ToR3 {
- #[prob = 0]
+ #[prob(0)]
Identity,
- #[prob = 6]
+ #[prob(6)]
Compose(Box<R3ToR3>, Box<R3ToR3>),
- #[prob = 1]
+ #[prob(1)]
Translate(Constant3),
- #[prob = 2]
+ #[prob(2)]
Sin(Constant),
- #[prob = 2]
+ #[prob(2)]
InfiniteMirrors(Constant),
+ #[prob(2)]
+ #[scale(2 * std::f32::consts::PI)]
+ Rotate(Constant3),
+ #[prob(2)]
+ Arctan(Constant) // arctan(c x) / c
}
#[derive(GenRandom, Debug)]
pub enum RToR {
- #[prob = 0]
+ #[prob(0)]
Identity,
- #[prob = 2]
+ #[prob(2)]
Compose(Box<RToR>, Box<RToR>),
- #[prob = 2]
- Add(Constant),
+ #[prob(2)]
+ Subtract(Constant),
}
#[derive(GenRandom, Debug)]
pub enum R3ToR {
- #[prob = 1]
+ #[prob(1)]
Sphere(Constant),
- #[prob = 1]
+ #[prob(1)]
Cube(Constant),
- #[prob = 8]
+ #[prob(8)]
Compose(Box<R3ToR3>, Box<R3ToR>, Box<RToR>),
- #[prob = 4]
+ #[prob(4)]
Mix(Box<R3ToR>, Box<R3ToR>, Constant),
- #[prob = 2]
+ #[prob(2)]
SmoothMin(Box<R3ToR>, Box<R3ToR>),
- #[prob = 2]
+ #[prob(2)]
Min(Box<R3ToR>, Box<R3ToR>),
}
@@ -184,9 +229,9 @@ impl Function for RToR {
match self {
Identity => input,
- Add(x) => {
+ Subtract(x) => {
let output = var.next();
- write_str!(code, "float {output} = {input} + {x};\n");
+ write_str!(code, "float {output} = {input} - {x};\n");
output
}
Compose(a, b) => {
@@ -233,6 +278,31 @@ impl Function for R3ToR3 {
let a_output = a.to_glsl(input, code, var);
b.to_glsl(a_output, code, var)
}
+ Arctan(c) => {
+ let output = var.next();
+ // we need to scale arctan(cx) so it doesn't break the SDF
+ write_str!(code, "vec3 {output} = (1.0 / {c}) * atan({c} * {input});\n");
+ output
+ },
+ Rotate(by) => {
+ // by = euler angles
+ // see https://en.wikipedia.org/wiki/Rotation_matrix#General_rotations
+ // for matrix
+ // this is the RzRyRx one
+ let c = var.next();
+ let s = var.next();
+ let m = var.next();
+ let output = var.next();
+ write_str!(code, "vec3 {c} = cos({by});\n");
+ write_str!(code, "vec3 {s} = sin({by});\n");
+ write_str!(code, "mat3 {m} = mat3(
+{c}.y*{c}.z, {s}.x*{s}.y*{c}.z - {c}.x*{s}.z, {c}.x*{s}.y*{c}.z + {s}.x*{s}.z,
+{c}.y*{s}.z, {s}.x*{s}.y*{s}.z + {c}.x*{c}.z, {c}.x*{s}.y*{s}.z - {s}.x*{c}.z,
+-{s}.y, {s}.x*{c}.y, {c}.x*{c}.y
+);\n");
+ write_str!(code, "vec3 {output} = {m} * {input};\n");
+ output
+ }
}
}
}