Files
OpenVulkano/openVulkanoCpp/Scene/Node.hpp
2024-07-20 19:12:34 +02:00

121 lines
3.1 KiB
C++

/*
* 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 "Base/ICloseable.hpp"
#include "Math/Math.hpp"
#include "Math/Pose.hpp"
#include "Drawable.hpp"
#include "UpdateFrequency.hpp"
#include "Shader/DescriptorInputDescription.hpp"
#include <vector>
#include <memory>
namespace OpenVulkano::Scene
{
class Scene;
class Node : public ICloseable
{
friend Scene;
public:
static constexpr size_t SIZE = sizeof(Math::Matrix4f);
static constexpr DescriptorSetLayoutBinding DESCRIPTOR_SET_LAYOUT_BINDING = { 0, DescriptorSetLayoutBinding::Type::TYPE_UNIFORM_BUFFER_DYNAMIC, 1, ShaderProgramType::ALL_GRAPHICS };
Math::Matrix4f localMat, worldMat;
Node* parent = nullptr;
Scene* scene = nullptr;
std::vector<Node*> children;
std::vector<Drawable*> drawables;
UpdateFrequency matrixUpdateFrequency = UpdateFrequency::Never;
ICloseable* renderNode = nullptr;
bool enabled = true;
public:
Node();
Node(const Math::Matrix4f& pose);
~Node() noexcept override;
void Init();
void Close() override;
void AddChild(Node* node);
void AddChildIfParentless(Node* node);
inline void AddChild(Drawable* drawable) { AddDrawable(drawable); }
void RemoveChild(Node* node);
void RemoveChildNodes();
inline void RemoveChild(Drawable* drawable) { RemoveDrawable(drawable); }
void AddDrawable(Drawable* drawable);
void RemoveDrawable(Drawable* drawable);
void AddDrawableIfParentless(Drawable* drawable);
void SetMatrix(const Math::Matrix4f& mat);
[[nodiscard]] Math::Matrix3f GetRotationMatrix() const { return static_cast<const Math::Matrix3f>(localMat); }
[[nodiscard]] const Math::Matrix4f& GetMatrix() const { return localMat; }
[[nodiscard]] const Math::Matrix4f& GetWorldMatrix() const { return worldMat; }
[[nodiscard]] Math::PoseF GetPose() { return Math::PoseF(GetMatrix()); }
[[nodiscard]] Math::PoseF GetWorldPose() { return Math::PoseF(GetWorldMatrix()); }
[[nodiscard]] bool IsEnabled() const { return enabled; }
void Enable() { enabled = true; }
void Disable() { enabled = false; }
void SetEnabled(bool enable) { enabled = enable; }
[[nodiscard]] Node* GetParent() const { return parent; }
[[nodiscard]] Scene* GetScene() const { return scene; }
[[nodiscard]] bool IsRoot() const { return scene && parent == this; }
[[nodiscard]] UpdateFrequency GetUpdateFrequency() const { return matrixUpdateFrequency; }
void SetUpdateFrequency(UpdateFrequency frequency)
{
if (!children.empty()) throw std::runtime_error("The update must not be changed for nodes with children.");
this->matrixUpdateFrequency = frequency;
}
float Distance(const Math::Vector4f& pos) const
{
return Math::Utils::distance(worldMat[3], pos);
}
float Distance2(const Math::Vector4f& pos) const
{
return Math::Utils::distance2(worldMat[3], pos);
}
protected:
virtual void UpdateWorldMatrix(const Math::Matrix4f& parentWorldMat);
private:
void SetParent(Node* parent);
void SetScene(Scene* scene);
};
}