From d1ec60c285322ea46fab963df0663c78273fc301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D0=BE=D0=BC=D0=B0=D0=BD=20=D0=95=D0=B2=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D1=8C=D0=B5=D0=B2=D0=B8=D1=87=20=D0=9A=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BB=D0=B5=D0=B2?= Date: Tue, 17 Oct 2023 02:17:33 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9A=D0=BB=D0=B0=D1=81=D1=81=20=D1=81=D1=86?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/Scene.h | 32 +++++++++++++++++++ src/Scene.cpp | 83 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 include/Scene.h create mode 100644 src/Scene.cpp diff --git a/include/Scene.h b/include/Scene.h new file mode 100644 index 0000000..4aada7f --- /dev/null +++ b/include/Scene.h @@ -0,0 +1,32 @@ +#ifndef SCENE_H +#define SCENE_H + +#include + +#include "Model.h" + +// Класс сцены +class Scene +{ + public: + Scene(); // Конструктор пустой сцены + Scene(const Scene ©); // Конструктор копирования + Scene& operator=(const Scene& other); // Оператор присваивания + + void render(); // Рендер сцены + + Node root; // Корневой узел + + // Списки объектов, выступающих узлами + std::list nodes; // Список пустых узлов + std::list models; // Список моделей для рендера + + protected: + void rebuld_tree(const Scene& from); // Перестройка дерева после копирования или присваивания + template + void rebuild_Nodes_list(T& nodes, const Scene& from); // Перестройка узлов выбранного списка + template + void move_parent(Node& for_node, const std::list& from_nodes, std::list& this_nodes); // Сдвигает родителя узла между двумя списками при условии его принадлежности к оригинальному +}; + +#endif // SCENE_H diff --git a/src/Scene.cpp b/src/Scene.cpp new file mode 100644 index 0000000..c03dbde --- /dev/null +++ b/src/Scene.cpp @@ -0,0 +1,83 @@ +#include "Scene.h" + +// Конструктор пустой сцены +Scene::Scene() +{ + +} + +// Конструктор копирования +Scene::Scene(const Scene ©): root(copy.root), +nodes(copy.nodes), models(copy.models) +{ + rebuld_tree(copy); +} + +// Оператор присваивания +Scene& Scene::operator=(const Scene& other) +{ + root = other.root; + nodes = other.nodes; + models = other.models; + + rebuld_tree(other); + + return *this; +} + +// Рендер сцены +void Scene::render() +{ + for (auto & model : models) + model.render(); +} + +// Перестройка узлов выбранного списка +template +void Scene::rebuild_Nodes_list(T& nodes, const Scene& from) +{ + for (auto it = nodes.begin(); it != nodes.end(); it++) + { + // Берем родителя, который указывает на оригинальный объект + Node* parent = it->getParent(); + + // Если родитель - оригинальный корневой узел, то меняем на собственный корневой узел + if (parent == &from.root) + { + it->setParent(&root); + continue; + } + + // Если можно привести к модели, то ищем родителя среди моделей + if (dynamic_cast(parent)) + move_parent(*it, from.models, this->models); + // Иначе это пустой узел + else + move_parent(*it, from.nodes, this->nodes); + + // Не нашли родителя - значит он не часть этой сцены + // и изменений по нему не требуется + } +} + +// Сдвигает родителя узла между двумя списками при условии его принадлежности к оригинальному +template +void Scene::move_parent(Node& for_node, const std::list& from_nodes, std::list& this_nodes) +{ + // Возьмем адрес родителя + Node* parent = for_node.getParent(); + // Цикл по элементам списков для перемещения родителя + // Списки в процессе копирования идеинтичные, вторая проверка не требуется + for (auto it_from = from_nodes.begin(), it_this = this_nodes.begin(); it_from != from_nodes.end(); ++it_from, ++it_this) + // Если адрес объекта, на который указывает итератор, совпадает с родителем - меняем родителя по второму итератору (it_this) + if (&(*it_from) == parent) + for_node.setParent(&(*it_this)); +} + +// Перестройка дерева после копирования или присваивания +void Scene::rebuld_tree(const Scene& from) +{ + // Восстановим родителей в пустых узлах для копии + rebuild_Nodes_list(nodes, from); + rebuild_Nodes_list(models, from); +}