diff --git a/include/Nazara/Core/ECS.hpp b/include/Nazara/Core/ECS.hpp new file mode 100644 index 000000000..3ecf2aec9 --- /dev/null +++ b/include/Nazara/Core/ECS.hpp @@ -0,0 +1,46 @@ +// Copyright (C) 2020 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_ECS_HPP +#define NAZARA_ECS_HPP + +#include +#include +#include + +namespace Nz +{ + class GraphicsComponent; + class NodeComponent; + class RigidBody3DComponent; + + class ECS : public ModuleBase + { + friend ModuleBase; + friend class Audio; + friend class Graphics; + friend class Physics2D; + friend class Physics3D; + friend class Utility; + + public: + using Dependencies = TypeList; + + struct Config {}; + + inline ECS(Config /*config*/); + ~ECS() = default; + + private: + static inline void RegisterComponents(); + + NAZARA_CORE_API static ECS* s_instance; + }; +} + +#include + +#endif diff --git a/include/Nazara/Core/ECS.inl b/include/Nazara/Core/ECS.inl new file mode 100644 index 000000000..ed9d42ebc --- /dev/null +++ b/include/Nazara/Core/ECS.inl @@ -0,0 +1,35 @@ +// Copyright (C) 2020 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + /*! + * \ingroup core + * \class Nz::ECS + * \brief Core class that represents the ECS module + */ + inline ECS::ECS(Config /*config*/) : + ModuleBase("ECS", this) + { + RegisterComponents(); + } + + inline void ECS::RegisterComponents() + { + if (entt::type_seq() != 0) + throw std::runtime_error("NodeComponent has wrong index, please initialize Nazara ECS before instancing your own components"); + + if (entt::type_seq() != 1) + throw std::runtime_error("GraphicsComponent has wrong index, please initialize Nazara ECS before instancing your own components"); + + if (entt::type_seq() != 2) + throw std::runtime_error("GraphicsComponent has wrong index, please initialize Nazara ECS before instancing your own components"); + } +} + +#include diff --git a/include/Nazara/Graphics/Components/GraphicsComponent.hpp b/include/Nazara/Graphics/Components/GraphicsComponent.hpp index e69de29bb..835528a87 100644 --- a/include/Nazara/Graphics/Components/GraphicsComponent.hpp +++ b/include/Nazara/Graphics/Components/GraphicsComponent.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2021 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_GRAPHICSCOMPONENT_HPP +#define NAZARA_GRAPHICSCOMPONENT_HPP + +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_GRAPHICS_API GraphicsComponent + { + public: + GraphicsComponent() = default; + GraphicsComponent(const GraphicsComponent&) = default; + GraphicsComponent(GraphicsComponent&&) = default; + ~GraphicsComponent() = default; + + inline void AttachRenderable(std::shared_ptr renderable); + inline void DetachRenderable(const std::shared_ptr& renderable); + + inline const std::vector>& GetRenderables() const; + inline WorldInstance& GetWorldInstance(); + inline const WorldInstance& GetWorldInstance() const; + + GraphicsComponent& operator=(const GraphicsComponent&) = default; + GraphicsComponent& operator=(GraphicsComponent&&) = default; + + private: + std::vector> m_renderables; + WorldInstance m_worldInstance; + }; +} + +#include + +#endif diff --git a/include/Nazara/Graphics/Components/GraphicsComponent.inl b/include/Nazara/Graphics/Components/GraphicsComponent.inl index e69de29bb..f85cf7b3a 100644 --- a/include/Nazara/Graphics/Components/GraphicsComponent.inl +++ b/include/Nazara/Graphics/Components/GraphicsComponent.inl @@ -0,0 +1,37 @@ +// Copyright (C) 2021 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Prerequisites.hpp + +#include +#include +#include "GraphicsComponent.hpp" + +namespace Nz +{ + inline void GraphicsComponent::AttachRenderable(std::shared_ptr renderable) + { + m_renderables.push_back(std::move(renderable)); + } + + inline void GraphicsComponent::DetachRenderable(const std::shared_ptr& renderable) + { + auto it = std::find(m_renderables.begin(), m_renderables.end(), renderable); + if (it != m_renderables.end()) + m_renderables.erase(it); + } + + inline const std::vector>& GraphicsComponent::GetRenderables() const + { + return m_renderables; + } + + inline WorldInstance& GraphicsComponent::GetWorldInstance() + { + return m_worldInstance; + } + + inline const WorldInstance& GraphicsComponent::GetWorldInstance() const + { + return m_worldInstance; + } +} diff --git a/include/Nazara/Physics3D/Components/RigidBody3DComponent.hpp b/include/Nazara/Physics3D/Components/RigidBody3DComponent.hpp new file mode 100644 index 000000000..8b6362fe5 --- /dev/null +++ b/include/Nazara/Physics3D/Components/RigidBody3DComponent.hpp @@ -0,0 +1,30 @@ +// Copyright (C) 2021 Jérôme Leclercq +// This file is part of the "Nazara Engine - Physics 3D module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_RIGIDBODYCOMPONENT_HPP +#define NAZARA_RIGIDBODYCOMPONENT_HPP + +#include +#include + +namespace Nz +{ + class NAZARA_PHYSICS3D_API RigidBody3DComponent : public RigidBody3D + { + public: + using RigidBody3D::RigidBody3D; + RigidBody3DComponent(const RigidBody3DComponent&) = default; + RigidBody3DComponent(RigidBody3DComponent&&) noexcept = default; + ~RigidBody3DComponent() = default; + + RigidBody3DComponent& operator=(const RigidBody3DComponent&) = default; + RigidBody3DComponent& operator=(RigidBody3DComponent&&) noexcept = default; + }; +} + +#include + +#endif diff --git a/include/Nazara/Physics3D/Components/RigidBody3DComponent.inl b/include/Nazara/Physics3D/Components/RigidBody3DComponent.inl new file mode 100644 index 000000000..97eb269a7 --- /dev/null +++ b/include/Nazara/Physics3D/Components/RigidBody3DComponent.inl @@ -0,0 +1,12 @@ +// Copyright (C) 2021 Jérôme Leclercq +// This file is part of the "Nazara Engine - Physics 3D module" +// For conditions of distribution and use, see copyright notice in Prerequisites.hpp + +#include +#include + +namespace Nz +{ +} + +#include diff --git a/include/Nazara/Physics3D/Systems/Physics3DSystem.hpp b/include/Nazara/Physics3D/Systems/Physics3DSystem.hpp new file mode 100644 index 000000000..a1231b04e --- /dev/null +++ b/include/Nazara/Physics3D/Systems/Physics3DSystem.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2021 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_PHYSICS3DSYSTEM_HPP +#define NAZARA_PHYSICS3DSYSTEM_HPP + +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_PHYSICS3D_API Physics3DSystem + { + public: + Physics3DSystem(entt::registry& registry); + Physics3DSystem(const Physics3DSystem&) = delete; + Physics3DSystem(Physics3DSystem&&) = delete; + ~Physics3DSystem(); + + template RigidBody3DComponent CreateRigidBody(Args&&... args); + + inline PhysWorld3D& GetPhysWorld(); + inline const PhysWorld3D& GetPhysWorld() const; + + void Update(entt::registry& registry, float elapsedTime); + + Physics3DSystem& operator=(const Physics3DSystem&) = delete; + Physics3DSystem& operator=(Physics3DSystem&&) = delete; + + private: + static void OnConstruct(entt::registry& registry, entt::entity entity); + + entt::connection m_constructConnection; + PhysWorld3D m_physWorld; + }; +} + +#include + +#endif diff --git a/include/Nazara/Physics3D/Systems/Physics3DSystem.inl b/include/Nazara/Physics3D/Systems/Physics3DSystem.inl new file mode 100644 index 000000000..e86acefd0 --- /dev/null +++ b/include/Nazara/Physics3D/Systems/Physics3DSystem.inl @@ -0,0 +1,27 @@ +// Copyright (C) 2021 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Prerequisites.hpp + +#include +#include + +namespace Nz +{ + template + RigidBody3DComponent Physics3DSystem::CreateRigidBody(Args&&... args) + { + return RigidBody3DComponent(&m_physWorld, std::forward(args)...); + } + + inline PhysWorld3D& Physics3DSystem::GetPhysWorld() + { + return m_physWorld; + } + + inline const PhysWorld3D& Physics3DSystem::GetPhysWorld() const + { + return m_physWorld; + } +} + +#include diff --git a/include/Nazara/Utility/Components/NodeComponent.hpp b/include/Nazara/Utility/Components/NodeComponent.hpp index e69de29bb..dbc7f99ae 100644 --- a/include/Nazara/Utility/Components/NodeComponent.hpp +++ b/include/Nazara/Utility/Components/NodeComponent.hpp @@ -0,0 +1,34 @@ +// Copyright (C) 2021 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_NODECOMPONENT_HPP +#define NAZARA_NODECOMPONENT_HPP + +#include +#include +#include + +namespace Nz +{ + class NAZARA_UTILITY_API NodeComponent : public Node + { + public: + NodeComponent() = default; + NodeComponent(const NodeComponent&) = default; + NodeComponent(NodeComponent&&) noexcept = default; + ~NodeComponent() = default; + + void SetParent(entt::registry& registry, entt::entity entity, bool keepDerived = false); + using Node::SetParent; + + NodeComponent& operator=(const NodeComponent&) = default; + NodeComponent& operator=(NodeComponent&&) noexcept = default; + }; +} + +#include + +#endif diff --git a/include/Nazara/Utility/Components/NodeComponent.inl b/include/Nazara/Utility/Components/NodeComponent.inl index e69de29bb..99b319512 100644 --- a/include/Nazara/Utility/Components/NodeComponent.inl +++ b/include/Nazara/Utility/Components/NodeComponent.inl @@ -0,0 +1,12 @@ +// Copyright (C) 2021 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Prerequisites.hpp + +#include +#include + +namespace Nz +{ +} + +#include diff --git a/src/Nazara/Core/ECS.cpp b/src/Nazara/Core/ECS.cpp new file mode 100644 index 000000000..d1d40a6ed --- /dev/null +++ b/src/Nazara/Core/ECS.cpp @@ -0,0 +1,11 @@ +// Copyright (C) 2020 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + NAZARA_CORE_API ECS* ECS::s_instance = nullptr; +} diff --git a/src/Nazara/Graphics/Components/GraphicsComponent.cpp b/src/Nazara/Graphics/Components/GraphicsComponent.cpp index e69de29bb..c246b33c8 100644 --- a/src/Nazara/Graphics/Components/GraphicsComponent.cpp +++ b/src/Nazara/Graphics/Components/GraphicsComponent.cpp @@ -0,0 +1,10 @@ +// Copyright (C) 2021 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Prerequisites.hpp + +#include +#include + +namespace Nz +{ +} diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index 09208e1a3..badff0a2c 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include @@ -18,6 +19,8 @@ namespace Nz Graphics::Graphics(Config config) : ModuleBase("Graphics", this) { + ECS::RegisterComponents(); + Renderer* renderer = Renderer::Instance(); const std::vector& renderDeviceInfo = renderer->QueryRenderDevices(); diff --git a/src/Nazara/Physics3D/Components/RigidBody3DComponent.cpp b/src/Nazara/Physics3D/Components/RigidBody3DComponent.cpp new file mode 100644 index 000000000..3031d479a --- /dev/null +++ b/src/Nazara/Physics3D/Components/RigidBody3DComponent.cpp @@ -0,0 +1,10 @@ +// Copyright (C) 2021 Jérôme Leclercq +// This file is part of the "Nazara Engine - Physics 3D module" +// For conditions of distribution and use, see copyright notice in Prerequisites.hpp + +#include +#include + +namespace Nz +{ +} diff --git a/src/Nazara/Physics3D/Systems/Physics3DSystem.cpp b/src/Nazara/Physics3D/Systems/Physics3DSystem.cpp new file mode 100644 index 000000000..f92bc1dee --- /dev/null +++ b/src/Nazara/Physics3D/Systems/Physics3DSystem.cpp @@ -0,0 +1,45 @@ +// Copyright (C) 2021 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Prerequisites.hpp + +#include +#include +#include + +namespace Nz +{ + Physics3DSystem::Physics3DSystem(entt::registry& registry) + { + m_constructConnection = registry.on_construct().connect(); + } + + Physics3DSystem::~Physics3DSystem() + { + m_constructConnection.release(); + } + + void Physics3DSystem::Update(entt::registry& registry, float elapsedTime) + { + m_physWorld.Step(elapsedTime); + + // Replicate rigid body position to their node components + auto velView = registry.view(); + for (auto [entity, nodeComponent, rigidBodyComponent] : velView.each()) + { + nodeComponent.SetPosition(rigidBodyComponent.GetPosition(), CoordSys::Global); + nodeComponent.SetRotation(rigidBodyComponent.GetRotation(), CoordSys::Global); + } + } + + void Physics3DSystem::OnConstruct(entt::registry& registry, entt::entity entity) + { + // If our entity already has a node component when adding a rigid body, initialize it with + Nz::NodeComponent* node = registry.try_get(entity); + if (node) + { + RigidBody3DComponent& rigidBody = registry.get(entity); + rigidBody.SetPosition(node->GetPosition()); + rigidBody.SetRotation(node->GetRotation()); + } + } +} diff --git a/src/Nazara/Utility/Components/NodeComponent.cpp b/src/Nazara/Utility/Components/NodeComponent.cpp index e69de29bb..9b17be981 100644 --- a/src/Nazara/Utility/Components/NodeComponent.cpp +++ b/src/Nazara/Utility/Components/NodeComponent.cpp @@ -0,0 +1,18 @@ +// Copyright (C) 2021 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Prerequisites.hpp + +#include +#include +#include + +namespace Nz +{ + void NodeComponent::SetParent(entt::registry& registry, entt::entity entity, bool keepDerived) + { + NodeComponent* nodeComponent = registry.try_get(entity); + NazaraAssert(nodeComponent, "entity doesn't have a NodeComponent"); + + Node::SetParent(nodeComponent, keepDerived); + } +} diff --git a/src/Nazara/Utility/Utility.cpp b/src/Nazara/Utility/Utility.cpp index b1ca74d80..bd5314862 100644 --- a/src/Nazara/Utility/Utility.cpp +++ b/src/Nazara/Utility/Utility.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,8 @@ namespace Nz Utility::Utility(Config /*config*/) : ModuleBase("Utility", this) { + ECS::RegisterComponents(); + if (!Buffer::Initialize()) throw std::runtime_error("failed to initialize buffers");