add BlockModel struct

This commit is contained in:
MihailRis 2025-04-27 18:21:56 +03:00
parent 718f5d1089
commit 20e3a961f9
12 changed files with 46 additions and 39 deletions

View File

@ -257,12 +257,12 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) {
}
}
for (const auto& [_, def] : content->blocks.getDefs()) {
if (!def->modelName.empty() &&
def->modelName.find(':') == std::string::npos) {
if (!def->model.name.empty() &&
def->model.name.find(':') == std::string::npos) {
loader.add(
AssetType::MODEL,
MODELS_FOLDER + "/" + def->modelName,
def->modelName
MODELS_FOLDER + "/" + def->model.name,
def->model.name
);
}
}

View File

@ -28,7 +28,7 @@ std::unique_ptr<Content> ContentBuilder::build() {
// Generating runtime info
def.rt.id = blockDefsIndices.size();
def.rt.emissive = *reinterpret_cast<uint32_t*>(def.emission);
def.rt.solid = def.model == BlockModelType::BLOCK;
def.rt.solid = def.model.type == BlockModelType::BLOCK;
def.rt.extended = def.size.x > 1 || def.size.y > 1 || def.size.z > 1;
const float EPSILON = 0.01f;

View File

@ -86,20 +86,23 @@ template<> void ContentUnitLoader<Block>::loadUnit(
}
// block model
std::string modelTypeName = BlockModelTypeMeta.getNameString(def.model);
auto& model = def.model;
std::string modelTypeName = BlockModelTypeMeta.getNameString(model.type);
root.at("model").get(modelTypeName);
root.at("model-name").get(def.modelName);
if (BlockModelTypeMeta.getItem(modelTypeName, def.model)) {
if (def.model == BlockModelType::CUSTOM && def.customModelRaw == nullptr) {
root.at("model-name").get(def.model.name);
if (BlockModelTypeMeta.getItem(modelTypeName, model.type)) {
if (model.type == BlockModelType::CUSTOM && def.model.customRaw == nullptr) {
if (root.has("model-primitives")) {
def.customModelRaw = root["model-primitives"];
} else if (def.modelName.empty()) {
throw std::runtime_error(name + ": no 'model-primitives' or 'model-name' found");
def.model.customRaw = root["model-primitives"];
} else if (def.model.name.empty()) {
throw std::runtime_error(
name + ": no 'model-primitives' or 'model-name' found"
);
}
}
} else if (!modelTypeName.empty()) {
logger.error() << "unknown model: " << modelTypeName;
def.model = BlockModelType::NONE;
model.type = BlockModelType::NONE;
}
std::string cullingModeName = CullingModeMeta.getNameString(def.culling);
@ -171,9 +174,9 @@ template<> void ContentUnitLoader<Block>::loadUnit(
"block " + util::quote(def.name) + ": invalid block size"
);
}
if (def.model == BlockModelType::BLOCK &&
if (model.type == BlockModelType::BLOCK &&
(def.size.x != 1 || def.size.y != 1 || def.size.z != 1)) {
def.model = BlockModelType::AABB;
model.type = BlockModelType::AABB;
def.hitboxes = {AABB(def.size)};
}
}

View File

@ -19,7 +19,7 @@ void corecontent::setup(Input& input, ContentBuilder& builder) {
block.skyLightPassing = true;
block.obstacle = false;
block.selectable = false;
block.model = BlockModelType::NONE;
block.model.type = BlockModelType::NONE;
block.pickingItem = CORE_EMPTY;
}
{

View File

@ -35,10 +35,10 @@ void ContentGfxCache::refresh(const Block& def, const Atlas& atlas) {
sideregions[def.rt.id * 6 + side] = atlas.get(TEXTURE_NOTFOUND);
}
}
if (def.model == BlockModelType::CUSTOM) {
auto model = assets.require<model::Model>(def.modelName);
if (def.model.type == BlockModelType::CUSTOM) {
auto model = assets.require<model::Model>(def.model.name);
// temporary dirty fix tbh
if (def.modelName.find(':') == std::string::npos) {
if (def.model.name.find(':') == std::string::npos) {
for (auto& mesh : model.meshes) {
size_t pos = mesh.texture.find(':');
if (pos == std::string::npos) {

View File

@ -44,7 +44,7 @@ void BlockWrapsRenderer::draw(const BlockWrapper& wrapper) {
}
if (vox->id != BLOCK_VOID) {
const auto& def = level.content.getIndices()->blocks.require(vox->id);
switch (def.model) {
switch (def.model.type) {
case BlockModelType::BLOCK:
batch->cube(
glm::vec3(wrapper.position) + glm::vec3(0.5f),

View File

@ -32,7 +32,7 @@ std::unique_ptr<ImageData> BlocksPreview::draw(
cache.getRegion(id, 4), cache.getRegion(id, 5)};
glm::vec3 offset(0.1f, 0.5f, 0.1f);
switch (def.model) {
switch (def.model.type) {
case BlockModelType::NONE:
// something went wrong...
break;

View File

@ -453,7 +453,7 @@ void BlocksRenderer::render(
int x = i % CHUNK_W;
int y = i / (CHUNK_D * CHUNK_W);
int z = (i / CHUNK_D) % CHUNK_W;
switch (def.model) {
switch (def.model.type) {
case BlockModelType::BLOCK:
blockCube({x, y, z}, texfaces, def, vox.state, !def.shadeless,
def.ambientOcclusion);
@ -516,7 +516,7 @@ SortingMeshData BlocksRenderer::renderTranslucent(
int x = i % CHUNK_W;
int y = i / (CHUNK_D * CHUNK_W);
int z = (i / CHUNK_D) % CHUNK_W;
switch (def.model) {
switch (def.model.type) {
case BlockModelType::BLOCK:
blockCube({x, y, z}, texfaces, def, vox.state, !def.shadeless,
def.ambientOcclusion);

View File

@ -50,16 +50,16 @@ static inline UVRegion get_region_for(
void ModelsGenerator::prepare(Content& content, Assets& assets) {
for (auto& [name, def] : content.blocks.getDefs()) {
if (def->model == BlockModelType::CUSTOM && def->modelName.empty()) {
if (def->model.type == BlockModelType::CUSTOM && def->model.name.empty()) {
assets.store(
std::make_unique<model::Model>(
loadCustomBlockModel(
def->customModelRaw, assets, !def->shadeless
def->model.customRaw, assets, !def->shadeless
)
),
name + ".model"
);
def->modelName = def->name + ".model";
def->model.name = def->name + ".model";
}
}
for (auto& [name, def] : content.items.getDefs()) {
@ -131,12 +131,12 @@ model::Model ModelsGenerator::generate(
if (def.iconType == ItemIconType::BLOCK) {
auto model = assets.require<model::Model>("block");
const auto& blockDef = content.blocks.require(def.icon);
if (blockDef.model == BlockModelType::XSPRITE) {
if (blockDef.model.type == BlockModelType::XSPRITE) {
return create_flat_model(
"blocks:" + blockDef.textureFaces.at(0), assets
);
} else if (blockDef.model == BlockModelType::CUSTOM) {
model = assets.require<model::Model>(blockDef.modelName);
} else if (blockDef.model.type == BlockModelType::CUSTOM) {
model = assets.require<model::Model>(blockDef.model.name);
for (auto& mesh : model.meshes) {
mesh.scale(glm::vec3(0.2f));
}
@ -144,7 +144,7 @@ model::Model ModelsGenerator::generate(
}
for (auto& mesh : model.meshes) {
mesh.lighting = !blockDef.shadeless;
switch (blockDef.model) {
switch (blockDef.model.type) {
case BlockModelType::AABB: {
glm::vec3 size = blockDef.hitboxes.at(0).size();
float m = glm::max(size.x, glm::max(size.y, size.z));

View File

@ -312,7 +312,7 @@ static int l_get_textures(lua::State* L) {
static int l_get_model(lua::State* L) {
if (auto def = require_block(L)) {
return lua::pushlstring(L, BlockModelTypeMeta.getName(def->model));
return lua::pushlstring(L, BlockModelTypeMeta.getName(def->model.type));
}
return 0;
}

View File

@ -143,7 +143,6 @@ void Block::cloneTo(Block& dst) {
if (particles) {
dst.particles = std::make_unique<ParticlesPreset>(*particles);
}
dst.customModelRaw = customModelRaw;
}
static std::set<std::string, std::less<>> RESERVED_BLOCK_FIELDS {

View File

@ -94,6 +94,16 @@ enum class BlockModelType {
CUSTOM
};
struct BlockModel {
BlockModelType type = BlockModelType::BLOCK;
/// @brief Custom model raw data
dv::value customRaw = nullptr;
/// @brief Custom model name (generated or an asset)
std::string name = "";
};
VC_ENUM_METADATA(BlockModelType)
{"none", BlockModelType::NONE},
{"block", BlockModelType::BLOCK},
@ -152,13 +162,8 @@ public:
/// @brief Influences visible block sides for transparent blocks
uint8_t drawGroup = 0;
/// @brief Block model type
BlockModelType model = BlockModelType::BLOCK;
/// @brief Custom model raw data
dv::value customModelRaw = nullptr;
std::string modelName = "";
/// @brief Block model
BlockModel model {};
/// @brief Culling mode
CullingMode culling = CullingMode::DEFAULT;