diff options
Diffstat (limited to 'src/sdf.rs')
-rw-r--r-- | src/sdf.rs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/sdf.rs b/src/sdf.rs new file mode 100644 index 0000000..51d85cc --- /dev/null +++ b/src/sdf.rs @@ -0,0 +1,82 @@ +#![allow(dead_code)] // @TODO @TEMPORARY + +use std::fmt::Write; + +// we're only writing numbers and strings so write! should never fail. +macro_rules! write_str { + ($( $arg:tt )*) => { write!($($arg)*).unwrap() } +} + +enum R3ToR3 { + Identity, + Translate([f32; 3]) +} + +enum RToR { + Identity, + Add(f32) +} + +pub struct Sdf { + pre: R3ToR3, + post: RToR +} + +impl RToR { + /// treats `v<*initial value of var_idx>` as the input, and puts the output in `v<final value of *var_idx>`. + fn to_glsl(&self, code: &mut String, var_idx: &mut u32) { + use RToR::*; + let input = *var_idx; + + match self { + Identity => {}, // no code + Add(x) => { + *var_idx += 1; + let output = *var_idx; + write_str!(code, "float v{output} = v{input} + {x};\n"); + } + } + } +} + +impl R3ToR3 { + /// treats `v<*initial value of var_idx>` as the input, and puts the output in `v<final value of *var_idx>`. + fn to_glsl(&self, code: &mut String, var_idx: &mut u32) { + use R3ToR3::*; + let input = *var_idx; + + match self { + Identity => {}, // no code + Translate([x, y, z]) => { + *var_idx += 1; + let output = *var_idx; + write_str!(code, "vec3 v{output} = v{input} + vec3({x}, {y}, {z});\n"); + }, + } + } +} + +impl Sdf { + /// test sphere + pub fn sphere() -> Self { + Self { + pre: R3ToR3::Identity, + post: RToR::Identity + } + } + + /// appends some glsl code including a function `float sdf(vec3 p) { ... }` + pub fn to_glsl(&self, code: &mut String) { + code.push_str("float sdf(vec3 p) {\n"); + // don't start out right next to the origin, since weird stuff might be happening there + let origin_dist: f32 = 2.0; + write_str!(code, "vec3 v0 = p - vec3(0,0,-{}.);\n", origin_dist); + let mut var_idx = 0; + self.pre.to_glsl(code, &mut var_idx); + write_str!(code, "float v{} = length(v{}) - 1.0;\n", var_idx + 1, var_idx); + var_idx += 1; + self.post.to_glsl(code, &mut var_idx); + write_str!(code, "return v{var_idx};\n"); + code.push('}'); + } +} |