139 lines
5 KiB
Rust
139 lines
5 KiB
Rust
use bevy::{
|
|
app::{Startup, Update},
|
|
asset::Assets,
|
|
ecs::system::{Commands, Query, ResMut, Resource},
|
|
math::Vec3,
|
|
render::{camera::Camera, color::Color},
|
|
transform::components::GlobalTransform,
|
|
window::Window,
|
|
};
|
|
use bevy_egui::{
|
|
egui::{self, color_picker, Color32},
|
|
EguiContexts, EguiPlugin,
|
|
};
|
|
use rand::Rng;
|
|
|
|
use crate::{
|
|
vvedit::editor_bevy_input_shim::keybind_codes::REMOVE_VOXEL,
|
|
vvlib::{
|
|
inputs::InputRegister, intersections::octtree_ray_overlap, obb::OBB,
|
|
oct_asset::OctAssetMarker,
|
|
},
|
|
};
|
|
use crate::{
|
|
vvedit::editor_bevy_input_shim::keybind_codes::{INSERT_VOXEL, PAINT_VOXEL},
|
|
vvlib::oct_asset::{MeshingOctTreePairs, OctTreeAsset},
|
|
};
|
|
|
|
use super::{
|
|
editor_bevy_input_shim::setup_inputs,
|
|
orbit_camera::orbit_camera::{pan_orbit_camera, spawn_camera},
|
|
};
|
|
|
|
pub fn register_edit_ui(app: &mut bevy::prelude::App) -> &mut bevy::prelude::App {
|
|
app.insert_resource(EditWindowUIState {});
|
|
app.add_plugins(EguiPlugin);
|
|
app.add_systems(Startup, startup_system_edit_ui);
|
|
app.add_systems(Update, edit_window_ui);
|
|
app.add_systems(Update, pan_orbit_camera);
|
|
setup_inputs(app);
|
|
app
|
|
}
|
|
|
|
pub fn startup_system_edit_ui(commands: Commands) {
|
|
spawn_camera(commands);
|
|
}
|
|
|
|
#[derive(Default, Resource)]
|
|
pub struct EditWindowUIState {}
|
|
|
|
pub fn edit_click_events(
|
|
input_data: ResMut<InputRegister>,
|
|
camera_query: Query<(&Camera, &GlobalTransform)>,
|
|
oct_tree: Query<(&GlobalTransform, &OctAssetMarker)>,
|
|
windows: Query<&Window>,
|
|
mut oct_assets: ResMut<Assets<OctTreeAsset>>,
|
|
) {
|
|
let paint = input_data.get_binary_input(&PAINT_VOXEL.into());
|
|
let remove = input_data.get_binary_input(&REMOVE_VOXEL.into());
|
|
let insert = input_data.get_binary_input(&INSERT_VOXEL.into());
|
|
for window in &windows {
|
|
for (trans, oct) in &oct_tree {
|
|
for (camera, cam_trans) in &camera_query {
|
|
let mut rng = rand::thread_rng();
|
|
let r: f32 = rng.gen_range(0.0..1.0);
|
|
let g: f32 = rng.gen_range(0.0..1.0);
|
|
let b: f32 = rng.gen_range(0.0..1.0);
|
|
let Some(cursor_pos) = window.cursor_position() else {
|
|
continue;
|
|
};
|
|
let Some(ray) = camera.viewport_to_world(cam_trans, cursor_pos) else {
|
|
continue;
|
|
};
|
|
let obb = OBB::from_transform(trans.compute_transform());
|
|
let octtree = oct_assets.get_mut(oct.oct_handle.clone());
|
|
if octtree.is_none() {
|
|
continue;
|
|
}
|
|
let edit_octtree = &mut octtree.unwrap().model;
|
|
let collision =
|
|
octtree_ray_overlap(edit_octtree, &obb, ray.origin, ray.direction.normalize());
|
|
|
|
if let Some(_) = paint.filter(|input| input.pressed()) {
|
|
if collision.is_some() {
|
|
let col = collision.unwrap();
|
|
edit_octtree
|
|
.set_voxel_at_location(col.voxel_index_location, Color::rgb(r, g, b));
|
|
}
|
|
} else if let Some(_) = remove.filter(|input| input.pressed()) {
|
|
if collision.is_some() {
|
|
let col = collision.unwrap();
|
|
|
|
edit_octtree.remove_voxel(col.voxel_index_location);
|
|
}
|
|
} else if let Some(_) = insert.filter(|input| input.pressed()) {
|
|
if collision.is_some() {
|
|
let col = collision.unwrap();
|
|
let hitloc = col.hit_data.hitpoint.local.clone();
|
|
let hitnorm = col.hit_data.normal.local.clone();
|
|
let hitvox = hitloc + (hitnorm * 0.25);
|
|
edit_octtree.set_voxel_at_location(hitvox.round(), Color::rgb(r, g, b));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn edit_window_ui(
|
|
mut _shared_ui_state: ResMut<EditWindowUIState>,
|
|
mut contexts: EguiContexts,
|
|
mut oct_assets: ResMut<Assets<OctTreeAsset>>,
|
|
mut pairs: ResMut<MeshingOctTreePairs>,
|
|
) {
|
|
let mut color: Color32 = Default::default();
|
|
egui::Window::new("VVEdit").show(contexts.ctx_mut(), |ui| {
|
|
let mut label = String::from("Pre-Alpha");
|
|
use std::fmt::Write;
|
|
writeln!(label, " Controls:").ok();
|
|
writeln!(label, "click adds a voxel:").ok();
|
|
writeln!(label, "R+click removes a voxel:").ok();
|
|
writeln!(label, "E+click paints (edits) a voxel:").ok();
|
|
|
|
color_picker::color_picker_color32(ui, &mut color, color_picker::Alpha::Opaque);
|
|
ui.label(label);
|
|
if ui.button("Add Origin Voxel").clicked() {
|
|
//
|
|
for pair in &mut pairs.handles {
|
|
let id = pair.oct_handle.clone();
|
|
let tree = oct_assets.get_mut(id);
|
|
if tree.is_some() {
|
|
//
|
|
let tree = tree.unwrap();
|
|
tree.model.set_voxel_at_location(Vec3::ZERO, Color::BLUE);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|