diff options
author | pommicket <pommicket@gmail.com> | 2022-12-17 15:59:27 -0500 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2022-12-17 15:59:27 -0500 |
commit | 59933702dc8ead31528fbc4ff786819e88d83c99 (patch) | |
tree | 66b8cf97350a74622958ca1f917eea26f8392976 /src | |
parent | c54c5900588eb682f206aa5b92156dd868b9cd32 (diff) |
copy+paste scene
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 101 | ||||
-rw-r--r-- | src/sdf.rs | 14 | ||||
-rw-r--r-- | src/sdl.rs | 12 | ||||
-rw-r--r-- | src/win.rs | 96 |
4 files changed, 179 insertions, 44 deletions
diff --git a/src/main.rs b/src/main.rs index f010914..4737245 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,8 @@ @TODO: - auto-select level set by sampling a bunch of points - bring time back, w pause/rewind/adjust time speed (start out paused?) +- feedback for copy/paste (flash screen or something) +- clean up code w a big state object - Params instead of depth for GenRandom - allow multiple endpoints (cube & sphere & ...) - seed control (maybe save seeds to a file then let user go back&forth through past sdfs) @@ -14,7 +16,8 @@ - AA quality - # iterations, distance cutoff - documentation -- GenRandom integers (+ gen_random_scale_bias +- GenRandom integers (+ gen_random_scale_bias) +- better SDL api: Context + Window<'a> impl !Send+!Sync ----- cool seeds: @@ -259,43 +262,23 @@ void main() { Ok(()) } -fn gen_program_with_seed( - window: &mut win::Window, - program: &mut win::Program, - seed: u64, -) -> Result<(), String> { +fn get_rng() -> impl rand::Rng { use rand::SeedableRng; - - let mut rng = rand::rngs::SmallRng::seed_from_u64(seed); - let my_sdf = sdf::R3ToR::good_random(&mut rng, 6); - let color_function = sdf::R3ToR3::good_random(&mut rng, 7); - let scene = sdf::Scene { - sdf: my_sdf, - color_function, - }; - gen_program_from_scene(window, program, &scene) -} - -fn gen_program(window: &mut win::Window, program: &mut win::Program) -> Result<(), String> { - let seed = rand::random::<u64>(); - gen_program_with_seed(window, program, seed) -} - -#[allow(dead_code)] // @TODO @TEMPORARY -fn gen_program_from_string( - window: &mut win::Window, - program: &mut win::Program, - s: &str, -) -> Result<(), String> { - let scene = sdf::Scene::import_string(s).ok_or_else(|| "bad scene string".to_string())?; - gen_program_from_scene(window, program, &scene) + rand::rngs::SmallRng::seed_from_u64(rand::random::<u64>()) } fn try_main() -> Result<(), String> { let mut window = win::Window::new("AutoSDF", 1280, 720, true) .map_err(|e| format!("Error creating window: {e}"))?; let mut program = window.new_program(); - gen_program_with_seed(&mut window, &mut program, 1)?; + let config = sdf::SceneConfig { + sdf_max_depth: 7, + color_max_depth: 6, + }; + let mut scene = sdf::Scene::good_random(&mut get_rng(), &config); + gen_program_from_scene(&mut window, &mut program, &scene).unwrap_or_else(|e| + eprintln!("Error: {e}") + ); //gen_program_from_string(&mut window, &mut program, "a263736466a167436f6d706f736583a1695472616e736c61746583a163463332fa3ea4c00ca163463332fa3e85dc00a163463332fa3f2bbdaea167436f6d706f736583a166526f7461746583a163463332fa3f750dc2a163463332fa3f5a7f0ea163463332fa3f2df98ca1634d696e82a167436f6d706f736583a167436f6d706f736582a16353696ea163463332fa3f7cc2a0a167436f6d706f736582684964656e74697479684964656e74697479a166537068657265a163463332fa3f26f8f6684964656e74697479a167436f6d706f736583a166526f7461746583a163463332fa3f1bfed8a163463332fa3f1e1e30a163463332fa3eddc6b0a1634d697883a167436f6d706f736583684964656e74697479a166537068657265a163463332fa3ea149ec684964656e74697479a167436f6d706f736583684964656e74697479a166537068657265a163463332fa3f6b0018684964656e74697479a163463332fa3e60a8d8684964656e74697479684964656e74697479684964656e746974796e636f6c6f725f66756e6374696f6ea165537153696ea163463332fa3ebaa7ec")?; let mut buffer = window.create_buffer(); @@ -327,13 +310,57 @@ fn try_main() -> Result<(), String> { use win::Event::*; use win::Key::*; match event { - Quit | KeyDown(Escape) => break 'mainloop, - KeyDown(F1) => show_debug_info = !show_debug_info, - KeyDown(R) => { - gen_program(&mut window, &mut program)?; - view.level_set = 0.0; + Quit | KeyDown { key: Escape, .. } => break 'mainloop, + KeyDown { key: F1, .. } => show_debug_info = !show_debug_info, + KeyDown { key: R, .. } => { + scene = sdf::Scene::good_random(&mut get_rng(), &config); + match gen_program_from_scene(&mut window, &mut program, &scene) { + Ok(()) => { + view.level_set = 0.0; + } + Err(e) => { + eprintln!("Error: {e}") + } + }; + } + KeyDown { key: C, modifier, .. } if modifier.ctrl() => { + // copy scene + match window.set_clipboard_text(&scene.export_string()) { + Ok(()) => { + } + Err(e) => { + eprintln!("couldn't copy text to clipboard: {e}") + } + } + } + KeyDown { key: V, modifier, .. } if modifier.ctrl() => { + // paste scene + match window.get_clipboard_text() { + Ok(s) => { + match sdf::Scene::import_string(&s) { + Some(new_scene) => { + scene = new_scene; + match gen_program_from_scene(&mut window, &mut program, &scene) { + Ok(()) => { + view.level_set = 0.0; + } + Err(e) => { + eprintln!("Error: {e}") + } + } + } + None => { + eprintln!("bad string") + } + } + } + Err(e) => { + // very unlikely to happen + eprintln!("couldn't get clipboard text: {e}") + } + } } - KeyDown(N0) => view.level_set = 0.0, + KeyDown { key: N0, .. } => view.level_set = 0.0, MouseMotion { xrel, yrel, .. } => { let mouse_sensitivity = 0.05; view.yaw_by(-xrel as f32 * mouse_sensitivity * frame_dt); @@ -543,6 +543,11 @@ impl R3ToR3 { } } +pub struct SceneConfig { + pub sdf_max_depth: isize, + pub color_max_depth: isize +} + #[derive(Serialize, Deserialize)] pub struct Scene { pub sdf: R3ToR, @@ -563,4 +568,13 @@ impl Scene { let bytes = decode_hex(s)?; serde_cbor::from_reader(&bytes[..]).ok()? } + + pub fn good_random(rng: &mut impl Rng, config: &SceneConfig) -> Self { + let sdf = R3ToR::good_random(rng, config.sdf_max_depth); + let color_function = R3ToR3::good_random(rng, config.color_max_depth); + Scene { + sdf, + color_function, + } + } } @@ -220,6 +220,18 @@ pub const AUDIO_F32LSB: u16 = 0x8120; pub const AUDIO_F32MSB: u16 = 0x9120; pub const AUDIO_F32: u16 = AUDIO_F32LSB; +pub const KMOD_NONE: u16 = 0x0000; +pub const KMOD_LSHIFT: u16 = 0x0001; +pub const KMOD_RSHIFT: u16 = 0x0002; +pub const KMOD_LCTRL: u16 = 0x0040; +pub const KMOD_RCTRL: u16 = 0x0080; +pub const KMOD_LALT: u16 = 0x0100; +pub const KMOD_RALT: u16 = 0x0200; +pub const KMOD_LGUI: u16 = 0x0400; +pub const KMOD_RGUI: u16 = 0x0800; +pub const KMOD_NUM: u16 = 0x1000; +pub const KMOD_CAPS: u16 = 0x2000; + // NOTE: ideally we wouldn't need Copy on all of these // but otherwise we wouldn't be able to put them in a union @@ -270,11 +270,91 @@ impl Key { } } -#[derive(Debug)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct KeyModifier { + lctrl: bool, + lshift: bool, + lalt: bool, + lgui: bool, + rctrl: bool, + rshift: bool, + ralt: bool, + rgui: bool, + numlock: bool, + capslock: bool, +} + +impl KeyModifier { + pub fn lctrl(&self) -> bool { + self.lctrl + } + pub fn rctrl(&self) -> bool { + self.rctrl + } + pub fn lshift(&self) -> bool { + self.lshift + } + pub fn rshift(&self) -> bool { + self.rshift + } + pub fn lalt(&self) -> bool { + self.lalt + } + pub fn ralt(&self) -> bool { + self.ralt + } + pub fn lgui(&self) -> bool { + self.lgui + } + pub fn rgui(&self) -> bool { + self.rgui + } + pub fn ctrl(&self) -> bool { + self.lctrl || self.rctrl + } + pub fn shift(&self) -> bool { + self.lshift || self.rshift + } + pub fn alt(&self) -> bool { + self.lalt || self.ralt + } + pub fn gui(&self) -> bool { + self.lgui || self.rgui + } + pub fn capslock(&self) -> bool { + self.capslock + } + pub fn numlock(&self) -> bool { + self.numlock + } + + fn from_sdl(keymod: u16) -> Self { + Self { + lctrl: (keymod & sdl::KMOD_LCTRL) != 0, + rctrl: (keymod & sdl::KMOD_RCTRL) != 0, + lshift: (keymod & sdl::KMOD_LSHIFT) != 0, + rshift: (keymod & sdl::KMOD_RSHIFT) != 0, + lalt: (keymod & sdl::KMOD_LALT) != 0, + ralt: (keymod & sdl::KMOD_RALT) != 0, + lgui: (keymod & sdl::KMOD_LGUI) != 0, + rgui: (keymod & sdl::KMOD_RGUI) != 0, + capslock: (keymod & sdl::KMOD_CAPS) != 0, + numlock: (keymod & sdl::KMOD_NUM) != 0, + } + } +} + +#[derive(Debug, Clone)] pub enum Event { Quit, - KeyDown(Key), - KeyUp(Key), + KeyDown { + key: Key, + modifier: KeyModifier + }, + KeyUp { + key: Key, + modifier: KeyModifier + }, MouseMotion { x: i32, y: i32, @@ -1074,12 +1154,14 @@ impl Window { match r#type { sdl::SDL_QUIT => return Some(Event::Quit), sdl::SDL_KEYDOWN | sdl::SDL_KEYUP => { - let scancode = unsafe { sdl.key }.keysym.scancode; - if let Some(k) = Key::from_sdl(scancode) { + let keysym = unsafe { sdl.key }.keysym; + let scancode = keysym.scancode; + if let Some(key) = Key::from_sdl(scancode) { + let modifier = KeyModifier::from_sdl(keysym.r#mod); if r#type == sdl::SDL_KEYDOWN { - return Some(Event::KeyDown(k)); + return Some(Event::KeyDown { key, modifier }); } else { - return Some(Event::KeyUp(k)); + return Some(Event::KeyUp { key, modifier }); } } } |