Dicewars-Siedler/src/engine/renderer/loader/AssetManager.cpp
Sebastian Böckelmann 89e98d0f88
All checks were successful
Tests / test (push) Successful in 3m2s
ADD: Upload Intermediate Assets to GPU, closes #18
2026-04-21 09:05:09 +02:00

165 lines
6.1 KiB
C++

//
// Created by sebastian on 08.02.26.
//
#include "AssetManager.h"
#include <cassert>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <utility>
#include "json.hpp"
#include "OBJLoader.h"
#include "spdlog/spdlog.h"
namespace fs = std::filesystem;
using namespace nlohmann;
std::shared_ptr<TexturedModel> 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<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);
}
void AssetManager::loadAsset(const std::string &assetPath, Loader &loader) {
json assetConfiguration = readJsonFile(assetPath);
ModelStages modelStages;
std::string baseDir = std::filesystem::path(assetPath).parent_path().string();
for (const auto& modelStage : assetConfiguration["modelStages"]) {
auto name = modelStage["name"].get<std::string>();
auto objPath = modelStage["filename"].get<std::string>();
const auto conditionKey = modelStage["conditionKey"].get<std::string>();
const float min = modelStage["minValue"].get<float>();
const float max = modelStage["maxValue"].get<float>();
std::filesystem::path fullObjPath = std::filesystem::path(baseDir) / std::filesystem::path(objPath);
const std::shared_ptr<TexturedModel> model = loadModel(name, fullObjPath, "", loader);
const auto condition = ModelStageCondition(conditionKey, min, max);
modelStages.addModelStage(ModelStageConfiguration(model, name, condition));
}
modelsWithStages[assetConfiguration["name"].get<std::string>()] = std::make_shared<ModelStages>(modelStages);
}
std::shared_ptr<ModelStages> AssetManager::getModelStages(const std::string &modelName) {
if (modelsWithStages.contains(modelName)) {
return modelsWithStages[modelName];
}
return nullptr;
}
std::shared_ptr<ModelStageConfiguration> AssetManager::getModelStageConfiguration(const std::string &modelName, const std::string &stageName) {
if (const auto modelStages = getModelStages(modelName)) {
return std::make_shared<ModelStageConfiguration>(modelStages->getModelStageConfiguration(stageName));
}
return nullptr;
}
std::shared_ptr<ModelTexture> AssetManager::loadTexture(const std::string& name, const std::string &texturePath, Loader &loader) {
if (textures.contains(name)) {
return textures[name];
}
auto texture = std::make_shared<ModelTexture>(loader.loadTextureFromFile(texturePath));
textures[name] = texture;
return texture;
}
std::shared_ptr<ModelTexture> AssetManager::getTexture(const std::string &name) {
assert(textures.contains(name) && "Texture not found!");
return textures.at(name);
}
std::shared_ptr<UiTheme> AssetManager::getUiTheme(const std::string &themeName) {
assert(uiThemes.contains(themeName) && "Theme not found!");
return uiThemes.at(themeName);
}
std::shared_ptr<UiTheme> AssetManager::loadUiTheme(const std::string &themeName, const std::string &themePath) {
if (!uiThemes.contains(themeName)) {
json themeConfiguration = readJsonFile(themePath);
if (themeConfiguration.contains("font")) {
auto fontData = themeConfiguration["font"];
if (fontData.contains("path") && fontData.contains("sizes")) {
auto fontSizes = fontData["sizes"];
if (fontSizes.contains("small") && fontSizes.contains("medium") && fontSizes.contains("large")) {
std::string fontPath = fontData["path"].get<std::string>();
auto theme = std::make_shared<UiTheme>(
std::make_unique<Font>(fontPath, fontSizes["small"]),
std::make_unique<Font>(fontPath, fontSizes["medium"]),
std::make_unique<Font>(fontPath, fontSizes["large"])
);
uiThemes[themeName] = theme;
return theme;
} else {
std::cerr << "Required Font sizes not found in theme configuration!" << std::endl;
return nullptr;
}
} else {
std::cerr << "Required Font path not found in theme configuration!" << std::endl;
return nullptr;
}
} else {
std::cerr << "Required Font configuration not found in theme configuration!" << std::endl;
return nullptr;
}
} else {
return uiThemes[themeName];
}
}
void AssetManager::insertLoadedTexture(const std::string &name, const Texture2D &texture) {
if (textures.contains(name)) {
spdlog::warn("Texture '{}' already exists, skipping insert", name);
return;
}
textures[name] = std::make_shared<ModelTexture>(texture.id);
spdlog::debug("Texture '{}' inserted successfully", name);
}
void AssetManager::insertTexturedModel(const std::string &name, const TexturedModel &textured_model) {
if (models.contains(name)) {
spdlog::warn("Model '{}' already exists, skipping insert", name);
return;
}
models[name] = std::make_shared<TexturedModel>(textured_model);
spdlog::debug("Model '{}' inserted successfully", name);
}
void AssetManager::insertModelStages(const std::string &name, ModelStages modelStages) {
if (modelsWithStages.contains(name)) {
spdlog::warn("Asset '{}' already has stages, skipping insert", name);
return;
}
modelsWithStages[name] = std::make_shared<ModelStages>(modelStages);
}
json AssetManager::readJsonFile(const std::string &path) {
if (fs::exists(path)) {
std::ifstream filestream(path);
json j;
filestream >> j;
return j;
}
return json::object();
}