a large number of small ui changes
This commit is contained in:
+56
-37
@@ -2,7 +2,7 @@ use std::sync::mpsc::{self, Receiver, TryRecvError};
|
|||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use eframe::egui::{
|
use eframe::egui::{
|
||||||
self, Color32, ColorImage, Context, DragValue, RichText, Sense, Slider, TextureHandle,
|
self, Color32, ColorImage, Context, DragValue, Frame, RichText, Sense, Slider, TextureHandle,
|
||||||
TextureOptions, Ui, Vec2,
|
TextureOptions, Ui, Vec2,
|
||||||
};
|
};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
@@ -42,7 +42,7 @@ impl TerrainApp {
|
|||||||
Self {
|
Self {
|
||||||
params: GenerationParams::default(),
|
params: GenerationParams::default(),
|
||||||
generation_tab: LeftTab::Generation,
|
generation_tab: LeftTab::Generation,
|
||||||
preview_focus: PreviewFocus::Heightmap,
|
preview_focus: PreviewFocus::Bumpmap,
|
||||||
textures: None,
|
textures: None,
|
||||||
generated: None,
|
generated: None,
|
||||||
generation_receiver: None,
|
generation_receiver: None,
|
||||||
@@ -127,11 +127,16 @@ impl TerrainApp {
|
|||||||
.default_width(320.0)
|
.default_width(320.0)
|
||||||
.min_width(280.0)
|
.min_width(280.0)
|
||||||
.show(ctx, |ui| {
|
.show(ctx, |ui| {
|
||||||
ui.heading("Terrain Generator");
|
ui.heading("Advanced Erosion Terrain Generator");
|
||||||
ui.add_space(8.0);
|
ui.add_space(8.0);
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
Self::tab_button(ui, &mut self.generation_tab, LeftTab::Generation, "Generation");
|
Self::tab_button(
|
||||||
|
ui,
|
||||||
|
&mut self.generation_tab,
|
||||||
|
LeftTab::Generation,
|
||||||
|
"Generation",
|
||||||
|
);
|
||||||
Self::tab_button(ui, &mut self.generation_tab, LeftTab::Advanced, "Advanced");
|
Self::tab_button(ui, &mut self.generation_tab, LeftTab::Advanced, "Advanced");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -231,48 +236,48 @@ impl TerrainApp {
|
|||||||
let bottom_strip_height = (available.y * 0.24).max(120.0).min(220.0);
|
let bottom_strip_height = (available.y * 0.24).max(120.0).min(220.0);
|
||||||
let main_height = (available.y - bottom_strip_height - 8.0).max(100.0);
|
let main_height = (available.y - bottom_strip_height - 8.0).max(100.0);
|
||||||
|
|
||||||
let (main_texture, bottom_texture) = match self.preview_focus {
|
let main_texture = match self.preview_focus {
|
||||||
PreviewFocus::Heightmap => (&textures.heightmap, &textures.bumpmap),
|
PreviewFocus::Heightmap => &textures.heightmap,
|
||||||
PreviewFocus::Bumpmap => (&textures.bumpmap, &textures.heightmap),
|
PreviewFocus::Bumpmap => &textures.bumpmap,
|
||||||
};
|
};
|
||||||
|
|
||||||
render_clickable_image(ui, main_texture, Vec2::new(available.x, main_height), false);
|
render_clickable_image(ui, main_texture, Vec2::new(available.x, main_height), false);
|
||||||
ui.add_space(8.0);
|
ui.add_space(8.0);
|
||||||
|
|
||||||
ui.horizontal_centered(|ui| {
|
let thumb_width = (available.x * 0.28).max(120.0).min(240.0);
|
||||||
let thumb_width = ((available.x - 24.0) * 0.28).max(100.0).min(220.0);
|
let panel_width = (thumb_width + 32.0).min(available.x);
|
||||||
let spacer = (available.x - thumb_width * 2.0).max(0.0);
|
let secondary_texture = match self.preview_focus {
|
||||||
|
PreviewFocus::Heightmap => &textures.bumpmap,
|
||||||
let main_thumb_clicked = render_clickable_image(
|
PreviewFocus::Bumpmap => &textures.heightmap,
|
||||||
ui,
|
|
||||||
match self.preview_focus {
|
|
||||||
PreviewFocus::Heightmap => &textures.heightmap,
|
|
||||||
PreviewFocus::Bumpmap => &textures.bumpmap,
|
|
||||||
},
|
|
||||||
Vec2::new(thumb_width, bottom_strip_height),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
ui.add_space(spacer);
|
|
||||||
|
|
||||||
let secondary_clicked =
|
|
||||||
render_clickable_image(ui, bottom_texture, Vec2::new(thumb_width, bottom_strip_height), true);
|
|
||||||
|
|
||||||
if main_thumb_clicked {
|
|
||||||
self.preview_focus = match self.preview_focus {
|
|
||||||
PreviewFocus::Heightmap => PreviewFocus::Heightmap,
|
|
||||||
PreviewFocus::Bumpmap => PreviewFocus::Bumpmap,
|
|
||||||
};
|
};
|
||||||
}
|
let secondary_focus = match self.preview_focus {
|
||||||
|
|
||||||
if secondary_clicked {
|
|
||||||
self.preview_focus = match self.preview_focus {
|
|
||||||
PreviewFocus::Heightmap => PreviewFocus::Bumpmap,
|
PreviewFocus::Heightmap => PreviewFocus::Bumpmap,
|
||||||
PreviewFocus::Bumpmap => PreviewFocus::Heightmap,
|
PreviewFocus::Bumpmap => PreviewFocus::Heightmap,
|
||||||
};
|
};
|
||||||
|
let secondary_label = match secondary_focus {
|
||||||
|
PreviewFocus::Heightmap => "Heightmap",
|
||||||
|
PreviewFocus::Bumpmap => "Bumpmap",
|
||||||
|
};
|
||||||
|
|
||||||
|
ui.horizontal_centered(|ui| {
|
||||||
|
Frame::group(ui.style()).show(ui, |ui| {
|
||||||
|
ui.set_min_width(panel_width);
|
||||||
|
ui.set_max_width(panel_width);
|
||||||
|
ui.vertical_centered(|ui| {
|
||||||
|
ui.label(RichText::new(secondary_label).strong());
|
||||||
|
ui.add_space(6.0);
|
||||||
|
if render_clickable_image(
|
||||||
|
ui,
|
||||||
|
secondary_texture,
|
||||||
|
Vec2::new(thumb_width, bottom_strip_height - 32.0),
|
||||||
|
true,
|
||||||
|
) {
|
||||||
|
self.preview_focus = secondary_focus;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,7 +299,12 @@ fn gray_to_color_image(image: &image::GrayImage) -> ColorImage {
|
|||||||
ColorImage::new(size, pixels)
|
ColorImage::new(size, pixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn labeled_int_slider(ui: &mut Ui, label: &str, value: &mut usize, range: std::ops::RangeInclusive<usize>) {
|
fn labeled_int_slider(
|
||||||
|
ui: &mut Ui,
|
||||||
|
label: &str,
|
||||||
|
value: &mut usize,
|
||||||
|
range: std::ops::RangeInclusive<usize>,
|
||||||
|
) {
|
||||||
ui.label(label);
|
ui.label(label);
|
||||||
let mut slider_value = *value as u32;
|
let mut slider_value = *value as u32;
|
||||||
if ui
|
if ui
|
||||||
@@ -320,12 +330,21 @@ fn labeled_float_slider(
|
|||||||
ui.add(slider);
|
ui.add(slider);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_clickable_image(ui: &mut Ui, texture: &TextureHandle, max_size: Vec2, clickable: bool) -> bool {
|
fn render_clickable_image(
|
||||||
|
ui: &mut Ui,
|
||||||
|
texture: &TextureHandle,
|
||||||
|
max_size: Vec2,
|
||||||
|
clickable: bool,
|
||||||
|
) -> bool {
|
||||||
let image_size = texture.size_vec2();
|
let image_size = texture.size_vec2();
|
||||||
let scale = (max_size.x / image_size.x).min(max_size.y / image_size.y);
|
let scale = (max_size.x / image_size.x).min(max_size.y / image_size.y);
|
||||||
let desired_size = image_size * scale.max(0.01);
|
let desired_size = image_size * scale.max(0.01);
|
||||||
let image = egui::Image::new(texture)
|
let image = egui::Image::new(texture)
|
||||||
.fit_to_exact_size(desired_size)
|
.fit_to_exact_size(desired_size)
|
||||||
.sense(if clickable { Sense::click() } else { Sense::hover() });
|
.sense(if clickable {
|
||||||
|
Sense::click()
|
||||||
|
} else {
|
||||||
|
Sense::hover()
|
||||||
|
});
|
||||||
ui.add(image).clicked()
|
ui.add(image).clicked()
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-4
@@ -28,7 +28,7 @@ impl Default for GenerationParams {
|
|||||||
Self {
|
Self {
|
||||||
image_width: 512,
|
image_width: 512,
|
||||||
image_height: 512,
|
image_height: 512,
|
||||||
generation_scale: 6.0,
|
generation_scale: 1.0,
|
||||||
erosion_scale: 0.15,
|
erosion_scale: 0.15,
|
||||||
random_seed: 0,
|
random_seed: 0,
|
||||||
erosion_strength: 0.05,
|
erosion_strength: 0.05,
|
||||||
@@ -124,9 +124,10 @@ fn clamp01(x: f32) -> f32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn hash22(p: Vec2, random_seed: u64) -> Vec2 {
|
fn hash22(p: Vec2, random_seed: u64) -> Vec2 {
|
||||||
let seed = random_seed as f64;
|
let scrambled_x = splitmix64(random_seed ^ 0x9E37_79B9_7F4A_7C15);
|
||||||
let seed_x = seed * 0.754_877_666_246_692_7;
|
let scrambled_y = splitmix64(random_seed ^ 0xBF58_476D_1CE4_E5B9);
|
||||||
let seed_y = seed * 0.569_840_290_998_053_2;
|
let seed_x = u64_to_unit_f64(scrambled_x) * 1024.0;
|
||||||
|
let seed_y = u64_to_unit_f64(scrambled_y) * 1024.0;
|
||||||
let kx = 0.318_309_9_f64;
|
let kx = 0.318_309_9_f64;
|
||||||
let ky = 0.367_879_4_f64;
|
let ky = 0.367_879_4_f64;
|
||||||
|
|
||||||
@@ -140,6 +141,18 @@ fn hash22(p: Vec2, random_seed: u64) -> Vec2 {
|
|||||||
Vec2::new(rx as f32, ry as f32)
|
Vec2::new(rx as f32, ry as f32)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn splitmix64(mut x: u64) -> u64 {
|
||||||
|
x = x.wrapping_add(0x9E37_79B9_7F4A_7C15);
|
||||||
|
x = (x ^ (x >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9);
|
||||||
|
x = (x ^ (x >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB);
|
||||||
|
x ^ (x >> 31)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn u64_to_unit_f64(value: u64) -> f64 {
|
||||||
|
const SCALE: f64 = 1.0 / (u64::MAX as f64);
|
||||||
|
(value as f64) * SCALE
|
||||||
|
}
|
||||||
|
|
||||||
fn noised(p: Vec2, random_seed: u64) -> (f32, Vec2) {
|
fn noised(p: Vec2, random_seed: u64) -> (f32, Vec2) {
|
||||||
let i = Vec2::new(p.x.floor(), p.y.floor());
|
let i = Vec2::new(p.x.floor(), p.y.floor());
|
||||||
let f = Vec2::new(p.x - i.x, p.y - i.y);
|
let f = Vec2::new(p.x - i.x, p.y - i.y);
|
||||||
|
|||||||
Reference in New Issue
Block a user