feat: scene + entity class

This commit is contained in:
2025-10-22 15:23:51 +02:00
parent ea593feb8d
commit 4798c52e51
4 changed files with 48 additions and 53 deletions

View File

@ -5,9 +5,8 @@ set(SOURCES
src/IO/file_manager.cpp src/IO/file_manager.cpp
src/renderer/debug.cpp src/renderer/debug.cpp
src/window/window.cpp
src/scene/scene.cpp src/scene/scene.cpp
src/window/window.cpp
src/components/batch.cpp src/components/batch.cpp
src/renderer/mesh.cpp src/renderer/mesh.cpp

View File

@ -1,18 +1,30 @@
#ifndef ENGINE_SCENE_H_ #pragma once
#define ENGINE_SCENE_H_
#include <entt/entt.hpp> #include <entt/entt.hpp>
#include <memory> #include <memory>
namespace Engine { namespace Engine {
class Scene; class Entity;
class Scene {
private:
friend class Entity;
public:
Scene() = default;
Entity CreateEntity();
private:
entt::registry m_registry;
friend class Renderer;
};
class Entity { class Entity {
friend class Scene;
private:
Entity(entt::entity entity, Scene* scene) : m_entity(entity), m_scene(scene) {}
public: public:
Entity() = default;
Entity(entt::entity entity, Scene* scene) : m_entity(entity), m_scene(scene) {}
Entity(const Entity& other) = default;
template<typename Type, typename... Args> template<typename Type, typename... Args>
inline auto AddComponent(Args &&...args) { inline auto AddComponent(Args &&...args) {
assert(this->m_scene != nullptr && "Scene has not been assigned to the entity"); assert(this->m_scene != nullptr && "Scene has not been assigned to the entity");
@ -25,22 +37,8 @@ public:
return m_scene->m_registry.get<Type>(m_entity); return m_scene->m_registry.get<Type>(m_entity);
} }
private: private:
entt::entity m_entity; entt::entity m_entity { 0 };
Scene *m_scene; Scene *m_scene = nullptr;
};
class Scene {
private:
friend class Entity;
public:
Scene();
std::unique_ptr<Entity> CreateEntity();
private:
entt::registry m_registry;
friend class Renderer;
}; };
} // namespace Engine } // namespace Engine
#endif // ENGINE_SCENE_H_

View File

@ -2,10 +2,8 @@
namespace Engine { namespace Engine {
Scene::Scene() = default; Entity Scene::CreateEntity() {
return { m_registry.create(), this };
std::unique_ptr<Entity> Scene::CreateEntity() {
return std::unique_ptr<Entity>(new Entity(m_registry.create(), this));
} }
} // namespace Engine }

View File

@ -35,19 +35,19 @@ public:
Object* lightObj = Object::LoadFile("./assets/common/sphere/sphere.obj"); Object* lightObj = Object::LoadFile("./assets/common/sphere/sphere.obj");
lightEntity = scene->CreateEntity(); lightEntity = scene->CreateEntity();
lightEntity->AddComponent<transform>(glm::vec3(5.f, 5.f, 5.f), glm::vec3(0.f)); lightEntity.AddComponent<transform>(glm::vec3(5.f, 5.f, 5.f), glm::vec3(0.f));
lightEntity->AddComponent<light>(light::LightType::DIRECTIONAL, glm::vec3(1.f, 1.f, 1.f), 1.5f); lightEntity.AddComponent<light>(light::LightType::DIRECTIONAL, glm::vec3(1.f, 1.f, 1.f), 1.5f);
lightEntity->AddComponent<mesh>(std::shared_ptr<Object>(lightObj)); lightEntity.AddComponent<mesh>(std::shared_ptr<Object>(lightObj));
cameraEntity = scene->CreateEntity(); cameraEntity = scene->CreateEntity();
cameraEntity->AddComponent<camera>(); cameraEntity.AddComponent<camera>();
cameraEntity->AddComponent<transform>(glm::vec3(0.f, 2.f, 2.f)); cameraEntity.AddComponent<transform>(glm::vec3(0.f, 2.f, 2.f));
Object* targetObj = Object::LoadFile("./assets/wizard/wizard.obj"); Object* targetObj = Object::LoadFile("./assets/wizard/wizard.obj");
modelEntity = scene->CreateEntity(); modelEntity = scene->CreateEntity();
modelEntity->AddComponent<transform>(glm::vec3(0.f, 0.0f, 0.f)); modelEntity.AddComponent<transform>(glm::vec3(0.f, 0.0f, 0.f));
modelEntity->AddComponent<mesh>(std::shared_ptr<Object>(targetObj)); modelEntity.AddComponent<mesh>(std::shared_ptr<Object>(targetObj));
modelEntity->AddComponent<rotate>(); modelEntity.AddComponent<rotate>();
// Object* grass = Object::LoadFile("./assets/common/cube/cube.obj"); // Object* grass = Object::LoadFile("./assets/common/cube/cube.obj");
// const auto cubeEntity = scene->m_registry.create(); // const auto cubeEntity = scene->m_registry.create();
@ -56,27 +56,27 @@ public:
// Cube template (use shared object to avoid reloading 1000 times) // Cube template (use shared object to avoid reloading 1000 times)
std::shared_ptr<Object> cubeObj = std::shared_ptr<Object>(Object::LoadFile("./assets/grass_block/grass_block.obj")); std::shared_ptr<Object> cubeObj = std::shared_ptr<Object>(Object::LoadFile("./assets/grass_block/grass_block.obj"));
const auto batchEntt = scene->CreateEntity(); auto batchEntt = scene->CreateEntity();
auto cubeBatch = batchEntt->AddComponent<batch>(); auto cubeBatch = batchEntt.AddComponent<batch>();
batchEntt->AddComponent<mesh>(cubeObj); batchEntt.AddComponent<mesh>(cubeObj);
// auto cubeBatch = scene->m_registry.get<batch>(batchEntt); // auto cubeBatch = scene->m_registry.get<batch>(batchEntt);
// Generate 1000 random cubes // Generate 1000 random cubes
for (int i = 0; i < 1000; ++i) { for (int i = 0; i < 1000; ++i) {
const auto cubeEntity = scene->CreateEntity(); auto cubeEntity = scene->CreateEntity();
float x = static_cast<float>(rand()) / RAND_MAX * 200.f - 100.f; // range [-100, 100] float x = static_cast<float>(rand()) / RAND_MAX * 200.f - 100.f; // range [-100, 100]
float y = static_cast<float>(rand()) / RAND_MAX * 10.f; // range [0, 10] float y = static_cast<float>(rand()) / RAND_MAX * 10.f; // range [0, 10]
float z = static_cast<float>(rand()) / RAND_MAX * 200.f - 100.f; // range [-100, 100] float z = static_cast<float>(rand()) / RAND_MAX * 200.f - 100.f; // range [-100, 100]
cubeEntity->AddComponent<transform>(glm::vec3(x, y, z)); cubeEntity.AddComponent<transform>(glm::vec3(x, y, z));
cubeEntity->AddComponent<rotate>(); cubeEntity.AddComponent<rotate>();
cubeEntity->AddComponent<batch::item>(cubeBatch.id()); cubeEntity.AddComponent<batch::item>(cubeBatch.id());
} }
Object* floorObj = Object::LoadFile("./assets/common/plane/plane.obj"); Object* floorObj = Object::LoadFile("./assets/common/plane/plane.obj");
const auto floorEntt = scene->CreateEntity(); auto floorEntt = scene->CreateEntity();
floorEntt->AddComponent<transform>(glm::vec3(0.f)); floorEntt.AddComponent<transform>(glm::vec3(0.f));
floorEntt->AddComponent<mesh>(std::shared_ptr<Object>(floorObj)); floorEntt.AddComponent<mesh>(std::shared_ptr<Object>(floorObj));
std::cout << "Game initialized" << std::endl; std::cout << "Game initialized" << std::endl;
@ -134,7 +134,7 @@ public:
if (state[SDL_SCANCODE_SPACE]) velocity.y += 1.f; if (state[SDL_SCANCODE_SPACE]) velocity.y += 1.f;
if (state[SDL_SCANCODE_LSHIFT]) velocity.y -= 1.f; if (state[SDL_SCANCODE_LSHIFT]) velocity.y -= 1.f;
auto camTransform = cameraEntity->GetComponent<transform>(); auto camTransform = cameraEntity.GetComponent<transform>();
camTransform.position += velocity * deltaTime * 2.5f; // speed is e.g. 2.5f camTransform.position += velocity * deltaTime * 2.5f; // speed is e.g. 2.5f
camTransform.rotation = cameraViewDirection; camTransform.rotation = cameraViewDirection;
@ -169,8 +169,8 @@ public:
glm::vec3 sunColor = glm::mix(dayColor, sunsetColor, sunsetFactor); glm::vec3 sunColor = glm::mix(dayColor, sunsetColor, sunsetFactor);
// Update the directional light in the registry // Update the directional light in the registry
auto l = lightEntity->GetComponent<light>(); auto l = lightEntity.GetComponent<light>();
auto t = lightEntity->GetComponent<transform>(); auto t = lightEntity.GetComponent<transform>();
if (l.type == light::LightType::DIRECTIONAL) { if (l.type == light::LightType::DIRECTIONAL) {
// "position" for directional light often stores direction vector // "position" for directional light often stores direction vector
// If your system instead uses transform.rotation, adjust accordingly // If your system instead uses transform.rotation, adjust accordingly
@ -211,9 +211,9 @@ public:
private: private:
std::shared_ptr<Scene> m_scene; std::shared_ptr<Scene> m_scene;
std::unique_ptr<Entity> lightEntity; Entity lightEntity;
std::unique_ptr<Entity> cameraEntity; Entity cameraEntity;
std::unique_ptr<Entity> modelEntity; Entity modelEntity;
float m_angle; float m_angle;
Uint64 m_lastTicks; Uint64 m_lastTicks;