From 39d850a48c0d985842049c3fb7d4706e29d83c26 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 3 Jul 2024 03:33:39 +0300 Subject: [PATCH] add modeltree:set_texture --- res/content/base/scripts/components/drop.lua | 6 ++- res/modules/internal/stdcomp.lua | 1 + src/graphics/render/ModelBatch.cpp | 43 +++++++++++++++++--- src/graphics/render/ModelBatch.hpp | 19 +++++++-- src/logic/scripting/lua/libentity.cpp | 9 ++++ src/objects/rigging.cpp | 2 +- src/objects/rigging.hpp | 2 +- 7 files changed, 68 insertions(+), 14 deletions(-) diff --git a/res/content/base/scripts/components/drop.lua b/res/content/base/scripts/components/drop.lua index 6093a747..97167877 100644 --- a/res/content/base/scripts/components/drop.lua +++ b/res/content/base/scripts/components/drop.lua @@ -5,12 +5,14 @@ local rig = entity.modeltree inair = true ready = false -local item = ARGS.item +local dropitem = ARGS.item local rotation = mat4.rotate({0, 1, 0}, math.random() * 360) mat4.rotate(rotation, {1, 0, 0}, math.random() * 360, rotation) mat4.rotate(rotation, {0, 0, 1}, math.random() * 360, rotation) rig:set_matrix(0, rotation) +local icon = item.icon(dropitem.id) +rig:set_texture("$0", icon:gsub("block%-previews", "blocks"):gsub("base%:", "")) function on_grounded(force) rig:set_matrix(0, mat4.rotate({0, 1, 0}, math.random()*360)) @@ -25,7 +27,7 @@ end function on_trigger_enter(index, oid) if ready and oid == 0 then entity:despawn() - inventory.add(player.get_inventory(oid), item.id, item.count) + inventory.add(player.get_inventory(oid), dropitem.id, dropitem.count) audio.play_sound_2d("events/pickup", 0.5, 0.8+math.random()*0.4, "regular") end end diff --git a/res/modules/internal/stdcomp.lua b/res/modules/internal/stdcomp.lua index b6e6f600..0e9e3baf 100644 --- a/res/modules/internal/stdcomp.lua +++ b/res/modules/internal/stdcomp.lua @@ -27,6 +27,7 @@ local Modeltree = {__index={ get_model=function(self, i) return __modeltree.get_model(self.eid, i) end, get_matrix=function(self, i) return __modeltree.get_matrix(self.eid, i) end, set_matrix=function(self, i, m) return __modeltree.set_matrix(self.eid, i, m) end, + set_texture=function(self, s, s2) return __modeltree.set_texture(self.eid, s, s2) end, }} function new_Modeltree(eid) diff --git a/src/graphics/render/ModelBatch.cpp b/src/graphics/render/ModelBatch.cpp index 00eb95a5..704e6be0 100644 --- a/src/graphics/render/ModelBatch.cpp +++ b/src/graphics/render/ModelBatch.cpp @@ -2,6 +2,7 @@ #include "../core/Mesh.hpp" #include "../core/Model.hpp" +#include "../core/Atlas.hpp" #include "../core/Texture.hpp" #include "../../assets/Assets.hpp" #include "../../window/Window.hpp" @@ -53,7 +54,9 @@ ModelBatch::ModelBatch(size_t capacity, Assets* assets, Chunks* chunks) ModelBatch::~ModelBatch() { } -void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix, const glm::mat3& rotation) { +void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix, + const glm::mat3& rotation, + const texture_names_map* varTextures) { glm::vec3 gpos = matrix * glm::vec4(glm::vec3(), 1.0f); light_t light = chunks->getLight(floor(gpos.x), floor(gpos.y), floor(gpos.z)); glm::vec4 lights ( @@ -62,7 +65,7 @@ void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix, const gl Lightmap::extract(light, 2) / 15.0f, Lightmap::extract(light, 3) / 15.0f ); - setTexture(assets->get(mesh.texture)); + setTexture(mesh.texture, varTextures); size_t vcount = mesh.vertices.size(); const auto& vertexData = mesh.vertices.data(); for (size_t i = 0; i < vcount / 3; i++) { @@ -70,7 +73,7 @@ void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix, const gl flush(); } for (size_t j = 0; j < 3; j++) { - const auto& vert = vertexData[i * 3 + j]; + const auto vert = vertexData[i * 3 + j]; auto norm = rotation * vert.normal; float d = glm::dot(norm, SUN_VECTOR); d = 0.8f + d * 0.2f; @@ -81,9 +84,10 @@ void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix, const gl } } -void ModelBatch::draw(const model::Model* model) { +void ModelBatch::draw(const model::Model* model, + const texture_names_map* varTextures) { for (const auto& mesh : model->meshes) { - entries.push_back({combined, rotation, &mesh}); + entries.push_back({combined, rotation, &mesh, varTextures}); } } @@ -94,7 +98,7 @@ void ModelBatch::render() { } ); for (auto& entry : entries) { - draw(*entry.mesh, entry.matrix, entry.rotation); + draw(*entry.mesh, entry.matrix, entry.rotation, entry.varTextures); } flush(); entries.clear(); @@ -114,6 +118,32 @@ void ModelBatch::box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights) { plane(pos-X*size, Z*size, Y*size, -X, lights); } +void ModelBatch::setTexture(const std::string& name, + const texture_names_map* varTextures) { + if (name.at(0) == '$') { + const auto& found = varTextures->find(name); + if (found == varTextures->end()) { + return setTexture(nullptr); + } else { + return setTexture(found->second, varTextures); + } + } + size_t sep = name.find(':'); + if (sep == std::string::npos) { + setTexture(assets->get(name)); + } else { + auto atlas = assets->get(name.substr(0, sep)); + if (atlas == nullptr) { + setTexture(nullptr); + } else { + setTexture(atlas->getTexture()); + if (auto reg = atlas->getIf(name.substr(sep+1))) { + region = *reg; + } + } + } +} + void ModelBatch::setTexture(Texture* texture) { if (texture == nullptr) { texture = blank.get(); @@ -122,6 +152,7 @@ void ModelBatch::setTexture(Texture* texture) { flush(); } this->texture = texture; + region = UVRegion {0.0f, 0.0f, 1.0f, 1.0f}; } void ModelBatch::flush() { diff --git a/src/graphics/render/ModelBatch.hpp b/src/graphics/render/ModelBatch.hpp index ba6f1eed..7f3c7e91 100644 --- a/src/graphics/render/ModelBatch.hpp +++ b/src/graphics/render/ModelBatch.hpp @@ -1,9 +1,12 @@ #ifndef GRAPHICS_RENDER_MODEL_BATCH_HPP_ #define GRAPHICS_RENDER_MODEL_BATCH_HPP_ +#include "../../maths/UVRegion.hpp" + #include #include #include +#include class Mesh; class Texture; @@ -15,6 +18,8 @@ namespace model { struct Model; } +using texture_names_map = std::unordered_map; + class ModelBatch { std::unique_ptr const buffer; size_t const capacity; @@ -30,6 +35,7 @@ class ModelBatch { Assets* assets; Chunks* chunks; Texture* texture = nullptr; + UVRegion region {0.0f, 0.0f, 1.0f, 1.0f}; static inline glm::vec3 SUN_VECTOR {0.411934f, 0.863868f, -0.279161f}; @@ -40,8 +46,8 @@ class ModelBatch { buffer[index++] = pos.x; buffer[index++] = pos.y; buffer[index++] = pos.z; - buffer[index++] = uv.x; - buffer[index++] = uv.y; + buffer[index++] = uv.x * region.getWidth() + region.u1; + buffer[index++] = uv.y * region.getHeight() + region.v1; union { float floating; @@ -72,8 +78,11 @@ class ModelBatch { vertex(pos-right+up, {0,1}, color); } - void draw(const model::Mesh& mesh, const glm::mat4& matrix, const glm::mat3& rotation); + void draw(const model::Mesh& mesh, const glm::mat4& matrix, + const glm::mat3& rotation, const texture_names_map* varTextures); void box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights); + void setTexture(const std::string& name, + const texture_names_map* varTextures); void setTexture(Texture* texture); void flush(); @@ -81,6 +90,7 @@ class ModelBatch { glm::mat4 matrix; glm::mat3 rotation; const model::Mesh* mesh; + const texture_names_map* varTextures; }; std::vector entries; public: @@ -93,7 +103,8 @@ public: void pushMatrix(glm::mat4 matrix); void popMatrix(); - void draw(const model::Model* model); + void draw(const model::Model* model, + const texture_names_map* varTextures); void render(); }; diff --git a/src/logic/scripting/lua/libentity.cpp b/src/logic/scripting/lua/libentity.cpp index 8f1dbf6a..5d55bd6a 100644 --- a/src/logic/scripting/lua/libentity.cpp +++ b/src/logic/scripting/lua/libentity.cpp @@ -148,6 +148,14 @@ static int l_modeltree_set_matrix(lua::State* L) { return 0; } +static int l_modeltree_set_texture(lua::State* L) { + if (auto entity = get_entity(L, 1)) { + auto& rig = entity->getModeltree(); + rig.textures[lua::require_string(L, 2)] = lua::require_string(L, 3); + } + return 0; +} + const luaL_Reg entitylib [] = { {"exists", lua::wrap}, {"spawn", lua::wrap}, @@ -159,6 +167,7 @@ const luaL_Reg modeltreelib [] = { {"get_model", lua::wrap}, {"get_matrix", lua::wrap}, {"set_matrix", lua::wrap}, + {"set_texture", lua::wrap}, {NULL, NULL} }; diff --git a/src/objects/rigging.cpp b/src/objects/rigging.cpp index 04a90177..baadc8bf 100644 --- a/src/objects/rigging.cpp +++ b/src/objects/rigging.cpp @@ -78,7 +78,7 @@ void RigConfig::render( continue; } batch.pushMatrix(rig.calculated.matrices[i]); - batch.draw(model); + batch.draw(model, &rig.textures); batch.popMatrix(); } } diff --git a/src/objects/rigging.hpp b/src/objects/rigging.hpp index e79bcf01..797ec20e 100644 --- a/src/objects/rigging.hpp +++ b/src/objects/rigging.hpp @@ -64,7 +64,7 @@ namespace rigging { RigConfig* config; Pose pose; Pose calculated; - std::vector textures; + std::unordered_map textures; }; class RigConfig {