#include "Scene.h" // Конструктор пустой сцены Scene::Scene() { } // Конструктор копирования Scene::Scene(const Scene ©): root(copy.root), nodes(copy.nodes), models(copy.models), cameras(copy.cameras) { rebuld_tree(copy); } // Оператор присваивания Scene& Scene::operator=(const Scene& other) { root = other.root; nodes = other.nodes; models = other.models; cameras = other.cameras; rebuld_tree(other); return *this; } // Рендер сцены void Scene::render(const GLuint &model_uniform) { for (auto & model : models) model.render(model_uniform); } // Перестройка узлов выбранного списка 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 // Иначе проверяем на принадлежность к камерам if (dynamic_cast(parent)) move_parent(*it, from.cameras, this->cameras); // Иначе это пустой узел 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); rebuild_Nodes_list(cameras, from); }