diff --git a/src/vvedit/editor_bevy_input_shim.rs b/src/vvedit/editor_bevy_input_shim.rs index ed49515..a66d347 100644 --- a/src/vvedit/editor_bevy_input_shim.rs +++ b/src/vvedit/editor_bevy_input_shim.rs @@ -1,9 +1,12 @@ use crate::vvlib::inputs::{BinaryInputBinding, BinaryInputID, InputRegister, InputRegisterPlugin}; use bevy::prelude::*; +use super::editor_ui::edit_click_events; + pub fn setup_inputs(app: &mut bevy::app::App) -> &mut bevy::app::App { app.add_plugins(InputRegisterPlugin); - app.add_systems(Startup, initiate_default_or_load_controls) + app.add_systems(Startup, initiate_default_or_load_controls); + app.add_systems(Update, edit_click_events) } pub mod keybind_codes { diff --git a/src/vvedit/editor_ui.rs b/src/vvedit/editor_ui.rs index f6a88db..75b2ae5 100644 --- a/src/vvedit/editor_ui.rs +++ b/src/vvedit/editor_ui.rs @@ -1,14 +1,20 @@ use bevy::{ app::{Startup, Update}, asset::Assets, - ecs::system::{Commands, ResMut, Resource}, + ecs::system::{Commands, Query, ResMut, Resource}, math::Vec3, - render::color::Color, + 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, + 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}, @@ -37,12 +43,121 @@ pub fn startup_system_edit_ui(commands: Commands) { #[derive(Default, Resource)] pub struct EditWindowUIState {} +pub fn edit_click_events( + input_data: ResMut, + camera_query: Query<(&Camera, &GlobalTransform)>, + oct_tree: Query<(&GlobalTransform, &OctAssetMarker)>, + windows: Query<&Window>, + mut oct_assets: ResMut>, +) { + 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, mut contexts: EguiContexts, mut oct_assets: ResMut>, mut pairs: ResMut, - input_data: ResMut, ) { egui::Window::new("VVEdit").show(contexts.ctx_mut(), |ui| { let mut label = String::from("Pre-Alpha"); @@ -65,19 +180,5 @@ pub fn edit_window_ui( } } } - // click processing - 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()); - if let Some(_input) = paint.filter(|input| input.pressed()) { - // - println!("paint input!"); - } else if let Some(_input) = remove.filter(|input| input.pressed()) { - // - println!("remove input!"); - } else if let Some(_input) = insert.filter(|input| input.pressed()) { - // - println!("insert input!"); - } }); } diff --git a/src/vvlib/intersections.rs b/src/vvlib/intersections.rs index 748a814..aa82fe3 100644 --- a/src/vvlib/intersections.rs +++ b/src/vvlib/intersections.rs @@ -15,8 +15,8 @@ use super::{ #[derive(Debug, Copy, Clone, PartialEq)] pub struct VectorPair { - global: Vec3, - local: Vec3, + pub global: Vec3, + pub local: Vec3, } impl VectorPair { pub fn new(global: Vec3, local: Vec3) -> VectorPair { @@ -49,9 +49,9 @@ pub struct OctTreeCollisionPoint { #[derive(Clone, Debug)] pub struct RayOctTreeIntersection { - pub(crate) hit_data: RayOBBIntersection, - pub(crate) path_to_hit: Path, - pub(crate) voxel_index_location: Vec3, + pub hit_data: RayOBBIntersection, + pub path_to_hit: Path, + pub voxel_index_location: Vec3, } pub fn octtree_overlap( @@ -256,8 +256,8 @@ pub fn sphere_sphere_overlap( #[derive(Debug, Clone)] pub struct RayOBBIntersection { - hitpoint: VectorPair, - normal: VectorPair, + pub hitpoint: VectorPair, + pub normal: VectorPair, } impl RayOBBIntersection { pub fn new(hitpoint: VectorPair, normal: VectorPair) -> RayOBBIntersection { diff --git a/src/vvlib/obb.rs b/src/vvlib/obb.rs index 57166fd..e2e66a6 100644 --- a/src/vvlib/obb.rs +++ b/src/vvlib/obb.rs @@ -32,4 +32,11 @@ impl OBB { .with_rotation(self.orientation) .with_scale(self.half_size * 2.) } + pub fn from_transform(trans: Transform) -> OBB { + OBB { + position: trans.translation, + orientation: trans.rotation, + half_size: trans.scale / 2., + } + } }