mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-08 04:21:50 +00:00
Merge branch 'main' into volume-renderer
This commit is contained in:
commit
b2df0a7e91
28 changed files with 642 additions and 184 deletions
|
|
@ -24,7 +24,8 @@ enum class AssetType {
|
|||
LAYOUT,
|
||||
SOUND,
|
||||
MODEL,
|
||||
POST_EFFECT
|
||||
POST_EFFECT,
|
||||
SKELETON
|
||||
};
|
||||
|
||||
namespace assetload {
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
#include "AssetsLoader.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "coders/imageio.hpp"
|
||||
#include "assetload_funcs.hpp"
|
||||
#include "Assets.hpp"
|
||||
#include "coders/commons.hpp"
|
||||
#include "coders/imageio.hpp"
|
||||
#include "constants.hpp"
|
||||
#include "content/Content.hpp"
|
||||
#include "content/ContentPack.hpp"
|
||||
#include "debug/Logger.hpp"
|
||||
#include "engine/Engine.hpp"
|
||||
#include "engine/EnginePaths.hpp"
|
||||
#include "io/io.hpp"
|
||||
#include "graphics/core/Texture.hpp"
|
||||
#include "io/io.hpp"
|
||||
#include "items/ItemDef.hpp"
|
||||
#include "logic/scripting/scripting.hpp"
|
||||
#include "objects/EntityDef.hpp"
|
||||
#include "objects/rigging.hpp"
|
||||
#include "util/ThreadPool.hpp"
|
||||
#include "voxels/Block.hpp"
|
||||
#include "items/ItemDef.hpp"
|
||||
#include "Assets.hpp"
|
||||
#include "assetload_funcs.hpp"
|
||||
#include "engine/Engine.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
|
|
@ -36,6 +36,7 @@ AssetsLoader::AssetsLoader(Engine& engine, Assets& assets, const ResPaths& paths
|
|||
addLoader(AssetType::SOUND, assetload::sound);
|
||||
addLoader(AssetType::MODEL, assetload::model);
|
||||
addLoader(AssetType::POST_EFFECT, assetload::posteffect);
|
||||
addLoader(AssetType::SKELETON, assetload::skeleton);
|
||||
}
|
||||
|
||||
void AssetsLoader::addLoader(AssetType tag, aloader_func func) {
|
||||
|
|
@ -141,6 +142,8 @@ static std::string assets_def_folder(AssetType tag) {
|
|||
return MODELS_FOLDER;
|
||||
case AssetType::POST_EFFECT:
|
||||
return POST_EFFECTS_FOLDER;
|
||||
case AssetType::SKELETON:
|
||||
return SKELETONS_FOLDER;
|
||||
}
|
||||
return "<error>";
|
||||
}
|
||||
|
|
@ -178,6 +181,12 @@ void AssetsLoader::processPreload(
|
|||
config = std::make_shared<PostEffectCfg>(advanced);
|
||||
break;
|
||||
}
|
||||
case AssetType::MODEL: {
|
||||
bool squashed = false;
|
||||
map.at("squash").get(squashed);
|
||||
config = std::make_shared<ModelCfg>(squashed);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -211,6 +220,7 @@ void AssetsLoader::processPreloadConfig(const io::path& file) {
|
|||
processPreloadList(AssetType::SOUND, root["sounds"]);
|
||||
processPreloadList(AssetType::MODEL, root["models"]);
|
||||
processPreloadList(AssetType::POST_EFFECT, root["post-effects"]);
|
||||
processPreloadList(AssetType::SKELETON, root["skeletons"]);
|
||||
// layouts are loaded automatically
|
||||
}
|
||||
|
||||
|
|
@ -263,21 +273,20 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) {
|
|||
add_layouts(pack->getEnvironment(), info.id, folder, loader);
|
||||
}
|
||||
|
||||
for (auto& entry : content->getSkeletons()) {
|
||||
auto& skeleton = *entry.second;
|
||||
for (auto& bone : skeleton.getBones()) {
|
||||
std::string model = bone->model.name;
|
||||
size_t pos = model.rfind('.');
|
||||
if (pos != std::string::npos) {
|
||||
model = model.substr(0, pos);
|
||||
}
|
||||
if (!model.empty()) {
|
||||
loader.add(
|
||||
AssetType::MODEL, MODELS_FOLDER + "/" + model, model
|
||||
);
|
||||
}
|
||||
for (const auto& entry : content->getPacks()) {
|
||||
io::path skeletonsDir = entry.first + ":skeletons";
|
||||
if (!io::is_directory(skeletonsDir)) {
|
||||
continue;
|
||||
}
|
||||
for (const auto& file : io::directory_iterator(skeletonsDir)) {
|
||||
loader.add(
|
||||
AssetType::SKELETON,
|
||||
file.string(),
|
||||
entry.first + ":" + file.stem()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& [_, def] : content->blocks.getDefs()) {
|
||||
if (def->variants) {
|
||||
for (const auto& variant : def->variants->variants) {
|
||||
|
|
@ -296,6 +305,16 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) {
|
|||
);
|
||||
}
|
||||
}
|
||||
for (const auto& [_, def] : content->entities.getDefs()) {
|
||||
if (def->skeletonName.find(':') == std::string::npos) {
|
||||
// expecting a VCM with skeleton
|
||||
loader.add(
|
||||
AssetType::MODEL,
|
||||
MODELS_FOLDER + "/" + def->skeletonName,
|
||||
def->skeletonName
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,12 @@ struct PostEffectCfg : AssetCfg {
|
|||
PostEffectCfg(bool advanced) : advanced(advanced) {}
|
||||
};
|
||||
|
||||
struct ModelCfg : AssetCfg {
|
||||
bool squashed;
|
||||
|
||||
ModelCfg(bool squashed) : squashed(squashed) {}
|
||||
};
|
||||
|
||||
using aloader_func = std::function<
|
||||
assetload::
|
||||
postfunc(AssetsLoader*, const ResPaths&, const std::string&, const std::string&, std::shared_ptr<AssetCfg>)>;
|
||||
|
|
|
|||
|
|
@ -325,13 +325,31 @@ assetload::postfunc assetload::model(
|
|||
const ResPaths& paths,
|
||||
const std::string& file,
|
||||
const std::string& name,
|
||||
const std::shared_ptr<AssetCfg>&
|
||||
const std::shared_ptr<AssetCfg>& config
|
||||
) {
|
||||
auto cfg = std::dynamic_pointer_cast<ModelCfg>(config);
|
||||
|
||||
auto path = paths.find(file + ".vec3");
|
||||
if (io::exists(path)) {
|
||||
auto bytes = io::read_bytes_buffer(path);
|
||||
auto modelVEC3 = std::make_shared<vec3::File>(vec3::load(path.string(), bytes));
|
||||
return [loader, name, modelVEC3=std::move(modelVEC3)](Assets* assets) {
|
||||
return [loader, name, cfg, modelVEC3=std::move(modelVEC3)](Assets* assets) {
|
||||
if (cfg && cfg->squashed) {
|
||||
model::Model fullModel;
|
||||
for (auto& entry : modelVEC3->models) {
|
||||
auto& vec3model = entry.second;
|
||||
auto& model = vec3model.model;
|
||||
model.translate(vec3model.origin);
|
||||
fullModel.merge(std::move(model));
|
||||
}
|
||||
request_textures(loader, fullModel);
|
||||
assets->store(
|
||||
std::make_unique<model::Model>(fullModel),
|
||||
name
|
||||
);
|
||||
logger.info() << "store model " << util::quote(name);
|
||||
return;
|
||||
}
|
||||
for (auto& [modelName, model] : modelVEC3->models) {
|
||||
request_textures(loader, model.model);
|
||||
std::string fullName = name;
|
||||
|
|
@ -381,18 +399,76 @@ assetload::postfunc assetload::model(
|
|||
|
||||
auto text = io::read_string(path);
|
||||
try {
|
||||
auto model = vcm::parse(path.string(), text, path.extension() == ".xml")
|
||||
.release();
|
||||
return [=](Assets* assets) {
|
||||
request_textures(loader, *model);
|
||||
assets->store(std::unique_ptr<model::Model>(model), name);
|
||||
};
|
||||
auto vcmModel = vcm::parse(path.string(), text, path.extension() == ".xml");
|
||||
|
||||
assert(vcmModel.parts.size() > 0);
|
||||
|
||||
if (vcmModel.parts.size() == 1 || (cfg && cfg->squashed)) {
|
||||
auto modelPtr = std::make_unique<model::Model>(std::move(vcmModel.squash())).release();
|
||||
return [=](Assets* assets) {
|
||||
auto model = std::unique_ptr<model::Model>(modelPtr);
|
||||
request_textures(loader, *model);
|
||||
assets->store(std::move(model), name);
|
||||
logger.info() << "store model " << util::quote(name);
|
||||
};
|
||||
} else {
|
||||
auto vcmModelPtr = std::make_unique<vcm::VcmModel>(std::move(vcmModel)).release();
|
||||
return [=](Assets* assets) {
|
||||
auto vcmModel = std::unique_ptr<vcm::VcmModel>(vcmModelPtr);
|
||||
for (auto& [partName, model] : vcmModel->parts) {
|
||||
auto fullName = name + "." + partName;
|
||||
logger.info()
|
||||
<< "store model part " << util::quote(partName)
|
||||
<< " as " << util::quote(fullName);
|
||||
assets->store(
|
||||
std::make_unique<model::Model>(std::move(model)),
|
||||
fullName
|
||||
);
|
||||
}
|
||||
for (auto& bone : vcmModel->skeleton->getBones()) {
|
||||
bone->setModel(name + "." + bone->model.name);
|
||||
}
|
||||
logger.info() << "store skeleton " << util::quote(name);
|
||||
assets->store<rigging::SkeletonConfig>(
|
||||
std::make_unique<rigging::SkeletonConfig>(
|
||||
std::move(*vcmModel->skeleton)
|
||||
),
|
||||
name
|
||||
);
|
||||
};
|
||||
}
|
||||
} catch (const parsing_error& err) {
|
||||
std::cerr << err.errorLog() << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
assetload::postfunc assetload::skeleton(
|
||||
AssetsLoader* loader,
|
||||
const ResPaths& paths,
|
||||
const std::string& file,
|
||||
const std::string& name,
|
||||
const std::shared_ptr<AssetCfg>& settings
|
||||
) {
|
||||
return [=](auto assets) {
|
||||
std::string text = io::read_string(file);
|
||||
auto skeleton = rigging::SkeletonConfig::parse(text, file, name);
|
||||
for (auto& bone : skeleton->getBones()) {
|
||||
std::string model = bone->model.name;
|
||||
size_t pos = model.rfind('.');
|
||||
if (pos != std::string::npos) {
|
||||
model = model.substr(0, pos);
|
||||
}
|
||||
if (!model.empty()) {
|
||||
loader->add(
|
||||
AssetType::MODEL, MODELS_FOLDER + "/" + model, model
|
||||
);
|
||||
}
|
||||
}
|
||||
assets->store(std::move(skeleton), name);
|
||||
};
|
||||
}
|
||||
|
||||
static void read_anim_file(
|
||||
const std::string& animFile,
|
||||
std::vector<std::pair<std::string, int>>& frameList
|
||||
|
|
|
|||
|
|
@ -69,4 +69,12 @@ namespace assetload {
|
|||
const std::string& name,
|
||||
const std::shared_ptr<AssetCfg>& settings
|
||||
);
|
||||
|
||||
postfunc skeleton(
|
||||
AssetsLoader*,
|
||||
const ResPaths& paths,
|
||||
const std::string& file,
|
||||
const std::string& name,
|
||||
const std::shared_ptr<AssetCfg>& settings
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue