Cleanup Node

This commit is contained in:
2020-10-17 00:53:30 +02:00
parent aea890971b
commit d50a14f9c9
3 changed files with 159 additions and 153 deletions

View File

@@ -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)

View File

@@ -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 <stdexcept>
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);
}
}
}

View File

@@ -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 <vector>
#include <stdexcept>
#include <glm/glm.hpp>
#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<Node*>();
drawables = std::vector<Drawable*>();
}
~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);
};
}
}