feat: Box brush
This commit is contained in:
parent
caa57922bf
commit
4373e671a0
3 changed files with 88 additions and 35 deletions
|
|
@ -15,10 +15,14 @@ impl<'a> GridManipulationTools<'a> {
|
|||
};
|
||||
self.grid.data[index] = element;
|
||||
}
|
||||
pub fn fill_xyz(&mut self,x1: u32, y1: u32, z1: u32, x2: u32, y2: u32, z2: u32, element: GridElement) {
|
||||
if x1 > x2 || y1 > y2 || z1 > z2 {
|
||||
pub fn set_vec(&mut self, vec: UVec3, element: GridElement) {
|
||||
let Some(index) = self.grid.indexify(vec) else {
|
||||
return;
|
||||
}
|
||||
};
|
||||
self.grid.data[index] = element;
|
||||
}
|
||||
pub fn fill_xyz(&mut self,x1: u32, y1: u32, z1: u32, x2: u32, y2: u32, z2: u32, element: GridElement) {
|
||||
let (x1,y1,z1,x2,y2,z2) = (x1.min(x2), y1.min(y2), z1.min(z2), x1.max(x2), y1.max(y2), z1.max(z2));
|
||||
|
||||
for x in x1..=x2 {
|
||||
for y in y1..=y2 {
|
||||
|
|
@ -27,6 +31,21 @@ impl<'a> GridManipulationTools<'a> {
|
|||
continue;
|
||||
};
|
||||
|
||||
self.grid.data[index] = element.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn fill_vec(&mut self,vec1: UVec3, vec2: UVec3, element: GridElement) {
|
||||
let (min_corner, max_corner) = (vec1.min(vec2), vec1.max(vec2));
|
||||
|
||||
for x in min_corner.x..=max_corner.x {
|
||||
for y in min_corner.y..=max_corner.y {
|
||||
for z in min_corner.z..=max_corner.z {
|
||||
let Some(index) = self.grid.indexify(UVec3::new(x,y,z)) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
self.grid.data[index] = element.clone();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ impl Plugin for EditorPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, PartialEq, Eq)]
|
||||
#[derive(Default, PartialEq, Eq)]
|
||||
pub enum Confirmation<T> {
|
||||
#[default]
|
||||
None,
|
||||
|
|
@ -23,6 +23,32 @@ pub enum Confirmation<T> {
|
|||
Confirmed(T)
|
||||
}
|
||||
|
||||
impl<T: Clone> Confirmation<T> {
|
||||
pub fn from_option(option: &Option<T>) -> Self {
|
||||
match option {
|
||||
Some(item) => Confirmation::Suggestion(item.clone()),
|
||||
None => Confirmation::None,
|
||||
}
|
||||
}
|
||||
pub fn to_option(&self) -> Option<T> {
|
||||
match self {
|
||||
Confirmation::None => None,
|
||||
Confirmation::Suggestion(item) => Some(item.clone()),
|
||||
Confirmation::Confirmed(item) => Some(item.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> Clone for Confirmation<T> {
|
||||
fn clone(&self) -> Self {
|
||||
match self {
|
||||
Self::None => Self::None,
|
||||
Self::Suggestion(arg0) => Self::Suggestion(arg0.clone()),
|
||||
Self::Confirmed(arg0) => Self::Confirmed(arg0.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, PartialEq, Eq,Resource)]
|
||||
pub struct EditorTool {
|
||||
pub block: GridElement,
|
||||
|
|
@ -34,14 +60,16 @@ pub enum ToolType {
|
|||
#[default]
|
||||
None,
|
||||
Paint{ position: Option<UVec3> },
|
||||
//Box { first_corner: Confirmation<UVec3>, second_corner: Option<UVec3> }
|
||||
Box { first_corner: Confirmation<UVec3>, second_corner: Option<UVec3> }
|
||||
}
|
||||
|
||||
|
||||
impl Display for ToolType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f,"{}",match self {
|
||||
ToolType::None => "None",
|
||||
ToolType::Paint { position: _ } => "Paint"
|
||||
ToolType::Paint { position: _ } => "Paint",
|
||||
ToolType::Box { first_corner: _, second_corner: _ } => "Box",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -51,15 +79,8 @@ impl Display for ToolType {
|
|||
pub struct ViewCube;
|
||||
|
||||
#[derive(Event)]
|
||||
pub struct ApplyTool{
|
||||
pub tool: EditorTool
|
||||
}
|
||||
pub struct ApplyTool;
|
||||
|
||||
impl ApplyTool {
|
||||
pub fn new(tool: EditorTool) -> Self {
|
||||
Self { tool }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn calculate_tools(
|
||||
mut commands: Commands,
|
||||
|
|
@ -69,38 +90,50 @@ pub fn calculate_tools(
|
|||
mut tool: ResMut<EditorTool>,
|
||||
grid: Res<Grid>
|
||||
) {
|
||||
let tool_change: ToolType = match tool.kind {
|
||||
// Calculating tile cursor tile placement
|
||||
let mut cursor_position: Option<UVec3> = None;
|
||||
|
||||
for (_, ray) in ray_map.iter() {
|
||||
let Some((_, hit)) = raycast.cast_ray(*ray, &MeshRayCastSettings::default()).first() else {continue;};
|
||||
|
||||
let placement_position = if let GridElement::Air = tool.block { hit.point - 0.51 * hit.normal.normalize() } else { hit.point + 0.51 * hit.normal.normalize() }.round();
|
||||
|
||||
cursor_position = Some(placement_position.as_ivec3().max(IVec3::ZERO).as_uvec3().min(grid.size-UVec3::ONE));
|
||||
}
|
||||
|
||||
let tool_change: ToolType = match tool.kind.clone() {
|
||||
ToolType::None => ToolType::None,
|
||||
ToolType::Paint { position: _ } => {
|
||||
let mut new_position: Option<UVec3> = None;
|
||||
|
||||
for (_, ray) in ray_map.iter() {
|
||||
let Some((_, hit)) = raycast.cast_ray(*ray, &MeshRayCastSettings::default()).first() else {continue;};
|
||||
|
||||
let placement_position = if let GridElement::Air = tool.block { hit.point - 0.51 * hit.normal.normalize() } else { hit.point + 0.51 * hit.normal.normalize() }.round();
|
||||
|
||||
new_position = Some(placement_position.as_ivec3().max(IVec3::ZERO).as_uvec3().min(grid.size-UVec3::ONE));
|
||||
ToolType::Paint { position: _ } => ToolType::Paint { position: cursor_position },
|
||||
ToolType::Box { first_corner, second_corner: _ } => {
|
||||
if let Confirmation::Confirmed(_) = first_corner {
|
||||
ToolType::Box { first_corner, second_corner: cursor_position }
|
||||
} else {
|
||||
ToolType::Box { first_corner: Confirmation::from_option(&cursor_position), second_corner: None }
|
||||
}
|
||||
|
||||
ToolType::Paint { position: new_position }
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
tool.kind = tool_change;
|
||||
|
||||
|
||||
if mouse_button.just_pressed(MouseButton::Left) {
|
||||
commands.trigger(ApplyTool::new(tool.clone()));
|
||||
commands.trigger(ApplyTool);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_tool(params: On<ApplyTool>, mut grid: ResMut<Grid>) {
|
||||
match params.tool.kind {
|
||||
ToolType::None => {},
|
||||
ToolType::Paint { position } => {
|
||||
let Some(position) = position else { return; };
|
||||
let index = grid.indexify(position).unwrap();
|
||||
grid.data[index] = params.tool.block;
|
||||
pub fn apply_tool(_params: On<ApplyTool>, mut grid: ResMut<Grid>, mut tool: ResMut<EditorTool>) {
|
||||
let mut editor = grid.manipulate();
|
||||
match tool.kind {
|
||||
ToolType::Paint { position: Some(position) } => {
|
||||
editor.set_vec(position, tool.block);
|
||||
},
|
||||
ToolType::Box { first_corner: Confirmation::Suggestion(first_corner), second_corner } => {
|
||||
tool.kind = ToolType::Box { first_corner: Confirmation::Confirmed(first_corner), second_corner: second_corner };
|
||||
},
|
||||
ToolType::Box { first_corner: Confirmation::Confirmed(first_corner), second_corner: Some(second_corner) } => {
|
||||
editor.fill_vec(first_corner, second_corner, tool.block);
|
||||
tool.kind = ToolType::Box { first_corner: Confirmation::None, second_corner: None };
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use bevy::prelude::*;
|
|||
use crate::MAX_FLUID_AMOUNT;
|
||||
use crate::grid::{Grid, GridElement};
|
||||
use crate::simulation::SimulationStatus;
|
||||
use crate::view::editor::{EditorTool,ToolType};
|
||||
use crate::view::editor::{EditorTool,ToolType,Confirmation};
|
||||
|
||||
pub struct UIPlugin;
|
||||
|
||||
|
|
@ -105,7 +105,8 @@ fn editor_tools_column() -> impl Scene {
|
|||
label("Tools")
|
||||
ToolLabel,
|
||||
tool_button(ToolType::None),
|
||||
tool_button(ToolType::Paint{position: None})
|
||||
tool_button(ToolType::Paint{position: None}),
|
||||
tool_button(ToolType::Box { first_corner: Confirmation::None, second_corner: None })
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue