spline undo fixes #1411

This commit is contained in:
Turánszki János
2025-12-29 13:17:45 +01:00
parent cf3217ebac
commit 49a45745e4
5 changed files with 53 additions and 4 deletions
+14
View File
@@ -5041,6 +5041,7 @@ void EditorComponent::ConsumeHistoryOperation(bool undo)
}
break;
case HISTORYOP_ADD:
case HISTORYOP_ADD_TO_SPLINE:
{
// Read selections states from archive:
@@ -5074,6 +5075,19 @@ void EditorComponent::ConsumeHistoryOperation(bool undo)
selectedAFTER.push_back(sel);
}
if (type == HISTORYOP_ADD_TO_SPLINE)
{
wi::vector<Entity> modifiedSplineEntities;
archive >> modifiedSplineEntities;
EntitySerializer seri;
seri.allow_remap = false;
for (size_t i = 0; i < modifiedSplineEntities.size(); ++i)
{
scene.Entity_Remove(modifiedSplineEntities[i], false); // no recursive!!!
scene.Entity_Serialize(archive, seri, INVALID_ENTITY, wi::scene::Scene::EntitySerializeFlags::KEEP_INTERNAL_ENTITY_REFERENCES); // no recursive!!!
}
}
wi::vector<Entity> addedEntities;
archive >> addedEntities;
+1
View File
@@ -167,6 +167,7 @@ public:
HISTORYOP_DELETE, // entity removed
HISTORYOP_COMPONENT_DATA, // generic component data changed
HISTORYOP_PAINTTOOL, // paint tool interaction
HISTORYOP_ADD_TO_SPLINE, // Spline node added
HISTORYOP_NONE
};
+11
View File
@@ -335,8 +335,19 @@ void SplineWindow::NewNode()
spline->spline_node_transforms.push_back(transform);
scene.Component_Attach(node_entity, entity);
RefreshEntries();
wi::Archive& archive = editor->AdvanceHistory();
archive << EditorComponent::HISTORYOP_ADD_TO_SPLINE;
editor->RecordSelection(archive);
editor->ClearSelected();
editor->AddSelected(node_entity);
editor->RecordSelection(archive);
editor->RecordEntity(archive, entity);
editor->RecordEntity(archive, node_entity);
editor->componentsWnd.RefreshEntityTree();
}
+26 -3
View File
@@ -184,6 +184,7 @@ namespace wi::terrain
wi::jobsystem::context workload;
std::atomic_bool cancelled{ false };
wi::vector<SplineComponent> splines;
wi::vector<wi::ecs::Entity> spline_entities;
wi::vector<Chunk> removable_chunks; // chunks that were invalidated are regenerated on the generator thread. Before merging them with the scene, the previous version of them will need to be removed from the destination scene
std::deque<Chunk> priority_invalidation; // to not let invalidation stuck at same chunks every frame while editing splines, for more appealing visual feedback
};
@@ -928,21 +929,43 @@ namespace wi::terrain
terrain_spline_count_scene++;
}
}
if (terrain_spline_count_scene != generator->splines.size())
// Check mismatches between current and previous slines (removal, undo, etc.)
for (size_t i = 0; i < generator->splines.size(); ++i)
{
// Need to invalidate terrain if spline was removed:
for (const SplineComponent& spline : generator->splines)
const SplineComponent& spline = generator->splines[i];
Entity entity = generator->spline_entities[i];
bool invalidation_required = false;
invalidation_required |= !scene->splines.Contains(entity); // no longer exists in scene, was deleted
if (!invalidation_required)
{
// If spline exists in scene, need to compare for changes:
const SplineComponent& other = *scene->splines.GetComponent(entity);
invalidation_required |= spline.width != other.width;
invalidation_required |= spline.rotation != other.rotation;
invalidation_required |= spline.terrain_modifier_amount != other.terrain_modifier_amount;
invalidation_required |= spline.terrain_pushdown != other.terrain_pushdown;
invalidation_required |= spline.terrain_texture_falloff != other.terrain_texture_falloff;
invalidation_required |= spline.spline_node_transforms.size() != other.spline_node_transforms.size();
if (!invalidation_required)
{
// Last resort compare whole node transform array:
invalidation_required |= std::memcmp(spline.spline_node_transforms.data(), other.spline_node_transforms.data(), spline.spline_node_transforms.size() * sizeof(TransformComponent)) != 0;
}
}
if (invalidation_required)
{
InvalidateChunksAtSpline(spline);
}
}
generator->splines.clear();
generator->spline_entities.clear();
for (size_t i = 0; i < scene->splines.GetCount(); ++i)
{
const SplineComponent& spline = scene->splines[i];
if (spline.terrain_modifier_amount > 0)
{
generator->splines.push_back(spline);
generator->spline_entities.push_back(scene->splines.GetEntity(i));
}
}
wi::jobsystem::Execute(generator->workload, [=](wi::jobsystem::JobArgs a) {
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
const int revision = 869;
const int revision = 870;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);