Cleanup Node
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user