diff --git a/crates/editor/src/history/commands.rs b/crates/editor/src/history/commands.rs index e98d98d..c927138 100644 --- a/crates/editor/src/history/commands.rs +++ b/crates/editor/src/history/commands.rs @@ -112,6 +112,13 @@ pub enum EditorCommand { old: Option, new: BrushDesc, }, + SetBrushTransform { + entity: Entity, + old_transform: Transform, + new_transform: Transform, + old_brush: Option, + new_brush: BrushDesc, + }, SetStaticMeshRenderer { entity: Entity, old: Option, @@ -177,6 +184,7 @@ impl EditorCommand { EditorCommand::SetCollider { .. } => "Set Collider", EditorCommand::SetPrimitive { .. } => "Set Primitive", EditorCommand::SetBrush { .. } => "Set Brush", + EditorCommand::SetBrushTransform { .. } => "Clip Brush", EditorCommand::SetStaticMeshRenderer { .. } => "Set Static Mesh Renderer", EditorCommand::SetPostProcessVolume { .. } => "Set Post Process Volume", EditorCommand::SetTransformGroup { .. } => "Move Selection", diff --git a/crates/editor/src/history/mod.rs b/crates/editor/src/history/mod.rs index 5d42e4d..10820d0 100644 --- a/crates/editor/src/history/mod.rs +++ b/crates/editor/src/history/mod.rs @@ -499,6 +499,36 @@ pub fn set_brush_with_history(world: &mut World, entity: Entity, new: BrushDesc) push_history(world, EditorCommand::SetBrush { entity, old, new }); } +pub fn set_brush_transform_with_history( + world: &mut World, + entity: Entity, + new_transform: Transform, + new_brush: BrushDesc, +) { + if !is_level_object(world, entity) { + return; + } + let old_transform = world.get::(entity).copied().unwrap_or_default(); + let old_brush = world.get::(entity).cloned(); + if old_transform == new_transform && old_brush.as_ref() == Some(&new_brush) { + return; + } + if let Ok(mut entity_mut) = world.get_entity_mut(entity) { + entity_mut.insert(new_transform); + entity_mut.insert(new_brush.clone()); + } + push_history( + world, + EditorCommand::SetBrushTransform { + entity, + old_transform, + new_transform, + old_brush, + new_brush, + }, + ); +} + pub fn set_static_mesh_renderer_with_history( world: &mut World, entity: Entity, @@ -834,6 +864,17 @@ fn undo_command(world: &mut World, command: &mut EditorCommand) { EditorCommand::SetBrush { entity, old, .. } => { apply_brush(world, *entity, old); } + EditorCommand::SetBrushTransform { + entity, + old_transform, + old_brush, + .. + } => { + if let Some(mut transform) = world.get_mut::(*entity) { + *transform = *old_transform; + } + apply_brush(world, *entity, old_brush); + } EditorCommand::SetStaticMeshRenderer { entity, old, .. } => { apply_static_mesh_renderer(world, *entity, old); } @@ -962,6 +1003,17 @@ fn redo_command(world: &mut World, command: &mut EditorCommand) { entity_mut.insert(new.clone()); } } + EditorCommand::SetBrushTransform { + entity, + new_transform, + new_brush, + .. + } => { + if let Ok(mut entity_mut) = world.get_entity_mut(*entity) { + entity_mut.insert(*new_transform); + entity_mut.insert(new_brush.clone()); + } + } EditorCommand::SetStaticMeshRenderer { entity, new, .. } => { if let Ok(mut entity_mut) = world.get_entity_mut(*entity) { entity_mut.insert(new.clone()); diff --git a/crates/editor/src/viewport/brush_edit.rs b/crates/editor/src/viewport/brush_edit.rs index a9dbb9f..55a27e5 100644 --- a/crates/editor/src/viewport/brush_edit.rs +++ b/crates/editor/src/viewport/brush_edit.rs @@ -8,9 +8,7 @@ use shared::{ }; use crate::camera::EditorCamera; -use crate::history::{ - push_command, set_brush_with_history, set_transform_with_history, EditorCommand, -}; +use crate::history::{push_command, set_brush_transform_with_history, EditorCommand}; use crate::operators::{ActiveOperator, OperatorPhase, OperatorStatus}; use crate::scene_io::SceneIo; use crate::selection::ViewportClick; @@ -381,12 +379,7 @@ fn brush_clip_commit( }; scene_io.status = "Brush clip committed".into(); commands.queue(move |world: &mut World| { - let old_transform = world - .get::(brush_entity) - .copied() - .unwrap_or_default(); - set_transform_with_history(world, brush_entity, old_transform, result.transform); - set_brush_with_history(world, brush_entity, result.brush); + set_brush_transform_with_history(world, brush_entity, result.transform, result.brush); }); } @@ -1031,4 +1024,17 @@ mod tests { assert_eq!(result.transform.translation, Vec3::new(0.25, 0.0, 0.0)); assert!(validate_brush(&result.brush).is_valid()); } + + #[test] + fn clip_history_command_is_grouped() { + let command = EditorCommand::SetBrushTransform { + entity: Entity::PLACEHOLDER, + old_transform: Transform::default(), + new_transform: Transform::from_translation(Vec3::X), + old_brush: Some(BrushDesc::default()), + new_brush: BrushDesc::default(), + }; + + assert_eq!(command.label(), "Clip Brush"); + } }