use bevy::prelude::*;
use crate::util::generate_shader_id;
pub trait SdfAssets {
fn add_sdf_body<T: Into<String>>(&mut self, sdf: T) -> Handle<Shader>;
fn add_sdf_expr<T: Into<String>>(&mut self, sdf: T) -> Handle<Shader>;
fn add_fill_body<T: Into<String>>(&mut self, fill: T) -> Handle<Shader>;
fn add_fill_expr<T: Into<String>>(&mut self, fill: T) -> Handle<Shader>;
}
impl SdfAssets for Assets<Shader> {
fn add_sdf_body<T: Into<String>>(&mut self, sdf: T) -> Handle<Shader> {
let body = sdf.into();
let id = generate_shader_id();
let shader = Shader::from_wgsl(
format!(
r#"
#define_import_path smud::sdf{id}
#import smud
fn sdf(input: smud::SdfInput) -> f32 {{
// Backward compatibility aliases for the old API
let p = input.pos;
let params = input.params;
let bounds = input.bounds;
{body}
}}
"#
),
file!(),
);
self.add(shader)
}
fn add_fill_body<T: Into<String>>(&mut self, fill: T) -> Handle<Shader> {
let body = fill.into();
let id = generate_shader_id();
let shader = Shader::from_wgsl(
format!(
r#"
#define_import_path smud::fill{id}
#import smud
#import bevy_render::globals::Globals
@group(0) @binding(1) var<uniform> globals: Globals;
fn fill(input: smud::FillInput) -> vec4<f32> {{
let time = globals.time;
let p = input.pos;
let params = input.params;
let d = input.distance;
{body}
}}
"#
),
file!(),
);
self.add(shader)
}
fn add_sdf_expr<T: Into<String>>(&mut self, sdf: T) -> Handle<Shader> {
let e = sdf.into();
self.add_sdf_body(format!("return {e};"))
}
fn add_fill_expr<T: Into<String>>(&mut self, fill: T) -> Handle<Shader> {
let e = fill.into();
self.add_fill_body(format!("return {e};"))
}
}