vixevoxerust/src/vvedit/editor_ui.rs

185 lines
7.1 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, Transform},
window::Window,
};
use bevy_egui::{egui, EguiContexts, EguiPlugin};
use crate::{
vvedit::editor_bevy_input_shim::keybind_codes::REMOVE_VOXEL,
vvlib::{
inputs::InputRegister, intersections::octtree_ray_overlap, obb::OBB,
oct_asset::OctAssetMarker, octtree,
},
};
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());
// preprep done
if let Some(_) = paint.filter(|input| input.pressed()) {
for window in &windows {
for (trans, oct) in &oct_tree {
for (camera, cam_trans) in &camera_query {
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 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.5);
edit_octtree.set_voxel_at_location(hitvox.round(), Color::PINK);
}
}
}
}
} else if let Some(_) = remove.filter(|input| input.pressed()) {
for window in &windows {
for (trans, oct) in &oct_tree {
for (camera, cam_trans) in &camera_query {
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 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.5);
edit_octtree.remove_voxel(hitvox.round());
}
}
}
}
} else if let Some(_) = insert.filter(|input| input.pressed()) {
for window in &windows {
for (trans, oct) in &oct_tree {
for (camera, cam_trans) in &camera_query {
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 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.5);
edit_octtree.set_voxel_at_location(hitvox.round(), Color::PINK);
}
}
}
}
}
}
pub fn edit_window_ui(
mut _shared_ui_state: ResMut<EditWindowUIState>,
mut contexts: EguiContexts,
mut oct_assets: ResMut<Assets<OctTreeAsset>>,
mut pairs: ResMut<MeshingOctTreePairs>,
) {
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();
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);
}
}
}
});
}