summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-12-17 15:59:27 -0500
committerpommicket <pommicket@gmail.com>2022-12-17 15:59:27 -0500
commit59933702dc8ead31528fbc4ff786819e88d83c99 (patch)
tree66b8cf97350a74622958ca1f917eea26f8392976 /src
parentc54c5900588eb682f206aa5b92156dd868b9cd32 (diff)
copy+paste scene
Diffstat (limited to 'src')
-rw-r--r--src/main.rs101
-rw-r--r--src/sdf.rs14
-rw-r--r--src/sdl.rs12
-rw-r--r--src/win.rs96
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);
diff --git a/src/sdf.rs b/src/sdf.rs
index ab30fad..b78d119 100644
--- a/src/sdf.rs
+++ b/src/sdf.rs
@@ -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,
+ }
+ }
}
diff --git a/src/sdl.rs b/src/sdl.rs
index 05a647a..470da90 100644
--- a/src/sdl.rs
+++ b/src/sdl.rs
@@ -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
diff --git a/src/win.rs b/src/win.rs
index 393faee..a9b277e 100644
--- a/src/win.rs
+++ b/src/win.rs
@@ -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 });
}
}
}