17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 02:49:19 +02:00

feat(editor): nodes placed with the brush and the area fill go without names; name of a model instance set in the node properties and written to its definition on save; redo of a deletion finds nodes which have no name

This commit is contained in:
2026-10-06 21:58:57 +02:00
parent 90c5420396
commit c4a22eabd5
9 changed files with 166 additions and 11 deletions

View File

@@ -129,6 +129,7 @@ void node_layers::clear()
m_context = layer_context();
m_sources.clear();
m_erased.clear();
m_renamed.clear();
m_shapes.clear();
m_shapeserased = false;
m_templates.clear();
@@ -475,6 +476,17 @@ void node_layers::forget(basic_node const *Node)
}
m_erased.emplace_back(lookup->second.layer, lookup->second.span);
m_sources.erase(lookup);
m_renamed.erase(Node);
}
// indicates specified node was given another name in the editor
void node_layers::renamed(basic_node const *Node)
{
// NOTE: a node which isn't defined by a scenery file yet is written whole on save, along with its name
if (m_sources.find(Node) != m_sources.end())
{
m_renamed.emplace(Node);
}
}
void node_layers::shape(material_handle const Material, source_span const &Span)

View File

@@ -259,6 +259,8 @@ class node_layers
void track(basic_node const *Node, source_span const &Span, glm::vec3 const &Angles = glm::vec3{0.f}, glm::vec3 const &Scale = glm::vec3{1.f});
// indicates specified node was removed from the scene
void forget(basic_node const *Node);
// indicates specified node was given another name in the editor, for its definition to get it on save
void renamed(basic_node const *Node);
// stores location of a shape defined directly in the layer file being loaded
void shape(material_handle const Material, source_span const &Span);
std::vector<shape_source> const &shapes() const
@@ -373,6 +375,7 @@ class node_layers
layer_context m_context; // placement in effect at the current point of scenery load
std::unordered_map<basic_node const *, node_source> m_sources; // origins of nodes which can be rewritten on save
std::vector<std::pair<layer_handle, source_span>> m_erased; // definitions of nodes deleted since the load or the last save
std::unordered_set<basic_node const *> m_renamed; // nodes given another name since the load or the last save
std::vector<shape_source> m_shapes;
bool m_shapeserased{false}; // the binary terrain file holds shapes which the save drops
std::set<std::string> m_templates; // *.inc templates used by the scenery

View File

@@ -134,6 +134,7 @@ struct model_placement
std::optional<glm::vec3> angles; // complete rotation of the instance
glm::vec3 rotation{0.f}; // rotation the loader adds to the angle specified in the definition
std::optional<glm::vec3> scale; // scale factor to put in the definition
std::optional<std::string> name; // name of the node
};
bool about_equal(float const Left, float const Right)
@@ -166,6 +167,10 @@ bool patch_model(std::string &Text, model_placement const &Placement, std::strin
};
std::string additions; // blocks to insert ahead of the closing keyword
if (Placement.name)
{
replace(3, *Placement.name);
}
if (Placement.location)
{
replace(5, number(Placement.location->x));
@@ -693,7 +698,8 @@ save_result node_layers::save(std::vector<std::string> const &Rootstatements)
auto const moved{glm::distance(location, source.location) > 1e-4};
auto const rotated{false == glm::all(glm::epsilonEqual(angles, source.angles, 1e-3f))};
auto const scaled{false == glm::all(glm::epsilonEqual(scale, source.scale, 1e-4f))};
if (false == (moved || rotated || scaled))
auto const renamed{Model != nullptr && m_renamed.find(Node) != m_renamed.end()};
if (false == (moved || rotated || scaled || renamed))
{
return true;
}
@@ -725,6 +731,10 @@ save_result node_layers::save(std::vector<std::string> const &Rootstatements)
{
placement.scale = scale / source.context.scale;
}
if (renamed)
{
placement.name = (Node->name().empty() ? "none" : Node->name());
}
patched = patch_model(text, placement, error);
}
else
@@ -1614,6 +1624,7 @@ save_result node_layers::save(std::vector<std::string> const &Rootstatements)
included.dead = included.dead || included.removed;
}
m_erased.clear();
m_renamed.clear();
// the shapes of the rewritten files are somewhere else in them now
m_shapes.erase(std::remove_if(std::begin(m_shapes), std::end(m_shapes), [&](shape_source const &Shape) { return std::find(std::begin(composed), std::end(composed), Shape.layer) != std::end(composed); }), std::end(m_shapes));
for (auto *path : savedpaths)