UPD: Introduce ECS System
This commit is contained in:
parent
fffc799447
commit
fe376e9c0f
@ -58,7 +58,6 @@ add_executable(Dicewars_Siedler src/main.cpp
|
||||
src/engine/layer/entities/Light.h
|
||||
src/engine/platform/glfw/MousePicker.cpp
|
||||
src/engine/platform/glfw/MousePicker.h
|
||||
src/game/hexWorld/HexTile.h
|
||||
src/game/hexWorld/Map.cpp
|
||||
src/game/hexWorld/Map.h
|
||||
src/game/hexWorld/MapGenerator.cpp
|
||||
@ -79,8 +78,25 @@ add_executable(Dicewars_Siedler src/main.cpp
|
||||
src/game/hexWorld/tileGenerator/ForestTileGenerator.h
|
||||
src/engine/toolbox/Random.cpp
|
||||
src/engine/toolbox/Random.h
|
||||
src/game/TileInteractionSystem.cpp
|
||||
src/game/TileInteractionSystem.h
|
||||
src/engine/core/ECS/Component.cpp
|
||||
src/engine/core/ECS/Component.h
|
||||
src/engine/core/ECS/TransformComponent.cpp
|
||||
src/engine/core/ECS/TransformComponent.h
|
||||
src/engine/core/ECS/ModelComponent.cpp
|
||||
src/engine/core/ECS/ModelComponent.h
|
||||
src/engine/core/ECS/EntityManager.cpp
|
||||
src/engine/core/ECS/EntityManager.h
|
||||
src/engine/core/ECS/RenderSystem.cpp
|
||||
src/engine/core/ECS/RenderSystem.h
|
||||
src/engine/core/ECS/TileRenderComponent.cpp
|
||||
src/engine/core/ECS/TileRenderComponent.h
|
||||
src/game/hexWorld/ecs/components/TileGameplayComponent.cpp
|
||||
src/game/hexWorld/ecs/components/TileGameplayComponent.h
|
||||
src/game/hexWorld/ecs/components/MapEntityComponent.h
|
||||
src/engine/renderer/components/TerrainRenderingData.h
|
||||
src/game/hexWorld/RessourceType.h
|
||||
src/game/hexWorld/ecs/systems/TileHighlightSystem.cpp
|
||||
src/game/hexWorld/ecs/systems/TileHighlightSystem.h
|
||||
)
|
||||
|
||||
target_include_directories(Dicewars_Siedler PRIVATE
|
||||
|
||||
5
src/engine/core/ECS/Component.cpp
Normal file
5
src/engine/core/ECS/Component.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#include "Component.h"
|
||||
16
src/engine/core/ECS/Component.h
Normal file
16
src/engine/core/ECS/Component.h
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#ifndef COMPONENT_H
|
||||
#define COMPONENT_H
|
||||
#include "glm/vec3.hpp"
|
||||
|
||||
|
||||
class Component {
|
||||
public:
|
||||
virtual ~Component() = default;
|
||||
};
|
||||
|
||||
|
||||
#endif //COMPONENT_H
|
||||
17
src/engine/core/ECS/EntityManager.cpp
Normal file
17
src/engine/core/ECS/EntityManager.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#include "EntityManager.h"
|
||||
#include <algorithm>
|
||||
EntityID EntityManager::createEntity() {
|
||||
const EntityID id = nextID++;
|
||||
entities.push_back(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
void EntityManager::destroyEntity(EntityID entity) {
|
||||
entities.erase(std::remove(entities.begin(), entities.end(), entity), entities.end());
|
||||
transforms.erase(entity);
|
||||
models.erase(entity);
|
||||
}
|
||||
80
src/engine/core/ECS/EntityManager.h
Normal file
80
src/engine/core/ECS/EntityManager.h
Normal file
@ -0,0 +1,80 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#ifndef ENTITYMANAGER_H
|
||||
#define ENTITYMANAGER_H
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
// Forward Declarations (KEINE includes hier!)
|
||||
class TransformComponent;
|
||||
class ModelComponent;
|
||||
class TileRenderComponent;
|
||||
class TileGameplayComponent;
|
||||
class MapEntityComponent;
|
||||
|
||||
using EntityID = std::uint32_t;
|
||||
|
||||
class EntityManager {
|
||||
private:
|
||||
EntityID nextID = 1;
|
||||
std::vector<EntityID> entities;
|
||||
|
||||
std::unordered_map<EntityID, std::shared_ptr<TransformComponent>> transforms;
|
||||
std::unordered_map<EntityID, std::shared_ptr<ModelComponent>> models;
|
||||
std::unordered_map<EntityID, std::shared_ptr<TileRenderComponent>> tileRenderComponents;
|
||||
std::unordered_map<EntityID, std::shared_ptr<TileGameplayComponent>> tileGameplayComponents;
|
||||
std::unordered_map<EntityID, std::shared_ptr<MapEntityComponent>> mapEntityComponents;
|
||||
|
||||
public:
|
||||
EntityID createEntity();
|
||||
void destroyEntity(EntityID entity);
|
||||
|
||||
template<typename T>
|
||||
void addComponent(EntityID entity, std::shared_ptr<T> component) {
|
||||
if constexpr (std::is_same_v<T, TransformComponent>) {
|
||||
transforms[entity] = component;
|
||||
} else if constexpr (std::is_same_v<T, ModelComponent>) {
|
||||
models[entity] = component;
|
||||
} else if constexpr (std::is_same_v<T, TileRenderComponent>) {
|
||||
tileRenderComponents[entity] = component;
|
||||
} else if constexpr (std::is_same_v<T, TileGameplayComponent>) {
|
||||
tileGameplayComponents[entity] = component;
|
||||
} else if constexpr (std::is_same_v<T, MapEntityComponent>) {
|
||||
mapEntityComponents[entity] = component;
|
||||
} else {
|
||||
static_assert(sizeof(T) == 0, "Component-Typ nicht unterstützt");
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::shared_ptr<T> getComponent(EntityID entity) {
|
||||
if constexpr (std::is_same_v<T, TransformComponent>) {
|
||||
auto it = transforms.find(entity);
|
||||
return (it != transforms.end()) ? it->second : nullptr;
|
||||
} else if constexpr (std::is_same_v<T, ModelComponent>) {
|
||||
auto it = models.find(entity);
|
||||
return (it != models.end()) ? it->second : nullptr;
|
||||
} else if constexpr (std::is_same_v<T, TileRenderComponent>) {
|
||||
auto it = tileRenderComponents.find(entity);
|
||||
return (it != tileRenderComponents.end()) ? it->second : nullptr;
|
||||
} else if constexpr (std::is_same_v<T, TileGameplayComponent>) {
|
||||
auto it = tileGameplayComponents.find(entity);
|
||||
return (it != tileGameplayComponents.end()) ? it->second : nullptr;
|
||||
} else if constexpr (std::is_same_v<T, MapEntityComponent>) {
|
||||
auto it = mapEntityComponents.find(entity);
|
||||
return (it != mapEntityComponents.end()) ? it->second : nullptr;
|
||||
} else {
|
||||
static_assert(sizeof(T) == 0, "Component-Typ nicht unterstützt");
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<EntityID>& getAllEntities() const { return entities; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //ENTITYMANAGER_H
|
||||
5
src/engine/core/ECS/ModelComponent.cpp
Normal file
5
src/engine/core/ECS/ModelComponent.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#include "ModelComponent.h"
|
||||
21
src/engine/core/ECS/ModelComponent.h
Normal file
21
src/engine/core/ECS/ModelComponent.h
Normal file
@ -0,0 +1,21 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#ifndef MODELCOMPONENT_H
|
||||
#define MODELCOMPONENT_H
|
||||
#include <memory>
|
||||
|
||||
#include "Component.h"
|
||||
#include "../../renderer/model/TexturedModel.h"
|
||||
|
||||
|
||||
class ModelComponent: public Component {
|
||||
public:
|
||||
std::shared_ptr<TexturedModel> model;
|
||||
ModelComponent(std::shared_ptr<TexturedModel> model) : model(std::move(model)) {};
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //MODELCOMPONENT_H
|
||||
24
src/engine/core/ECS/RenderSystem.cpp
Normal file
24
src/engine/core/ECS/RenderSystem.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#include "RenderSystem.h"
|
||||
|
||||
void RenderSystem::render(EntityManager &entityManager, MasterRenderer &renderer) {
|
||||
for (auto id : entityManager.getAllEntities()) {
|
||||
|
||||
auto transform = entityManager.getComponent<TransformComponent>(id);
|
||||
auto model = entityManager.getComponent<ModelComponent>(id);
|
||||
auto tileRenderingComponent = entityManager.getComponent<TileRenderComponent>(id);
|
||||
|
||||
if (!transform || !model) continue;
|
||||
|
||||
if (tileRenderingComponent) {
|
||||
renderer.submitTerrainTile(transform, model, tileRenderingComponent);
|
||||
} else {
|
||||
Entity entity = Entity(model->model, transform->position, transform->rotation.x, transform->rotation.y, transform->rotation.z, transform->scale);
|
||||
renderer.submitEntity(std::make_unique<Entity>(entity));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
18
src/engine/core/ECS/RenderSystem.h
Normal file
18
src/engine/core/ECS/RenderSystem.h
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#ifndef RENDERSYSTEM_H
|
||||
#define RENDERSYSTEM_H
|
||||
#include "EntityManager.h"
|
||||
#include "../../renderer/MasterRenderer.h"
|
||||
|
||||
|
||||
class RenderSystem {
|
||||
public:
|
||||
void render(EntityManager &entityManager, MasterRenderer &renderer);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //RENDERSYSTEM_H
|
||||
5
src/engine/core/ECS/TileRenderComponent.cpp
Normal file
5
src/engine/core/ECS/TileRenderComponent.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#include "TileRenderComponent.h"
|
||||
22
src/engine/core/ECS/TileRenderComponent.h
Normal file
22
src/engine/core/ECS/TileRenderComponent.h
Normal file
@ -0,0 +1,22 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#ifndef TILERENDERCOMPONENT_H
|
||||
#define TILERENDERCOMPONENT_H
|
||||
#include <memory>
|
||||
|
||||
#include "Component.h"
|
||||
#include "../../renderer/model/TexturedModel.h"
|
||||
|
||||
|
||||
class TileRenderComponent : public Component{
|
||||
public:
|
||||
bool isHighlighted;
|
||||
explicit TileRenderComponent(bool isHighlighted) : isHighlighted(isHighlighted) {};
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //TILERENDERCOMPONENT_H
|
||||
5
src/engine/core/ECS/TransformComponent.cpp
Normal file
5
src/engine/core/ECS/TransformComponent.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#include "TransformComponent.h"
|
||||
20
src/engine/core/ECS/TransformComponent.h
Normal file
20
src/engine/core/ECS/TransformComponent.h
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#ifndef TRANSFORMCOMPONENT_H
|
||||
#define TRANSFORMCOMPONENT_H
|
||||
#include "Component.h"
|
||||
|
||||
|
||||
class TransformComponent : public Component {
|
||||
public:
|
||||
TransformComponent(glm::vec3 position, glm::vec3 rotation, float scale) : position(position), rotation(rotation), scale(scale) {};
|
||||
glm::vec3 position;
|
||||
glm::vec3 rotation;
|
||||
float scale;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //TRANSFORMCOMPONENT_H
|
||||
@ -9,7 +9,6 @@
|
||||
#include "../../renderer/model/TexturedModel.h"
|
||||
#include "glm/vec3.hpp"
|
||||
|
||||
|
||||
class Entity {
|
||||
private:
|
||||
std::shared_ptr<TexturedModel> model;
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
|
||||
#include "MasterRenderer.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "../core/Application.h"
|
||||
#include "glm/ext/matrix_clip_space.hpp"
|
||||
|
||||
@ -24,13 +26,14 @@ void MasterRenderer::render(const Light &light, const Camera &camera) {
|
||||
|
||||
}
|
||||
|
||||
void MasterRenderer::submitEntity(Entity *entity) {
|
||||
void MasterRenderer::submitEntity(std::unique_ptr<Entity> entity) {
|
||||
TexturedModel* entityModel = entity->getModel().get();
|
||||
entities[entityModel].push_back(entity);
|
||||
entities[entityModel].push_back(std::move(entity));
|
||||
}
|
||||
|
||||
void MasterRenderer::submitTerrainTile(HexRenderData *tile) {
|
||||
terrainTiles[tile->model.get()].push_back(tile);
|
||||
void MasterRenderer::submitTerrainTile(std::shared_ptr<TransformComponent> transform, std::shared_ptr<ModelComponent> model, std::shared_ptr<TileRenderComponent> terrainTileComponent) {
|
||||
TerrainRenderingData terrain = TerrainRenderingData(std::move(transform), std::move(model), std::move(terrainTileComponent));
|
||||
terrainTiles[terrain.modelComponent->model.get()].push_back(std::make_unique<TerrainRenderingData>(std::move(terrain)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
|
||||
#include "Renderer.h"
|
||||
#include "TerrainRenderer.h"
|
||||
#include "../../game/hexWorld/HexTile.h"
|
||||
#include "../layer/entities/Entity.h"
|
||||
#include "model/TexturedModel.h"
|
||||
|
||||
@ -19,8 +18,8 @@ class Light;
|
||||
|
||||
class MasterRenderer {
|
||||
private:
|
||||
std::unordered_map<TexturedModel*, std::vector<Entity*>> entities;
|
||||
std::unordered_map<TexturedModel*, std::vector<HexRenderData*>> terrainTiles;
|
||||
std::unordered_map<TexturedModel*, std::vector<std::unique_ptr<Entity>>> entities;
|
||||
std::unordered_map<TexturedModel*, std::vector<std::unique_ptr<TerrainRenderingData>>> terrainTiles;
|
||||
glm::mat4 projectionMatrix;
|
||||
std::unique_ptr<Renderer> entityRenderer;
|
||||
std::unique_ptr<TerrainRenderer> terrainRenderer;
|
||||
@ -39,8 +38,8 @@ public:
|
||||
};
|
||||
void render(const Light &light, const Camera &camera);
|
||||
|
||||
void submitEntity(Entity* entity);
|
||||
void submitTerrainTile(HexRenderData* tile);
|
||||
void submitEntity(std::unique_ptr<Entity> entity);
|
||||
void submitTerrainTile(std::shared_ptr<TransformComponent> transform, std::shared_ptr<ModelComponent> model, std::shared_ptr<TileRenderComponent>);
|
||||
|
||||
[[nodiscard]] glm::mat4 getProjectionMatrix() const {return projectionMatrix;}
|
||||
};
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
|
||||
#include <ranges>
|
||||
|
||||
#include "../../game/hexWorld/HexTile.h"
|
||||
#include "../core/Application.h"
|
||||
#include "../layer/entities/Light.h"
|
||||
#include "../toolbox/MathUtils.h"
|
||||
@ -24,7 +23,8 @@ void Renderer::prepare(const Camera& camera, const Light& light) {
|
||||
}
|
||||
|
||||
|
||||
void Renderer::renderEntities(const std::unordered_map<TexturedModel *, std::vector<Entity *>>& entities) {
|
||||
void Renderer::renderEntities(const std::unordered_map<TexturedModel *, std::vector<std::unique_ptr<Entity>>>& entities) {
|
||||
|
||||
for (const auto& [texturedModel, batch] : entities) {
|
||||
prepareTexturedModel(*texturedModel);
|
||||
for (const auto& entity : batch) {
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_RENDERER_H
|
||||
#define DICEWARS_SIEDLER_RENDERER_H
|
||||
#include "../../game/hexWorld/HexTile.h"
|
||||
#include "../layer/entities/Entity.h"
|
||||
#include "model/RawModel.h"
|
||||
#include "model/TexturedModel.h"
|
||||
@ -24,7 +23,7 @@ public:
|
||||
};
|
||||
void prepare(const ::Camera &camera, const Light& light);
|
||||
|
||||
void renderEntities(const std::unordered_map<TexturedModel *, std::vector<Entity *>> &entities);
|
||||
void renderEntities(const std::unordered_map<TexturedModel *, std::vector<std::unique_ptr<Entity>>> &entities);
|
||||
void finalizeFrame();
|
||||
private:
|
||||
StaticShader staticShader;
|
||||
|
||||
@ -13,7 +13,7 @@ void TerrainRenderer::prepare(const Camera &camera, const Light &light) {
|
||||
terrainShader.loadViewMatrix(viewMatrix);
|
||||
}
|
||||
|
||||
void TerrainRenderer::renderTerrainTiles(const std::unordered_map<TexturedModel *, std::vector<HexRenderData *>> &terrainTiles) {
|
||||
void TerrainRenderer::renderTerrainTiles(const std::unordered_map<TexturedModel *, std::vector<std::unique_ptr<TerrainRenderingData>>> &terrainTiles) {
|
||||
for (const auto& [texturedModel, batch] : terrainTiles) {
|
||||
prepareTexturedModel(*texturedModel);
|
||||
for (const auto& hexTile : batch) {
|
||||
@ -47,9 +47,9 @@ void TerrainRenderer::unbindTexturedModel() {
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void TerrainRenderer::prepareInstance(const HexRenderData &hexTile) {
|
||||
glm::mat4 transformationMatrix = MathUtils::createTransformationMatrix(hexTile.position, 0,0,0,1);
|
||||
void TerrainRenderer::prepareInstance(const TerrainRenderingData &hexTile) {
|
||||
glm::mat4 transformationMatrix = MathUtils::createTransformationMatrix(hexTile.transform->position, 0,0,0,1);
|
||||
terrainShader.loadTransformationMatrix(transformationMatrix);
|
||||
|
||||
terrainShader.loadIsHighlighted(hexTile.highlight);
|
||||
terrainShader.loadIsHighlighted(hexTile.terrainRenderComponent->isHighlighted);
|
||||
}
|
||||
|
||||
@ -4,12 +4,13 @@
|
||||
|
||||
#ifndef TERRAINRENDERER_H
|
||||
#define TERRAINRENDERER_H
|
||||
#include "../../game/hexWorld/HexTile.h"
|
||||
|
||||
#include "model/TexturedModel.h"
|
||||
#include "shaders/StaticShader.h"
|
||||
|
||||
#include "../layer/entities/Camera.h"
|
||||
#include "../layer/entities/Light.h"
|
||||
#include "components/TerrainRenderingData.h"
|
||||
#include "shaders/TerrainShader.h"
|
||||
|
||||
|
||||
@ -22,14 +23,14 @@ public:
|
||||
}
|
||||
|
||||
void prepare(const Camera &camera, const Light &light);
|
||||
void renderTerrainTiles(const std::unordered_map<TexturedModel*, std::vector<HexRenderData*>>& terrainTiles);
|
||||
void renderTerrainTiles(const std::unordered_map<TexturedModel*, std::vector<std::unique_ptr<TerrainRenderingData>>>& terrainTiles);
|
||||
void finalizeFrame();
|
||||
private:
|
||||
TerrainShader terrainShader;
|
||||
|
||||
void prepareTexturedModel(const TexturedModel &texturedModel);
|
||||
void unbindTexturedModel();
|
||||
void prepareInstance(const HexRenderData& hexTile);
|
||||
void prepareInstance(const TerrainRenderingData& hexTile);
|
||||
};
|
||||
|
||||
|
||||
|
||||
20
src/engine/renderer/components/TerrainRenderingData.h
Normal file
20
src/engine/renderer/components/TerrainRenderingData.h
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#ifndef TERRAINRENDERINGDATA_H
|
||||
#define TERRAINRENDERINGDATA_H
|
||||
#include "../../core/ECS/ModelComponent.h"
|
||||
#include "../../core/ECS/TileRenderComponent.h"
|
||||
#include "../../core/ECS/TransformComponent.h"
|
||||
|
||||
|
||||
struct TerrainRenderingData {
|
||||
std::shared_ptr<TransformComponent> transform;
|
||||
std::shared_ptr<ModelComponent> modelComponent;
|
||||
std::shared_ptr<TileRenderComponent> terrainRenderComponent;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //TERRAINRENDERINGDATA_H
|
||||
@ -5,6 +5,7 @@
|
||||
#include "AssetManager.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
|
||||
#include "../loader/OBJLoader.h"
|
||||
|
||||
@ -23,3 +24,8 @@ std::shared_ptr<TexturedModel> AssetManager::getModel(const std::string &name) {
|
||||
assert(models.contains(name) && "Model not found!");
|
||||
return models.at(name);
|
||||
}
|
||||
|
||||
void AssetManager::insertGeneratedModel(const std::string &name, std::shared_ptr<TexturedModel> model) {
|
||||
assert(!models.contains(name) && "Model already exists!");
|
||||
models[name] = std::move(model);
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ class AssetManager {
|
||||
public:
|
||||
static std::shared_ptr<TexturedModel> loadModel(const std::string& name, const std::string& objPath, const std::string& texturePath, Loader& loader);
|
||||
static std::shared_ptr<TexturedModel> getModel(const std::string& name);
|
||||
static void insertGeneratedModel(const std::string& name, std::shared_ptr<TexturedModel> model);
|
||||
private:
|
||||
static inline std::unordered_map<std::string, std::shared_ptr<TexturedModel>> models;
|
||||
};
|
||||
|
||||
@ -38,10 +38,22 @@ void GameLayer::onAttach()
|
||||
|
||||
//treeModel = std::make_unique<TexturedModel>(*OBJLoader::loadModel("assets/trees/lowPolyTree.obj", "assets/trees/lowPolyTree.png", loader));
|
||||
//treeEntity = std::make_unique<Entity>(Entity(treeModel, glm::vec3(0,0,0), 0,0,0, 0.5f));
|
||||
MapGenerator::generateHexMap(*map, 10,10,10.f, mapEntities);
|
||||
printf("Generated Terrain with %lu Tiles!\n", map->tiles.size());
|
||||
MapGenerator::init(loader, 10.f);
|
||||
MapGenerator::generateHexMap(*map, 10,10, *entityManager);
|
||||
//printf("Generated Terrain with %lu Tiles!\n", map->tiles.size());
|
||||
|
||||
for (const auto& entity : mapEntities) {
|
||||
EntityID entityID = entityManager->createEntity();
|
||||
glm::vec3 pos = entity->getPosition();
|
||||
glm::vec3 rot = glm::vec3(entity->getRotX(), entity->getRotY(), entity->getRotZ());
|
||||
float scale = entity->getScale();
|
||||
entityManager->addComponent(entityID, std::make_shared<TransformComponent>(pos, rot, scale));
|
||||
entityManager->addComponent(entityID, std::make_shared<ModelComponent>(entity->getModel()));
|
||||
}
|
||||
|
||||
|
||||
auto cabinModel = AssetManager::loadModel("cabin", "assets/cabin/cabin.obj", "assets/cabin/cabin.jpg", loader);
|
||||
|
||||
//entities.push_back(std::make_shared<Entity>(Entity(cabinModel, glm::vec3(0,0,0), 0,0,0, 1.f)));
|
||||
}
|
||||
|
||||
@ -62,26 +74,8 @@ void GameLayer::onUpdate()
|
||||
|
||||
|
||||
camera->move(moveDir, 0.5f);
|
||||
|
||||
for (const auto& entity : entities) {
|
||||
renderer->submitEntity(entity.get());
|
||||
}
|
||||
|
||||
tileInteractionSystem->update(*map, *camera, *mousePicker);
|
||||
tileInteractionSystem->handleBuildAction(*map);
|
||||
|
||||
|
||||
std::vector<HexRenderData> terrainRenderData = map->getTerrainRenderData(hexModelDefault, hexModelWood, hexModelStone);
|
||||
for (auto& renderData : terrainRenderData) {
|
||||
renderer->submitTerrainTile(&renderData);
|
||||
}
|
||||
|
||||
for (HexTile& tile : map->tiles) {
|
||||
for (const auto& entity : tile.entitiesOnTile) {
|
||||
renderer->submitEntity(entity.get());
|
||||
}
|
||||
if (tile.building) renderer->submitEntity(tile.building.get());
|
||||
}
|
||||
tileHighlightSystem->update(*entityManager, *mousePicker, *camera);
|
||||
renderSystem->render(*entityManager, *renderer);
|
||||
|
||||
renderer->render(*light, *camera);
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
#ifndef DICEWARS_SIEDLER_GAMELAYER_H
|
||||
#define DICEWARS_SIEDLER_GAMELAYER_H
|
||||
#include "TileInteractionSystem.h"
|
||||
#include "../engine/core/ECS/RenderSystem.h"
|
||||
#include "../engine/layer/Layer.h"
|
||||
#include "../engine/platform/glfw/MousePicker.h"
|
||||
#include "../engine/renderer/Renderer.h"
|
||||
@ -13,6 +13,7 @@
|
||||
#include "../engine/layer/entities/Camera.h"
|
||||
#include "../engine/renderer/MasterRenderer.h"
|
||||
#include "hexWorld/Map.h"
|
||||
#include "hexWorld/ecs/systems/TileHighlightSystem.h"
|
||||
|
||||
|
||||
class GameLayer: public Layer {
|
||||
@ -38,7 +39,11 @@ private:
|
||||
|
||||
std::vector<std::shared_ptr<Entity>> mapEntities;
|
||||
std::vector<std::shared_ptr<Entity>> entities;
|
||||
std::unique_ptr<TileInteractionSystem> tileInteractionSystem = std::make_unique<TileInteractionSystem>();
|
||||
|
||||
std::unique_ptr<RenderSystem> renderSystem = std::make_unique<RenderSystem>();
|
||||
std::unique_ptr<TileHighlightSystem> tileHighlightSystem = std::make_unique<TileHighlightSystem>();
|
||||
std::unique_ptr<EntityManager> entityManager = std::make_unique<EntityManager>();
|
||||
|
||||
std::unique_ptr<Map> map;
|
||||
};
|
||||
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#include "TileInteractionSystem.h"
|
||||
|
||||
#include "../engine/layer/entities/Camera.h"
|
||||
#include "../engine/platform/glfw/InputManager.h"
|
||||
#include "../engine/renderer/model/AssetManager.h"
|
||||
#include "GLFW/glfw3.h"
|
||||
|
||||
void TileInteractionSystem::update(Map &map, const Camera &camera, const MousePicker &mousePicker) {
|
||||
for (HexTile& tile : map.tiles) {
|
||||
glm::vec3 intersectionPoint;
|
||||
tile.isHighlighted = tile.intersect(camera.getPosition(), mousePicker.getCurrentRay(), intersectionPoint);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void TileInteractionSystem::handleBuildAction(Map &map) {
|
||||
for (HexTile& tile : map.tiles) {
|
||||
if (tile.isHighlighted && InputManager::isMouseButtonPressed(GLFW_MOUSE_BUTTON_1)) {
|
||||
if (!tile.building && tile.resourceType == RessourceType::WOOD) {
|
||||
tile.entitiesOnTile.clear();
|
||||
tile.building = std::make_shared<Entity>(AssetManager::getModel("cabin"), tile.worldPos, 0,0,0,1.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#ifndef TILEINTERACTIONSYSTEM_H
|
||||
#define TILEINTERACTIONSYSTEM_H
|
||||
#include "../engine/platform/glfw/MousePicker.h"
|
||||
#include "hexWorld/Map.h"
|
||||
|
||||
|
||||
class TileInteractionSystem {
|
||||
public:
|
||||
void update(Map& map, const Camera& camera, const MousePicker& mousePicker);
|
||||
void handleBuildAction(Map& map);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //TILEINTERACTIONSYSTEM_H
|
||||
@ -4,7 +4,9 @@
|
||||
|
||||
#ifndef HEXMODELFACTORY_H
|
||||
#define HEXMODELFACTORY_H
|
||||
#include "HexTile.h"
|
||||
|
||||
|
||||
#include "RessourceType.h"
|
||||
#include "../../engine/renderer/model/RawModel.h"
|
||||
#include "../../engine/renderer/model/TexturedModel.h"
|
||||
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
//
|
||||
// Created by sebastian on 07.02.26.
|
||||
//
|
||||
|
||||
#ifndef HEXTILE_H
|
||||
#define HEXTILE_H
|
||||
#include <memory>
|
||||
|
||||
#include "../../engine/layer/entities/Entity.h"
|
||||
#include "../../engine/renderer/model/TexturedModel.h"
|
||||
#include "glm/vec2.hpp"
|
||||
#include "glm/vec3.hpp"
|
||||
#include "glm/ext/quaternion_geometric.hpp"
|
||||
|
||||
enum class RessourceType {
|
||||
NONE,
|
||||
WOOD,
|
||||
STONE
|
||||
};
|
||||
|
||||
struct HexTile {
|
||||
glm::vec3 worldPos;
|
||||
int q, r; //Axiale Koordinaten (hex-Koordinaten)
|
||||
int ownerID = -1;
|
||||
RessourceType resourceType = RessourceType::NONE;
|
||||
float radius;
|
||||
bool isHighlighted = false;
|
||||
|
||||
std::vector<std::shared_ptr<Entity>> entitiesOnTile;
|
||||
std::shared_ptr<Entity> building;
|
||||
|
||||
|
||||
bool intersect(const glm::vec3& rayOrigin, const glm::vec3& rayDirection, glm::vec3& intersectionPoint) const {
|
||||
float t = -rayOrigin.y / rayDirection.y;
|
||||
if (t < 0) return false; // Ray zeigt nach oben, nicht getroffen
|
||||
|
||||
intersectionPoint = rayOrigin + t * rayDirection;
|
||||
|
||||
glm::vec2 diff(intersectionPoint.x - worldPos.x, intersectionPoint.z - worldPos.z);
|
||||
return glm::length(diff) <= radius -0.1f;
|
||||
}
|
||||
};
|
||||
|
||||
struct HexRenderData {
|
||||
std::shared_ptr<TexturedModel> model;
|
||||
glm::vec3 position;
|
||||
bool highlight = false;
|
||||
};
|
||||
|
||||
#endif //HEXTILE_H
|
||||
@ -4,20 +4,13 @@
|
||||
|
||||
#include "Map.h"
|
||||
|
||||
std::vector<HexRenderData> Map::getTerrainRenderData(const std::shared_ptr<TexturedModel>& hexModel,
|
||||
const std::shared_ptr<TexturedModel>& woodModel, const std::shared_ptr<TexturedModel>& stoneModel) {
|
||||
std::vector<HexRenderData> renderData;
|
||||
renderData.reserve(tiles.size());
|
||||
for (auto& tile : tiles) {
|
||||
HexRenderData data;
|
||||
if (tile.resourceType == RessourceType::WOOD) {
|
||||
data = HexRenderData(woodModel, tile.worldPos, tile.isHighlighted);
|
||||
} else if (tile.resourceType == RessourceType::NONE) {
|
||||
data = HexRenderData(hexModel, tile.worldPos, tile.isHighlighted);
|
||||
} else if (tile.resourceType == RessourceType::STONE) {
|
||||
data =HexRenderData(stoneModel, tile.worldPos, tile.isHighlighted);
|
||||
#include "ecs/components/MapEntityComponent.h"
|
||||
#include "ecs/components/TileGameplayComponent.h"
|
||||
|
||||
void Map::clear(EntityManager &entityManager) {
|
||||
for (EntityID id: entityManager.getAllEntities()) {
|
||||
if (entityManager.getComponent<MapEntityComponent>(id)) {
|
||||
entityManager.destroyEntity(id);
|
||||
}
|
||||
renderData.push_back(data);
|
||||
}
|
||||
return renderData;
|
||||
}
|
||||
|
||||
@ -4,20 +4,21 @@
|
||||
|
||||
#ifndef MAP_H
|
||||
#define MAP_H
|
||||
#include "HexTile.h"
|
||||
#include "../../engine/core/ECS/EntityManager.h"
|
||||
|
||||
struct Area {
|
||||
int id;
|
||||
std::vector<HexTile*> tiles;
|
||||
std::vector<EntityID> tiles;
|
||||
};
|
||||
|
||||
class Map {
|
||||
public:
|
||||
std::vector<Area> areas;
|
||||
std::vector<HexTile> tiles;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
std::vector<HexRenderData> getTerrainRenderData(const std::shared_ptr<TexturedModel> &hexModel, const std::shared_ptr<TexturedModel> &woodModel, const std::shared_ptr<
|
||||
TexturedModel> &stoneModel);
|
||||
std::vector<Area> areas;
|
||||
|
||||
void clear(EntityManager& entityManager);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -3,3 +3,60 @@
|
||||
//
|
||||
|
||||
#include "MapGenerator.h"
|
||||
|
||||
float MapGenerator::hexRadius = 10.0f;
|
||||
|
||||
void MapGenerator::init(Loader &loader, float hexRadius) {
|
||||
MapGenerator::hexRadius = hexRadius;
|
||||
auto hexModelNone = HexModelFactory::createTexturedHexModel(loader, hexRadius, RessourceType::NONE);
|
||||
auto hexModelWood = HexModelFactory::createTexturedHexModel(loader, hexRadius, RessourceType::WOOD);
|
||||
auto hexModelStone = HexModelFactory::createTexturedHexModel(loader, hexRadius, RessourceType::STONE);
|
||||
|
||||
AssetManager::insertGeneratedModel("hexModelNone", std::make_shared<TexturedModel>(hexModelNone));
|
||||
AssetManager::insertGeneratedModel("hexModelWood", std::make_shared<TexturedModel>(hexModelWood));
|
||||
AssetManager::insertGeneratedModel("hexModelStone", std::make_shared<TexturedModel>(hexModelStone));
|
||||
}
|
||||
|
||||
void MapGenerator::generateHexMap(Map &map, int width, int height, EntityManager &entityManager) {
|
||||
Random random;
|
||||
|
||||
map.clear(entityManager);
|
||||
|
||||
float xOffset = hexRadius * std::sqrt(3.0f);
|
||||
float zOffset = hexRadius * 1.5f;
|
||||
|
||||
for (int r = 0; r < height; ++r) {
|
||||
for (int q = 0; q < width; ++q) {
|
||||
// Pointy-top Hexes
|
||||
float x = xOffset * (q + 0.5f * (r % 2));
|
||||
float z = zOffset * r;
|
||||
glm::vec3 worldPos = glm::vec3(x, 0.0f, z);
|
||||
float radius = hexRadius;
|
||||
|
||||
float randomValue = random.randomFloat(0.0f, 1.0f);
|
||||
RessourceType resourceType = RessourceType::NONE;
|
||||
std::shared_ptr<TexturedModel> hexModel = AssetManager::getModel("hexModelNone");
|
||||
if (randomValue < 0.5f) {
|
||||
resourceType = RessourceType::WOOD;
|
||||
ForestTileGenerator forestTileGenerator;
|
||||
std::vector<EntityID> entities = forestTileGenerator.generateHexTile(entityManager, random, worldPos);
|
||||
hexModel = AssetManager::getModel("hexModelWood");
|
||||
} else if (randomValue < 0.75f) {
|
||||
resourceType = RessourceType::STONE;
|
||||
hexModel = AssetManager::getModel("hexModelStone");
|
||||
}
|
||||
|
||||
EntityID entityID = entityManager.createEntity();
|
||||
const auto transformComponent = std::make_shared<TransformComponent>(worldPos, glm::vec3(0), 1.0f);
|
||||
const auto modelComponent = std::make_shared<ModelComponent>(hexModel);
|
||||
const auto tileHighlightComponent = std::make_shared<TileRenderComponent>(false);
|
||||
const auto tileGameplayComponent = std::make_shared<TileGameplayComponent>(q, r, radius, resourceType);
|
||||
|
||||
entityManager.addComponent(entityID, transformComponent);
|
||||
entityManager.addComponent(entityID, modelComponent);
|
||||
entityManager.addComponent(entityID, tileHighlightComponent);
|
||||
entityManager.addComponent(entityID, tileGameplayComponent);
|
||||
entityManager.addComponent(entityID, std::make_shared<MapEntityComponent>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,48 +7,25 @@
|
||||
#include <cmath>
|
||||
#include <random>
|
||||
|
||||
#include "HexTile.h"
|
||||
#include "HexModelFactory.h"
|
||||
#include "Map.h"
|
||||
#include "../../engine/core/ECS/ModelComponent.h"
|
||||
#include "../../engine/core/ECS/TileRenderComponent.h"
|
||||
#include "../../engine/core/ECS/TransformComponent.h"
|
||||
#include "../../engine/renderer/model/AssetManager.h"
|
||||
#include "../../engine/toolbox/Random.h"
|
||||
#include "ecs/components/MapEntityComponent.h"
|
||||
#include "ecs/components/TileGameplayComponent.h"
|
||||
#include "tileGenerator/ForestTileGenerator.h"
|
||||
|
||||
|
||||
|
||||
class MapGenerator {
|
||||
private:
|
||||
static float hexRadius;
|
||||
public:
|
||||
static void generateHexMap(Map& map, int width, int height, float hexRadius, std::vector<std::shared_ptr<Entity>>& mapEntities) {
|
||||
// Zufallsgenerator initialisieren (einmal)
|
||||
Random random;
|
||||
|
||||
map.tiles.clear();
|
||||
|
||||
float xOffset = hexRadius * std::sqrt(3.0f);
|
||||
float zOffset = hexRadius * 1.5f;
|
||||
|
||||
for (int r = 0; r < height; ++r) {
|
||||
for (int q = 0; q < width; ++q) {
|
||||
HexTile tile;
|
||||
tile.q = q;
|
||||
tile.r = r;
|
||||
|
||||
// Pointy-top Hexes
|
||||
float x = xOffset * (q + 0.5f * (r % 2));
|
||||
float z = zOffset * r;
|
||||
tile.worldPos = glm::vec3(x, 0.0f, z);
|
||||
tile.radius = hexRadius;
|
||||
|
||||
float randomValue = random.randomFloat(0.0f, 1.0f);
|
||||
if (randomValue < 0.5f) {
|
||||
tile.resourceType = RessourceType::WOOD;
|
||||
ForestTileGenerator forestTileGenerator;
|
||||
const std::vector<std::shared_ptr<Entity>> forestEntities = forestTileGenerator.generateHexTile(random, tile.worldPos, mapEntities);
|
||||
tile.entitiesOnTile = forestEntities;
|
||||
} else if (randomValue < 0.75f) {
|
||||
tile.resourceType = RessourceType::STONE;
|
||||
}
|
||||
map.tiles.push_back(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void init(Loader& loader, float hexRadius);
|
||||
static void generateHexMap(Map& map, int width, int height, EntityManager& entityManager);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
8
src/game/hexWorld/RessourceType.h
Normal file
8
src/game/hexWorld/RessourceType.h
Normal file
@ -0,0 +1,8 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#ifndef RESSOURCETYPE_H
|
||||
#define RESSOURCETYPE_H
|
||||
enum class RessourceType {NONE, WOOD, STONE};
|
||||
#endif //RESSOURCETYPE_H
|
||||
14
src/game/hexWorld/ecs/components/MapEntityComponent.h
Normal file
14
src/game/hexWorld/ecs/components/MapEntityComponent.h
Normal file
@ -0,0 +1,14 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#ifndef MAPENTITYCOMPONENT_H
|
||||
#define MAPENTITYCOMPONENT_H
|
||||
|
||||
|
||||
|
||||
struct MapEntityComponent {};
|
||||
|
||||
|
||||
|
||||
#endif //MAPENTITYCOMPONENT_H
|
||||
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#include "TileGameplayComponent.h"
|
||||
29
src/game/hexWorld/ecs/components/TileGameplayComponent.h
Normal file
29
src/game/hexWorld/ecs/components/TileGameplayComponent.h
Normal file
@ -0,0 +1,29 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#ifndef TILEGAMEPLAYCOMPONENT_H
|
||||
#define TILEGAMEPLAYCOMPONENT_H
|
||||
|
||||
#include "../../../../engine/core/ECS/Component.h"
|
||||
#include "../../../../engine/core/ECS/EntityManager.h"
|
||||
|
||||
|
||||
enum class RessourceType;
|
||||
|
||||
class TileGameplayComponent : public Component {
|
||||
public:
|
||||
int q, r;
|
||||
float radius;
|
||||
RessourceType ressourceType;
|
||||
|
||||
EntityID buildingEntityID = 0;
|
||||
std::vector<EntityID> entitiesOnTile;
|
||||
|
||||
TileGameplayComponent(int q, int r, float radius, RessourceType ressourceType) : q(q), r(r), radius(radius), ressourceType(ressourceType) {};
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //TILEGAMEPLAYCOMPONENT_H
|
||||
42
src/game/hexWorld/ecs/systems/TileHighlightSystem.cpp
Normal file
42
src/game/hexWorld/ecs/systems/TileHighlightSystem.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#include "TileHighlightSystem.h"
|
||||
|
||||
#include "../../../../engine/core/ECS/TileRenderComponent.h"
|
||||
#include "../../../../engine/core/ECS/TransformComponent.h"
|
||||
#include "../components/TileGameplayComponent.h"
|
||||
#include "../../../../engine/layer/entities/Camera.h"
|
||||
|
||||
|
||||
void TileHighlightSystem::update(EntityManager &entityManager, const MousePicker& picker, const Camera& camera) {
|
||||
for (EntityID entityID : entityManager.getAllEntities()) {
|
||||
auto tileRenderComponent = entityManager.getComponent<TileRenderComponent>(entityID);
|
||||
auto transformComponent = entityManager.getComponent<TransformComponent>(entityID);
|
||||
auto tileGameplayComponent = entityManager.getComponent<TileGameplayComponent>(entityID);
|
||||
|
||||
if (!tileRenderComponent || !transformComponent || !tileGameplayComponent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
glm::vec3 rayOrigin = camera.getPosition();
|
||||
glm::vec3 rayDirection = picker.getCurrentRay();
|
||||
glm::vec3 intersectionPoint;
|
||||
if (intersectTile(rayOrigin, rayDirection, transformComponent->position, tileGameplayComponent->radius, intersectionPoint)) {
|
||||
tileRenderComponent->isHighlighted = true;
|
||||
} else {
|
||||
tileRenderComponent->isHighlighted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TileHighlightSystem::intersectTile(const glm::vec3 &rayOrigin, const glm::vec3 &rayDirection, glm::vec3 worldPos, float hexRadius, glm::vec3& intersectionPoint) {
|
||||
float t = -rayOrigin.y / rayDirection.y;
|
||||
if (t < 0) return false;
|
||||
|
||||
intersectionPoint = rayOrigin + rayDirection * t;
|
||||
|
||||
glm::vec2 diff(intersectionPoint.x - worldPos.x, intersectionPoint.z - worldPos.z);
|
||||
return glm::length(diff) <= hexRadius - 0.1f;
|
||||
}
|
||||
20
src/game/hexWorld/ecs/systems/TileHighlightSystem.h
Normal file
20
src/game/hexWorld/ecs/systems/TileHighlightSystem.h
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// Created by sebastian on 08.02.26.
|
||||
//
|
||||
|
||||
#ifndef TILEHIGHLIGHTSYSTEM_H
|
||||
#define TILEHIGHLIGHTSYSTEM_H
|
||||
#include "../../../../engine/core/ECS/EntityManager.h"
|
||||
#include "../../../../engine/platform/glfw/MousePicker.h"
|
||||
class Camera;
|
||||
|
||||
class TileHighlightSystem {
|
||||
public:
|
||||
void update(EntityManager &entityManager, const MousePicker &picker, const Camera &camera);
|
||||
private:
|
||||
bool intersectTile(const glm::vec3 & rayOrigin, const glm::vec3 & rayDirection, glm::vec3 worldPos, float hexRadius, glm::vec3 &interectionPoint);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //TILEHIGHLIGHTSYSTEM_H
|
||||
@ -4,17 +4,18 @@
|
||||
|
||||
#include "ForestTileGenerator.h"
|
||||
|
||||
#include "../../../engine/core/ECS/ModelComponent.h"
|
||||
#include "../../../engine/core/ECS/TransformComponent.h"
|
||||
#include "../../../engine/renderer/model/AssetManager.h"
|
||||
#include "glm/detail/func_geometric.inl"
|
||||
|
||||
|
||||
std::vector<std::shared_ptr<Entity>> ForestTileGenerator::generateHexTile(Random& random, glm::vec3 tilePos, std::vector<std::shared_ptr<Entity>> &mapEntities) const {
|
||||
std::vector<EntityID> ForestTileGenerator::generateHexTile(EntityManager& em, Random& random, glm::vec3 tilePos) const {
|
||||
int treeCount = random.randomInt(minTreeCount, maxTreeCount);
|
||||
|
||||
std::vector<std::shared_ptr<Entity>> entitiesOnTile;
|
||||
std::shared_ptr<TexturedModel> treeModel = AssetManager::getModel("lowPolyTree");
|
||||
std::shared_ptr<TexturedModel> treeModel2 = AssetManager::getModel("lowPolyTree2");
|
||||
std::vector<std::shared_ptr<TexturedModel>> treeModels = {treeModel, treeModel2};
|
||||
std::vector<EntityID> entitiyIDs;
|
||||
for (int i = 0; i < treeCount; ++i) {
|
||||
glm::vec3 treePos;
|
||||
bool validPos = false;
|
||||
@ -28,21 +29,30 @@ std::vector<std::shared_ptr<Entity>> ForestTileGenerator::generateHexTile(Random
|
||||
treePos.z += random.randomFloat(-hexRadius * 0.5f, hexRadius * 0.5f);
|
||||
|
||||
validPos = true;
|
||||
for (const auto& otherTree : entitiesOnTile) {
|
||||
if (glm::distance(treePos, otherTree->getPosition()) < minDistance) {
|
||||
for (const auto& otherTreeID : entitiyIDs) {
|
||||
const auto otherTree = em.getComponent<TransformComponent>(otherTreeID);
|
||||
if (otherTree) {
|
||||
if (glm::distance(treePos, otherTree->position) < minDistance) {
|
||||
validPos = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
attempts++;
|
||||
}
|
||||
|
||||
if (!validPos) continue; // zu viele Versuche, überspringen
|
||||
|
||||
int treeModelIndex = random.randomInt(0, static_cast<int>(treeModels.size()-1));
|
||||
auto treeEntity = std::make_shared<Entity>(treeModels[treeModelIndex], treePos, 0, 0, 0, 1.f);
|
||||
mapEntities.push_back(treeEntity);
|
||||
entitiesOnTile.push_back(treeEntity);
|
||||
|
||||
const auto transformComponent = std::make_shared<TransformComponent>(treePos, glm::vec3(0), 1.f);
|
||||
const auto modelComponent = std::make_shared<ModelComponent>(treeModels[treeModelIndex]);
|
||||
|
||||
const EntityID entityID = em.createEntity();
|
||||
em.addComponent(entityID, transformComponent);
|
||||
em.addComponent(entityID, modelComponent);
|
||||
entitiyIDs.push_back(entityID);
|
||||
}
|
||||
return entitiesOnTile;
|
||||
return entitiyIDs;
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
class ForestTileGenerator : public HexTileGeneratorStrategy {
|
||||
public:
|
||||
std::vector<std::shared_ptr<Entity>> generateHexTile(Random& random, glm::vec3 tilePos, std::vector<std::shared_ptr<Entity>>& mapEntities) const override;
|
||||
std::vector<EntityID> generateHexTile(EntityManager& em, Random& random, glm::vec3 tilePos) const override;
|
||||
private:
|
||||
const int minTreeCount = 3;
|
||||
const int maxTreeCount = 5;
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "../../../engine/core/ECS/EntityManager.h"
|
||||
#include "../../../engine/layer/entities/Entity.h"
|
||||
#include "../../../engine/toolbox/Random.h"
|
||||
|
||||
@ -15,7 +16,7 @@ class HexTileGeneratorStrategy {
|
||||
public:
|
||||
virtual ~HexTileGeneratorStrategy() = default;
|
||||
|
||||
virtual std::vector<std::shared_ptr<Entity>> generateHexTile(Random& random, glm::vec3 tilePos, std::vector<std::shared_ptr<Entity>>& mapEntities) const = 0;
|
||||
virtual std::vector<EntityID> generateHexTile(EntityManager& em, Random& random, glm::vec3 tilePos) const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user