/* * 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 "Base/Render/RenderResource.hpp" #include "Math/Math.hpp" #include "Math/Pose.hpp" #include "Drawable.hpp" #include "UpdateFrequency.hpp" #include "Shader/DescriptorInputDescription.hpp" #include #include namespace OpenVulkano::Scene { class Scene; class Node : public RenderResourceHolder, 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 children; std::vector drawables; UpdateFrequency matrixUpdateFrequency = UpdateFrequency::Never; 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(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); }; }