Group brush clip history edits

This commit is contained in:
Rbanh 2026-06-06 14:19:35 -04:00
parent 48b1448c57
commit 1b9fbebda1
3 changed files with 75 additions and 9 deletions

View File

@ -112,6 +112,13 @@ pub enum EditorCommand {
old: Option<BrushDesc>,
new: BrushDesc,
},
SetBrushTransform {
entity: Entity,
old_transform: Transform,
new_transform: Transform,
old_brush: Option<BrushDesc>,
new_brush: BrushDesc,
},
SetStaticMeshRenderer {
entity: Entity,
old: Option<StaticMeshRenderer>,
@ -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",

View File

@ -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::<Transform>(entity).copied().unwrap_or_default();
let old_brush = world.get::<BrushDesc>(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::<Transform>(*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());

View File

@ -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::<Transform>(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");
}
}