diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d7931e..17b0f91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,6 +71,8 @@ add_executable(Dicewars_Siedler src/main.cpp src/engine/renderer/TerrainRenderer.h src/engine/renderer/shaders/TerrainShader.cpp src/engine/renderer/shaders/TerrainShader.h + src/engine/renderer/model/AssetManager.cpp + src/engine/renderer/model/AssetManager.h ) target_include_directories(Dicewars_Siedler PRIVATE diff --git a/assets/trees/tree.png b/assets/trees/tree.png new file mode 100644 index 0000000..a76bc86 Binary files /dev/null and b/assets/trees/tree.png differ diff --git a/src/engine/renderer/model/AssetManager.cpp b/src/engine/renderer/model/AssetManager.cpp new file mode 100644 index 0000000..37e442f --- /dev/null +++ b/src/engine/renderer/model/AssetManager.cpp @@ -0,0 +1,25 @@ +// +// Created by sebastian on 08.02.26. +// + +#include "AssetManager.h" + +#include + +#include "../loader/OBJLoader.h" + + +std::shared_ptr AssetManager::loadModel(const std::string &name, const std::string &objPath, const std::string &texturePath, Loader &loader) { + if (models.contains(name)) { + return models[name]; + } + + auto model = OBJLoader::loadModel(objPath, texturePath, loader); + models[name] = model; + return model; +} + +std::shared_ptr AssetManager::getModel(const std::string &name) { + assert(models.contains(name) && "Model not found!"); + return models.at(name); +} diff --git a/src/engine/renderer/model/AssetManager.h b/src/engine/renderer/model/AssetManager.h new file mode 100644 index 0000000..171749c --- /dev/null +++ b/src/engine/renderer/model/AssetManager.h @@ -0,0 +1,24 @@ +// +// Created by sebastian on 08.02.26. +// + +#ifndef ASSETMANAGER_H +#define ASSETMANAGER_H +#include +#include + +#include "TexturedModel.h" +#include "../loader/Loader.h" + + +class AssetManager { +public: + static std::shared_ptr loadModel(const std::string& name, const std::string& objPath, const std::string& texturePath, Loader& loader); + static std::shared_ptr getModel(const std::string& name); +private: + static inline std::unordered_map> models; +}; + + + +#endif //ASSETMANAGER_H diff --git a/src/game/GameLayer.cpp b/src/game/GameLayer.cpp index cec13f5..c6c6041 100644 --- a/src/game/GameLayer.cpp +++ b/src/game/GameLayer.cpp @@ -11,6 +11,7 @@ #include "../engine/renderer/textures/ModelTexture.h" #include "../engine/toolbox/MathUtils.h" #include "../engine/layer/entities/Light.h" +#include "../engine/renderer/model/AssetManager.h" #include "hexWorld/HexModelFactory.h" #include "hexWorld/MapGenerator.h" @@ -31,9 +32,12 @@ void GameLayer::onAttach() hexModelWood = std::make_shared(HexModelFactory::createTexturedHexModel(loader, 10.0f, RessourceType::WOOD)); map = std::make_unique(); - treeModel = std::make_unique(*OBJLoader::loadModel("assets/trees/lowPolyTree.obj", "assets/trees/lowPolyTree.png", loader)); - treeEntity = std::make_unique(Entity(treeModel, glm::vec3(0,0,0), 0,0,0, 0.5f)); - MapGenerator::generateHexMap(*map, 10,10,10.f, mapEntities, treeModel); + AssetManager::loadModel("lowPolyTree", "assets/trees/lowPolyTree.obj", "assets/trees/lowPolyTree.png", loader); + AssetManager::loadModel("lowPolyTree2", "assets/trees/tree.obj", "assets/trees/tree.png", loader); + + //treeModel = std::make_unique(*OBJLoader::loadModel("assets/trees/lowPolyTree.obj", "assets/trees/lowPolyTree.png", loader)); + //treeEntity = std::make_unique(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()); } diff --git a/src/game/GameLayer.h b/src/game/GameLayer.h index ad00cf1..e5ccafc 100644 --- a/src/game/GameLayer.h +++ b/src/game/GameLayer.h @@ -36,8 +36,6 @@ private: std::shared_ptr hexModelWood; std::vector> tileEntities; - std::shared_ptr treeModel; - std::unique_ptr treeEntity; std::vector> mapEntities; std::unique_ptr map; diff --git a/src/game/hexWorld/MapGenerator.h b/src/game/hexWorld/MapGenerator.h index b1ed0e4..2a248eb 100644 --- a/src/game/hexWorld/MapGenerator.h +++ b/src/game/hexWorld/MapGenerator.h @@ -9,10 +9,11 @@ #include "HexTile.h" #include "Map.h" +#include "../../engine/renderer/model/AssetManager.h" class MapGenerator { public: - static void generateHexMap(Map& map, int width, int height, float hexRadius, std::vector>& mapEntities, const std::shared_ptr& treeModel) { + static void generateHexMap(Map& map, int width, int height, float hexRadius, std::vector>& mapEntities) { // Zufallsgenerator initialisieren (einmal) std::random_device rd; // Zufälliger Seed std::mt19937 gen(rd()); // Mersenne Twister Generator @@ -24,6 +25,12 @@ public: float xOffset = hexRadius * std::sqrt(3.0f); float zOffset = hexRadius * 1.5f; + std::shared_ptr treeModel = AssetManager::getModel("lowPolyTree"); + std::shared_ptr treeModel2 = AssetManager::getModel("lowPolyTree2"); + std::vector> treeModels = {treeModel, treeModel2}; + + std::uniform_int_distribution treeModelDistribution(0, treeModels.size() - 1); + for (int r = 0; r < height; ++r) { for (int q = 0; q < width; ++q) { HexTile tile; @@ -43,17 +50,40 @@ public: int treeCount = 3 + (int) (dis(gen) * 3); std::uniform_real_distribution offsetDis(-hexRadius * 0.5f, hexRadius * 0.5f); + float minDistance = 3.0f; // Minimaler Abstand zwischen Bäumen + for (int i = 0; i < treeCount; ++i) { - glm::vec3 treePos = tile.worldPos; - treePos.x += offsetDis(gen); - treePos.z += offsetDis(gen); + glm::vec3 treePos; + bool validPos = false; - std::shared_ptr treeEntity = std::make_shared(Entity(treeModel, treePos, 0,0,0,.4f)); + // versuche zufällige Position, bis Abstand stimmt oder max Versuche erreicht + int attempts = 0; + const int maxAttempts = 10; + while (!validPos && attempts < maxAttempts) { + treePos = tile.worldPos; + treePos.x += offsetDis(gen); + treePos.z += offsetDis(gen); + + validPos = true; + for (const auto& otherTree : tile.entitiesOnTile) { + if (glm::distance(treePos, otherTree->getPosition()) < minDistance) { + validPos = false; + break; + } + } + attempts++; + } + + if (!validPos) continue; // zu viele Versuche, überspringen + + int treeModelIndex = treeModelDistribution(gen); + auto treeEntity = std::make_shared(treeModels[treeModelIndex], treePos, 0, 0, 0, 1.f); mapEntities.push_back(treeEntity); tile.entitiesOnTile.push_back(treeEntity); } + } map.tiles.push_back(tile);