#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_vector(T& nodes, const Scene& from) { for (int i = 0; i < nodes.size(); i++) { // Берем родителя, который указывает на оригинальный объект Node* parent = nodes[i].getParent(); // Если родитель - оригинальный корневой узел, то меняем на собственный корневой узел if (parent == &from.root) { nodes[i].setParent(&root); continue; } // Если наши родителя - меняем на него if (move_pointer(nodes[i], from.nodes, this->nodes)) continue; if (move_pointer(nodes[i], from.models, models)) continue; // Не нашли родителя - значит он не часть этой сцены // и изменений по нему не требуется } } // Сдвигает родителя узла между двумя списками при условии его принадлежности к оригинальному, возвращает признак замены template bool Scene::move_pointer(Node& for_node, const std::vector& from_nodes, std::vector& this_nodes) { // Определим отступ в памяти std::ptrdiff_t offset = (T*)for_node.getParent() - from_nodes.data(); // Если отступ является частью оригинального списка if (offset >= 0 && offset < from_nodes.size()) { for_node.setParent(this_nodes.data() + offset); // Замена родителя return true; } return false; } // Перестройка дерева после копирования или присваивания void Scene::rebuld_tree(const Scene& from) { // Восстановим родителей в пустых узлах для копии rebuild_Nodes_vector(nodes, from); rebuild_Nodes_vector(models, from); }