feat: item models generation simple & remove core:item_models
This commit is contained in:
parent
7a5fe3b2b0
commit
fae372d19f
@ -1,5 +1,3 @@
|
|||||||
local item_models = require "core:item_models"
|
|
||||||
|
|
||||||
local tsf = entity.transform
|
local tsf = entity.transform
|
||||||
local body = entity.rigidbody
|
local body = entity.rigidbody
|
||||||
local rig = entity.skeleton
|
local rig = entity.skeleton
|
||||||
@ -27,7 +25,7 @@ end
|
|||||||
|
|
||||||
do -- setup visuals
|
do -- setup visuals
|
||||||
local matrix = mat4.idt()
|
local matrix = mat4.idt()
|
||||||
scale = item_models.setup(dropitem.id, rig, 0)
|
rig:set_model(0, item.name(dropitem.id)..".model")
|
||||||
local bodysize = math.min(scale[1], scale[2], scale[3]) * DROP_SCALE
|
local bodysize = math.min(scale[1], scale[2], scale[3]) * DROP_SCALE
|
||||||
body:set_size({scale[1] * DROP_SCALE, bodysize, scale[3] * DROP_SCALE})
|
body:set_size({scale[1] * DROP_SCALE, bodysize, scale[3] * DROP_SCALE})
|
||||||
mat4.mul(matrix, rotation, matrix)
|
mat4.mul(matrix, rotation, matrix)
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
local item_models = require "core:item_models"
|
|
||||||
|
|
||||||
local tsf = entity.transform
|
local tsf = entity.transform
|
||||||
local body = entity.rigidbody
|
local body = entity.rigidbody
|
||||||
local rig = entity.skeleton
|
local rig = entity.skeleton
|
||||||
@ -9,12 +7,7 @@ local itemIndex = rig:index("item")
|
|||||||
|
|
||||||
local function refresh_model(id)
|
local function refresh_model(id)
|
||||||
itemid = id
|
itemid = id
|
||||||
if id == 0 then
|
rig:set_model(itemIndex, item.name(itemid)..".model")
|
||||||
rig:set_model(itemIndex, "")
|
|
||||||
else
|
|
||||||
local scale = item_models.setup(itemid, rig, itemIndex)
|
|
||||||
rig:set_matrix(itemIndex, mat4.scale(scale))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function on_render()
|
function on_render()
|
||||||
|
|||||||
@ -1,33 +0,0 @@
|
|||||||
local function setup(id, rig, index)
|
|
||||||
rig:set_model(index, "drop-block")
|
|
||||||
local icon = item.icon(id)
|
|
||||||
local size = {1.0, 1.0, 1.0}
|
|
||||||
if icon:find("^block%-previews%:") then
|
|
||||||
local bid = block.index(icon:sub(16))
|
|
||||||
model = block.get_model(bid)
|
|
||||||
if model == "X" then
|
|
||||||
size = {1.0, 0.3, 1.0}
|
|
||||||
rig:set_model(index, "drop-item")
|
|
||||||
rig:set_texture("$0", icon)
|
|
||||||
else
|
|
||||||
if model == "aabb" then
|
|
||||||
local rot = block.get_rotation_profile(bid) == "pipe" and 4 or 0
|
|
||||||
size = block.get_hitbox(bid, rot)[2]
|
|
||||||
vec3.mul(size, 2.0, size)
|
|
||||||
end
|
|
||||||
local textures = block.get_textures(bid)
|
|
||||||
for i,t in ipairs(textures) do
|
|
||||||
rig:set_texture("$"..tostring(i-1), "blocks:"..textures[i])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
size = {1.0, 0.3, 1.0}
|
|
||||||
rig:set_model(index, "drop-item")
|
|
||||||
rig:set_texture("$0", icon)
|
|
||||||
end
|
|
||||||
return size
|
|
||||||
end
|
|
||||||
|
|
||||||
return {
|
|
||||||
setup=setup,
|
|
||||||
}
|
|
||||||
@ -5,11 +5,13 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
#include <typeindex>
|
#include <typeindex>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "util/stringutil.hpp"
|
||||||
#include "graphics/core/TextureAnimation.hpp"
|
#include "graphics/core/TextureAnimation.hpp"
|
||||||
|
|
||||||
class Assets;
|
class Assets;
|
||||||
@ -84,6 +86,15 @@ public:
|
|||||||
return static_cast<T*>(found->second.get());
|
return static_cast<T*>(found->second.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T& require(const std::string& name) const {
|
||||||
|
T* asset = get<T>(name);
|
||||||
|
if (asset == nullptr) {
|
||||||
|
throw std::runtime_error(util::quote(name) + " not found");
|
||||||
|
}
|
||||||
|
return *asset;
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
std::optional<const assets_map*> getMap() const {
|
std::optional<const assets_map*> getMap() const {
|
||||||
const auto& mapIter = assets.find(typeid(T));
|
const auto& mapIter = assets.find(typeid(T));
|
||||||
|
|||||||
@ -418,11 +418,11 @@ void ContentLoader::loadItem(
|
|||||||
std::string iconTypeStr = "";
|
std::string iconTypeStr = "";
|
||||||
root.at("icon-type").get(iconTypeStr);
|
root.at("icon-type").get(iconTypeStr);
|
||||||
if (iconTypeStr == "none") {
|
if (iconTypeStr == "none") {
|
||||||
def.iconType = item_icon_type::none;
|
def.iconType = ItemIconType::NONE;
|
||||||
} else if (iconTypeStr == "block") {
|
} else if (iconTypeStr == "block") {
|
||||||
def.iconType = item_icon_type::block;
|
def.iconType = ItemIconType::BLOCK;
|
||||||
} else if (iconTypeStr == "sprite") {
|
} else if (iconTypeStr == "sprite") {
|
||||||
def.iconType = item_icon_type::sprite;
|
def.iconType = ItemIconType::SPRITE;
|
||||||
} else if (iconTypeStr.length()) {
|
} else if (iconTypeStr.length()) {
|
||||||
logger.error() << name << ": unknown icon type" << iconTypeStr;
|
logger.error() << name << ": unknown icon type" << iconTypeStr;
|
||||||
}
|
}
|
||||||
@ -532,7 +532,7 @@ void ContentLoader::loadBlock(
|
|||||||
auto& item = builder.items.create(full + BLOCK_ITEM_SUFFIX);
|
auto& item = builder.items.create(full + BLOCK_ITEM_SUFFIX);
|
||||||
item.generated = true;
|
item.generated = true;
|
||||||
item.caption = def.caption;
|
item.caption = def.caption;
|
||||||
item.iconType = item_icon_type::block;
|
item.iconType = ItemIconType::BLOCK;
|
||||||
item.icon = full;
|
item.icon = full;
|
||||||
item.placingBlock = full;
|
item.placingBlock = full;
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ void corecontent::setup(EnginePaths* paths, ContentBuilder* builder) {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
ItemDef& item = builder->items.create(CORE_EMPTY);
|
ItemDef& item = builder->items.create(CORE_EMPTY);
|
||||||
item.iconType = item_icon_type::none;
|
item.iconType = ItemIconType::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto bindsFile = paths->getResourcesFolder()/fs::path("bindings.toml");
|
auto bindsFile = paths->getResourcesFolder()/fs::path("bindings.toml");
|
||||||
@ -43,7 +43,7 @@ void corecontent::setup(EnginePaths* paths, ContentBuilder* builder) {
|
|||||||
block.hitboxes = {AABB()};
|
block.hitboxes = {AABB()};
|
||||||
block.breakable = false;
|
block.breakable = false;
|
||||||
ItemDef& item = builder->items.create(CORE_OBSTACLE+".item");
|
ItemDef& item = builder->items.create(CORE_OBSTACLE+".item");
|
||||||
item.iconType = item_icon_type::block;
|
item.iconType = ItemIconType::BLOCK;
|
||||||
item.icon = CORE_OBSTACLE;
|
item.icon = CORE_OBSTACLE;
|
||||||
item.placingBlock = CORE_OBSTACLE;
|
item.placingBlock = CORE_OBSTACLE;
|
||||||
item.caption = block.caption;
|
item.caption = block.caption;
|
||||||
@ -59,7 +59,7 @@ void corecontent::setup(EnginePaths* paths, ContentBuilder* builder) {
|
|||||||
block.hitboxes = {AABB()};
|
block.hitboxes = {AABB()};
|
||||||
block.obstacle = false;
|
block.obstacle = false;
|
||||||
ItemDef& item = builder->items.create(CORE_STRUCT_AIR+".item");
|
ItemDef& item = builder->items.create(CORE_STRUCT_AIR+".item");
|
||||||
item.iconType = item_icon_type::block;
|
item.iconType = ItemIconType::BLOCK;
|
||||||
item.icon = CORE_STRUCT_AIR;
|
item.icon = CORE_STRUCT_AIR;
|
||||||
item.placingBlock = CORE_STRUCT_AIR;
|
item.placingBlock = CORE_STRUCT_AIR;
|
||||||
item.caption = block.caption;
|
item.caption = block.caption;
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
#include "frontend/menu.hpp"
|
#include "frontend/menu.hpp"
|
||||||
#include "frontend/screens/Screen.hpp"
|
#include "frontend/screens/Screen.hpp"
|
||||||
#include "frontend/screens/MenuScreen.hpp"
|
#include "frontend/screens/MenuScreen.hpp"
|
||||||
|
#include "graphics/render/ModelsGenerator.hpp"
|
||||||
#include "graphics/core/Batch2D.hpp"
|
#include "graphics/core/Batch2D.hpp"
|
||||||
#include "graphics/core/DrawContext.hpp"
|
#include "graphics/core/DrawContext.hpp"
|
||||||
#include "graphics/core/ImageData.hpp"
|
#include "graphics/core/ImageData.hpp"
|
||||||
@ -280,6 +281,17 @@ void Engine::loadAssets() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
assets = std::move(new_assets);
|
assets = std::move(new_assets);
|
||||||
|
|
||||||
|
if (content) {
|
||||||
|
for (auto& [name, def] : content->items.getDefs()) {
|
||||||
|
assets->store(
|
||||||
|
std::make_unique<model::Model>(
|
||||||
|
ModelsGenerator::generate(*def, *content, *assets)
|
||||||
|
),
|
||||||
|
name + ".model"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_configs(const fs::path& root) {
|
static void load_configs(const fs::path& root) {
|
||||||
|
|||||||
@ -29,6 +29,11 @@ void Mesh::addBox(glm::vec3 pos, glm::vec3 size) {
|
|||||||
addPlane(pos-X*size, Z*size, Y*size, -X);
|
addPlane(pos-X*size, Z*size, Y*size, -X);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mesh::scale(const glm::vec3& size) {
|
||||||
|
for (auto& vertex : vertices) {
|
||||||
|
vertex.coord *= size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Model::clean() {
|
void Model::clean() {
|
||||||
meshes.erase(
|
meshes.erase(
|
||||||
|
|||||||
@ -17,6 +17,7 @@ namespace model {
|
|||||||
|
|
||||||
void addPlane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm);
|
void addPlane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm);
|
||||||
void addBox(glm::vec3 pos, glm::vec3 size);
|
void addBox(glm::vec3 pos, glm::vec3 size);
|
||||||
|
void scale(const glm::vec3& size);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Model {
|
struct Model {
|
||||||
|
|||||||
71
src/graphics/render/ModelsGenerator.cpp
Normal file
71
src/graphics/render/ModelsGenerator.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#include "ModelsGenerator.hpp"
|
||||||
|
|
||||||
|
#include "assets/Assets.hpp"
|
||||||
|
#include "items/ItemDef.hpp"
|
||||||
|
#include "voxels/Block.hpp"
|
||||||
|
#include "content/Content.hpp"
|
||||||
|
#include "debug/Logger.hpp"
|
||||||
|
|
||||||
|
static debug::Logger logger("models-generator");
|
||||||
|
|
||||||
|
static void configure_textures(
|
||||||
|
model::Model& model,
|
||||||
|
const Block& blockDef,
|
||||||
|
const Assets& assets
|
||||||
|
) {
|
||||||
|
for (auto& mesh : model.meshes) {
|
||||||
|
auto& texture = mesh.texture;
|
||||||
|
if (texture.empty() || texture.at(0) != '$') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int index = std::stoi(texture.substr(1));
|
||||||
|
texture = "blocks:"+blockDef.textureFaces.at(index);
|
||||||
|
} catch (const std::invalid_argument& err) {
|
||||||
|
} catch (const std::runtime_error& err) {
|
||||||
|
logger.error() << err.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static model::Model create_flat_model(
|
||||||
|
const std::string& texture, const Assets& assets
|
||||||
|
) {
|
||||||
|
auto model = assets.require<model::Model>("drop-item");
|
||||||
|
for (auto& mesh : model.meshes) {
|
||||||
|
if (mesh.texture == "$0") {
|
||||||
|
mesh.texture = texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
model::Model ModelsGenerator::generate(
|
||||||
|
const ItemDef& def, const Content& content, const Assets& assets
|
||||||
|
) {
|
||||||
|
if (def.iconType == ItemIconType::BLOCK) {
|
||||||
|
auto model = assets.require<model::Model>("block");
|
||||||
|
const auto& blockDef = content.blocks.require(def.icon);
|
||||||
|
if (blockDef.model == BlockModel::xsprite) {
|
||||||
|
return create_flat_model(
|
||||||
|
"blocks:" + blockDef.textureFaces.at(0), assets
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for (auto& mesh : model.meshes) {
|
||||||
|
switch (blockDef.model) {
|
||||||
|
case BlockModel::aabb:
|
||||||
|
mesh.scale(blockDef.hitboxes.at(0).size());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mesh.scale(glm::vec3(0.3f));
|
||||||
|
}
|
||||||
|
configure_textures(model, blockDef, assets);
|
||||||
|
return model;
|
||||||
|
} else if (def.iconType == ItemIconType::SPRITE) {
|
||||||
|
return create_flat_model(def.icon, assets);
|
||||||
|
} else {
|
||||||
|
return model::Model();
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/graphics/render/ModelsGenerator.hpp
Normal file
14
src/graphics/render/ModelsGenerator.hpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "graphics/core/Model.hpp"
|
||||||
|
|
||||||
|
struct ItemDef;
|
||||||
|
class Assets;
|
||||||
|
class Content;
|
||||||
|
|
||||||
|
class ModelsGenerator {
|
||||||
|
public:
|
||||||
|
static model::Model generate(
|
||||||
|
const ItemDef& def, const Content& content, const Assets& assets
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -161,9 +161,9 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) {
|
|||||||
|
|
||||||
auto& item = indices->items.require(stack.getItemId());
|
auto& item = indices->items.require(stack.getItemId());
|
||||||
switch (item.iconType) {
|
switch (item.iconType) {
|
||||||
case item_icon_type::none:
|
case ItemIconType::NONE:
|
||||||
break;
|
break;
|
||||||
case item_icon_type::block: {
|
case ItemIconType::BLOCK: {
|
||||||
const Block& cblock = content->blocks.require(item.icon);
|
const Block& cblock = content->blocks.require(item.icon);
|
||||||
batch->texture(previews->getTexture());
|
batch->texture(previews->getTexture());
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) {
|
|||||||
0, 0, 0, region, false, true, tint);
|
0, 0, 0, region, false, true, tint);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case item_icon_type::sprite: {
|
case ItemIconType::SPRITE: {
|
||||||
size_t index = item.icon.find(':');
|
size_t index = item.icon.find(':');
|
||||||
std::string name = item.icon.substr(index+1);
|
std::string name = item.icon.substr(index+1);
|
||||||
UVRegion region(0.0f, 0.0, 1.0f, 1.0f);
|
UVRegion region(0.0f, 0.0, 1.0f, 1.0f);
|
||||||
|
|||||||
@ -12,10 +12,10 @@ struct item_funcs_set {
|
|||||||
bool on_block_break_by : 1;
|
bool on_block_break_by : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class item_icon_type {
|
enum class ItemIconType {
|
||||||
none, // invisible (core:empty) must not be rendered
|
NONE, // invisible (core:empty) must not be rendered
|
||||||
sprite, // textured quad: icon is `atlas_name:texture_name`
|
SPRITE, // textured quad: icon is `atlas_name:texture_name`
|
||||||
block, // block preview: icon is string block id
|
BLOCK, // block preview: icon is string block id
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ItemDef {
|
struct ItemDef {
|
||||||
@ -29,7 +29,7 @@ struct ItemDef {
|
|||||||
bool generated = false;
|
bool generated = false;
|
||||||
uint8_t emission[4] {0, 0, 0, 0};
|
uint8_t emission[4] {0, 0, 0, 0};
|
||||||
|
|
||||||
item_icon_type iconType = item_icon_type::sprite;
|
ItemIconType iconType = ItemIconType::SPRITE;
|
||||||
std::string icon = "blocks:notfound";
|
std::string icon = "blocks:notfound";
|
||||||
|
|
||||||
std::string placingBlock = "core:air";
|
std::string placingBlock = "core:air";
|
||||||
|
|||||||
@ -36,11 +36,11 @@ static int l_item_defs_count(lua::State* L) {
|
|||||||
static int l_item_get_icon(lua::State* L) {
|
static int l_item_get_icon(lua::State* L) {
|
||||||
if (auto def = get_item_def(L, 1)) {
|
if (auto def = get_item_def(L, 1)) {
|
||||||
switch (def->iconType) {
|
switch (def->iconType) {
|
||||||
case item_icon_type::none:
|
case ItemIconType::NONE:
|
||||||
return 0;
|
return 0;
|
||||||
case item_icon_type::sprite:
|
case ItemIconType::SPRITE:
|
||||||
return lua::pushstring(L, def->icon);
|
return lua::pushstring(L, def->icon);
|
||||||
case item_icon_type::block:
|
case ItemIconType::BLOCK:
|
||||||
return lua::pushstring(L, "block-previews:" + def->icon);
|
return lua::pushstring(L, "block-previews:" + def->icon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include "maths/UVRegion.hpp"
|
#include "maths/UVRegion.hpp"
|
||||||
#include "maths/aabb.hpp"
|
#include "maths/aabb.hpp"
|
||||||
@ -111,7 +112,7 @@ public:
|
|||||||
std::string caption;
|
std::string caption;
|
||||||
|
|
||||||
/// @brief Textures set applied to block sides
|
/// @brief Textures set applied to block sides
|
||||||
std::string textureFaces[6]; // -x,x, -y,y, -z,z
|
std::array<std::string, 6> textureFaces; // -x,x, -y,y, -z,z
|
||||||
|
|
||||||
std::vector<std::string> modelTextures = {};
|
std::vector<std::string> modelTextures = {};
|
||||||
std::vector<BoxModel> modelBoxes = {};
|
std::vector<BoxModel> modelBoxes = {};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user