mikronova/kyokkou
src/art_scenes.rs
use crate::common::{Scene, ValidationStatus, render_button, show_validation};
#[derive(Debug, Clone, PartialEq)]
pub enum MetalType {
Gold,
Steel,
Chrome,
Copper,
}
#[derive(Debug, Clone, PartialEq)]
pub enum SceneType {
GodRays,
MetalReflections,
WaterLiquid,
FluidPipes,
VolumetricClouds,
}
pub struct ArtScenes {
pub scene_type: SceneType,
pub metal: MetalType,
pub render_samples: u32,
pub logo_path: String,
}
impl Default for ArtScenes {
fn default() -> Self {
Self {
scene_type: SceneType::GodRays,
metal: MetalType::Chrome,
render_samples: 128,
logo_path: String::new(),
}
}
}
impl ArtScenes {
fn to_json(&self) -> String {
let scene_type = match self.scene_type {
SceneType::GodRays => "god_rays",
SceneType::MetalReflections => "metal_reflections",
SceneType::WaterLiquid => "water_liquid",
SceneType::FluidPipes => "fluid_pipes",
SceneType::VolumetricClouds => "volumetric_clouds",
};
let metal = match self.metal {
MetalType::Gold => "gold",
MetalType::Steel => "steel",
MetalType::Chrome => "chrome",
MetalType::Copper => "copper",
};
let samples = if matches!(self.scene_type, SceneType::VolumetricClouds) {
self.render_samples.max(512)
} else {
self.render_samples
};
let logo = if self.logo_path.is_empty() {
"null".to_string()
} else {
"\"/in/textures/logo.png\"".to_string()
};
format!(
r#"{{"scene_type":"{scene_type}","metal":"{metal}","render_samples":{samples},"output_path":"/out/render.png","logo_path":{logo}}}"#
)
}
}
impl Scene for ArtScenes {
fn name(&self) -> &str {
"Art scenes"
}
fn validate(&self) -> Vec<ValidationStatus> {
let mut v = vec![];
if matches!(self.scene_type, SceneType::VolumetricClouds) && self.render_samples < 512 {
v.push(ValidationStatus::Warning(
"Volume clouds: samples auto-upgraded to 512".into(),
));
}
if self.render_samples == 0 {
v.push(ValidationStatus::Error("Render samples must be > 0".into()));
}
if v.is_empty() {
v.push(ValidationStatus::Ok);
}
v
}
fn show(&mut self, ui: &mut egui::Ui) -> Option<String> {
ui.heading("Art scenes");
ui.separator();
ui.horizontal(|ui| {
ui.label("Scene:");
egui::ComboBox::from_id_salt("scene_type")
.selected_text(format!("{:?}", self.scene_type))
.show_ui(ui, |ui| {
ui.selectable_value(&mut self.scene_type, SceneType::GodRays, "God rays");
ui.selectable_value(&mut self.scene_type, SceneType::MetalReflections, "Metal reflections");
ui.selectable_value(&mut self.scene_type, SceneType::WaterLiquid, "Water / liquid");
ui.selectable_value(&mut self.scene_type, SceneType::FluidPipes, "Fluid pipes");
ui.selectable_value(&mut self.scene_type, SceneType::VolumetricClouds, "Volumetric clouds");
});
});
ui.horizontal(|ui| {
ui.label("Metal:");
egui::ComboBox::from_id_salt("metal_type")
.selected_text(format!("{:?}", self.metal))
.show_ui(ui, |ui| {
ui.selectable_value(&mut self.metal, MetalType::Gold, "Gold");
ui.selectable_value(&mut self.metal, MetalType::Steel, "Steel");
ui.selectable_value(&mut self.metal, MetalType::Chrome, "Chrome");
ui.selectable_value(&mut self.metal, MetalType::Copper, "Copper");
});
});
ui.horizontal(|ui| {
ui.label("Samples:");
ui.add(egui::Slider::new(&mut self.render_samples, 1..=4096));
});
ui.horizontal(|ui| {
ui.label("Logo path:");
ui.text_edit_singleline(&mut self.logo_path);
});
ui.separator();
let statuses = self.validate();
show_validation(ui, &statuses);
ui.separator();
if render_button(ui, self.is_renderable()) {
return Some(self.to_json());
}
None
}
}