diff --git a/openVulkanoCpp/Scene/Drawable.cpp b/openVulkanoCpp/Scene/Drawable.cpp index 214d945..5c9d111 100644 --- a/openVulkanoCpp/Scene/Drawable.cpp +++ b/openVulkanoCpp/Scene/Drawable.cpp @@ -1,3 +1,9 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + #include "Drawable.hpp" #include "Scene.hpp" @@ -9,8 +15,10 @@ namespace openVulkanoCpp { if (this->scene == scene) return; if (scene && this->scene) throw std::runtime_error("Drawable has been associated with a scene already!"); + const auto oldScene = this->scene; this->scene = scene; if(scene) scene->RegisterDrawable(this); + else if (oldScene) oldScene->RemoveDrawable(this); } void Drawable::RemoveNode(Node* node) diff --git a/openVulkanoCpp/Scene/Node.cpp b/openVulkanoCpp/Scene/Node.cpp index 96c7158..83c3b17 100644 --- a/openVulkanoCpp/Scene/Node.cpp +++ b/openVulkanoCpp/Scene/Node.cpp @@ -1,9 +1,124 @@ -#include "Node.hpp" +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -namespace openVulkanoCpp +#include "Node.hpp" +#include "../Base/Utils.hpp" +#include + +namespace openVulkanoCpp::Scene { - namespace Scene + Node::Node() + : localMat(1), worldMat(1) + {} + + Node::~Node() noexcept { - const glm::mat4x4 Node::IDENTITY = glm::mat4(1); + if (parent || scene || !children.empty() || !drawables.empty()) + { + Node::Close(); + } + } + + void Node::Init() + { + if (parent || scene || !children.empty() || !drawables.empty()) throw std::runtime_error("Node already initialized"); + localMat = worldMat = glm::mat4x4(1); + enabled = true; + } + + void Node::Close() + { + children.clear(); + if (renderNode) renderNode->Close(); + parent = nullptr; + scene = nullptr; + enabled = false; + if (!children.empty()) Logger::SCENE->warn("Closing Node that has children!"); + for (Node* child : children) + { + child->SetParent(nullptr); + } + children.clear(); + for(Drawable* drawable : drawables) + { + drawable->RemoveNode(this); + } + drawables.clear(); + } + + void Node::AddChild(Node* node) + { + node->SetParent(this); + children.push_back(node); + node->UpdateWorldMatrix(worldMat); + } + + void Node::RemoveChild(Node* node) + { + if (node->parent == this) + { + Utils::Remove(children, node); + node->SetParent(nullptr); + } + } + + void Node::AddDrawable(Drawable* drawable) + { + if (scene) drawable->SetScene(scene); + else if (drawable->GetScene()) Logger::SCENE->warn("Drawable is already associated with a scene, but the node it was added to is not!"); + drawable->AddNode(this); + drawables.push_back(drawable); + } + + void Node::RemoveDrawable(Drawable* drawable) + { + drawable->RemoveNode(this); + Utils::Remove(drawables, drawable); + } + + void Node::SetMatrix(glm::mat4x4 mat) + { + localMat = mat; + UpdateWorldMatrix(parent ? parent->GetWorldMatrix() : glm::mat4x4(1)); + } + + void Node::UpdateWorldMatrix(const glm::mat4x4& parentWorldMat) + { + worldMat = parentWorldMat * localMat; + for (const auto& node : children) + { + node->UpdateWorldMatrix(worldMat); + } + } + + void Node::SetParent(Node* parent) + { + if (this->parent && parent) throw std::runtime_error("Node already has a parent! Nodes must not be used multiple times!"); + this->parent = parent; + if(parent && parent != this) this->scene = parent->scene; + if (!parent) SetScene(nullptr); + } + + void Node::SetScene(Scene* scene) + { + if (this->scene && scene) throw std::runtime_error("Node already has a scene!"); + this->scene = scene; + for (const auto& node : children) + { + node->SetScene(scene); + } + for (auto& drawable : drawables) + { + Scene* drawableScene = drawable->GetScene(); + if(drawableScene && drawableScene != scene) + { + Logger::SCENE->warn("Drawable is already associated with a scene! Creating copy."); + drawable = drawable->Copy(); + } + drawable->SetScene(scene); + } } } \ No newline at end of file diff --git a/openVulkanoCpp/Scene/Node.hpp b/openVulkanoCpp/Scene/Node.hpp index fe1dd42..7515d9e 100644 --- a/openVulkanoCpp/Scene/Node.hpp +++ b/openVulkanoCpp/Scene/Node.hpp @@ -1,9 +1,13 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + #pragma once + #include -#include #include -#include "../Base/Utils.hpp" -#include "../Base/IInitable.hpp" #include "../Base/ICloseable.hpp" #include "Drawable.hpp" @@ -21,8 +25,7 @@ namespace openVulkanoCpp struct Node : virtual IInitable, virtual ICloseable { friend Scene; - protected: - static const glm::mat4x4 IDENTITY; + public: glm::mat4x4 localMat, worldMat; bool enabled = true; @@ -34,128 +37,45 @@ namespace openVulkanoCpp ICloseable* renderNode = nullptr; public: - Node() = default; - virtual ~Node() = default; + Node(); - void Init() override - { - if (parent || scene || !children.empty() || !drawables.empty()) throw std::runtime_error("Node already initialized"); - localMat = worldMat = IDENTITY; - enabled = true; - parent = nullptr; - children = std::vector(); - drawables = std::vector(); - } + ~Node() override; - void Close() override - { - children.clear(); - if (renderNode) renderNode->Close(); - parent = nullptr; - scene = nullptr; - enabled = false; - if (!children.empty()) Logger::SCENE->warn("Closing Node that has children!"); - for (Node* child : children) - { - child->SetParent(nullptr); - } - children.clear(); - for(size_t i = drawables.size(); i > 0; i--) - { - RemoveDrawable(drawables[i]); - } - } + void Init() override; - void AddChild(Node* node) - { - node->SetParent(this); - children.push_back(node); - node->UpdateWorldMatrix(worldMat); - } + void Close() override; - void AddChild(Drawable* drawable) - { - AddDrawable(drawable); - } + void AddChild(Node* node); - void RemoveChild(Node* node) - { - if (node->parent == this) - { - Utils::Remove(children, node); - node->SetParent(nullptr); - } - } + inline void AddChild(Drawable* drawable) { AddDrawable(drawable); } - void RemoveChild(Drawable* drawable) - { - RemoveDrawable(drawable); - } + void RemoveChild(Node* node); - void AddDrawable(Drawable* drawable) - { - if (scene) drawable->SetScene(scene); - else if (drawable->GetScene()) Logger::SCENE->warn("Drawable is already associated with a scene, but the node it was added to is not!"); - drawable->AddNode(this); - drawables.push_back(drawable); - } + inline void RemoveChild(Drawable* drawable) { RemoveDrawable(drawable); } - void RemoveDrawable(Drawable* drawable) - { - drawable->RemoveNode(this); - Utils::Remove(drawables, drawable); - } + void AddDrawable(Drawable* drawable); - void SetMatrix(glm::mat4x4 mat) - { - localMat = mat; - UpdateWorldMatrix(parent ? parent->GetWorldMatrix() : IDENTITY); - } + void RemoveDrawable(Drawable* drawable); - const glm::mat4x4& GetMatrix() const - { - return localMat; - } + void SetMatrix(glm::mat4x4 mat); - const glm::mat4x4& GetWorldMatrix() const - { - return worldMat; - } + [[nodiscard]] const glm::mat4x4& GetMatrix() const { return localMat; } - bool IsEnabled() const - { - return enabled; - } + [[nodiscard]] const glm::mat4x4& GetWorldMatrix() const { return worldMat; } - void Enable() - { - enabled = true; - } + [[nodiscard]] bool IsEnabled() const { return enabled; } - void Disable() - { - enabled = false; - } + void Enable() { enabled = true; } - Node* GetParent() const - { - return parent; - } + void Disable() { enabled = false; } - Scene* GetScene() const - { - return scene; - } + [[nodiscard]] Node* GetParent() const { return parent; } - bool IsRoot() const - { - return scene && parent == this; - } + [[nodiscard]] Scene* GetScene() const { return scene; } - UpdateFrequency GetUpdateFrequency() - { - return matrixUpdateFrequency; - } + [[nodiscard]] bool IsRoot() const { return scene && parent == this; } + + [[nodiscard]] UpdateFrequency GetUpdateFrequency() const { return matrixUpdateFrequency; } void SetUpdateFrequency(UpdateFrequency frequency) { @@ -164,49 +84,12 @@ namespace openVulkanoCpp } protected: - virtual void UpdateWorldMatrix(const glm::mat4x4& parentWorldMat) - { - worldMat = parentWorldMat * localMat; - for (const auto& node : children) - { - node->UpdateWorldMatrix(worldMat); - } - } + virtual void UpdateWorldMatrix(const glm::mat4x4& parentWorldMat); private: - void SetParent(Node* parent) - { - if (this->parent && parent) throw std::runtime_error("Node already has a parent! Nodes must not be used multiple times!"); - this->parent = parent; - if(parent && parent != this) this->scene = parent->scene; - if (!parent) SetScene(nullptr); - } + void SetParent(Node* parent); - void SetScene(Scene* scene) - { - if (this->scene && scene) throw std::runtime_error("Node already has a scene!"); - this->scene = scene; - for (const auto& node : children) - { - node->SetScene(scene); - } - if (scene) - { - for (size_t i = 0; i < drawables.size(); i++) - { - Scene* drawableScene = drawables[i]->GetScene(); - if(drawableScene) - { - if(drawableScene != scene) - { - Logger::SCENE->warn("Drawable is already associated with a scene! Creating copy."); - drawables[i] = drawables[i]->Copy(); - } - } - drawables[i]->SetScene(scene); - } - } - } + void SetScene(Scene* scene); }; } }