From ee6bb5a315cc13aa51cda509d02780c21333af44 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Tue, 14 Nov 2017 21:23:34 +0300 Subject: [PATCH] Fix item and wield meshes (#6596) --- src/content_mapblock.cpp | 10 +++++- src/content_mapblock.h | 1 + src/mapblock_mesh.h | 3 +- src/wieldmesh.cpp | 78 +++++++++++++++++++++++----------------- 4 files changed, 57 insertions(+), 35 deletions(-) diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index c2a25037c..2b0948b3e 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -725,7 +725,7 @@ void MapblockMeshGenerator::drawGlasslikeFramedNode() v3s16 n2p = blockpos_nodes + p + g_26dirs[i]; MapNode n2 = data->m_vmanip.getNodeNoEx(n2p); content_t n2c = n2.getContent(); - if (n2c == current || n2c == CONTENT_IGNORE) + if (n2c == current) nb[i] = 1; } } @@ -1363,3 +1363,11 @@ void MapblockMeshGenerator::generate() drawNode(); } } + +void MapblockMeshGenerator::renderSingle(content_t node) +{ + p = {0, 0, 0}; + n = MapNode(node, 0xff, 0x00); + f = &nodedef->get(n); + drawNode(); +} diff --git a/src/content_mapblock.h b/src/content_mapblock.h index 93e3fe53c..5c07077a9 100644 --- a/src/content_mapblock.h +++ b/src/content_mapblock.h @@ -145,4 +145,5 @@ public: public: MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output); void generate(); + void renderSingle(content_t node); }; diff --git a/src/mapblock_mesh.h b/src/mapblock_mesh.h index 13e3da9a1..eccc1dcd0 100644 --- a/src/mapblock_mesh.h +++ b/src/mapblock_mesh.h @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_extrabloated.h" #include "client/tile.h" #include "voxel.h" +#include #include class Client; @@ -187,7 +188,7 @@ struct PreMeshBuffer struct MeshCollector { - std::vector prebuffers[MAX_TILE_LAYERS]; + std::array, MAX_TILE_LAYERS> prebuffers; bool m_use_tangent_vertices; MeshCollector(bool use_tangent_vertices): diff --git a/src/wieldmesh.cpp b/src/wieldmesh.cpp index 98e7b5fa1..db256c618 100644 --- a/src/wieldmesh.cpp +++ b/src/wieldmesh.cpp @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "itemdef.h" #include "nodedef.h" #include "mesh.h" +#include "content_mapblock.h" #include "mapblock_mesh.h" #include "client/tile.h" #include "log.h" @@ -300,6 +301,41 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename, } } +scene::SMesh *createSpecialNodeMesh(Client *client, content_t id, std::vector *colors) +{ + MeshMakeData mesh_make_data(client, false, false); + MeshCollector collector(false); + mesh_make_data.setSmoothLighting(false); + MapblockMeshGenerator gen(&mesh_make_data, &collector); + gen.renderSingle(id); + colors->clear(); + scene::SMesh *mesh = new scene::SMesh(); + for (auto &prebuffers : collector.prebuffers) + for (PreMeshBuffer &p : prebuffers) { + if (p.layer.material_flags & MATERIAL_FLAG_ANIMATION) { + const FrameSpec &frame = (*p.layer.frames)[0]; + p.layer.texture = frame.texture; + p.layer.normal_texture = frame.normal_texture; + } + for (video::S3DVertex &v : p.vertices) + v.Color.setAlpha(255); + scene::SMeshBuffer *buf = new scene::SMeshBuffer(); + // always set all textures + // with no shaders only texture 0 is ever actually used + buf->Material.setTexture(0, p.layer.texture); + buf->Material.setTexture(1, p.layer.normal_texture); + buf->Material.setTexture(2, p.layer.flags_texture); + p.layer.applyMaterialOptions(buf->Material); + mesh->addMeshBuffer(buf); + buf->append(&p.vertices[0], p.vertices.size(), + &p.indices[0], p.indices.size()); + buf->drop(); + colors->push_back( + ItemPartColor(p.layer.has_color, p.layer.color)); + } + return mesh; +} + void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client) { ITextureSource *tsrc = client->getTextureSource(); @@ -310,6 +346,8 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client) const ContentFeatures &f = ndef->get(def.name); content_t id = ndef->getId(def.name); + scene::SMesh *mesh = nullptr; + if (m_enable_shaders) { u32 shader_id = shdrsrc->getShader("wielded_shader", TILE_MATERIAL_BASIC, NDT_NORMAL); m_material_type = shdrsrc->getShaderInfo(shader_id).material; @@ -334,7 +372,7 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client) if (def.type == ITEM_NODE) { if (f.mesh_ptr[0]) { // e.g. mesh nodes and nodeboxes - scene::SMesh *mesh = cloneMesh(f.mesh_ptr[0]); + mesh = cloneMesh(f.mesh_ptr[0]); postProcessNodeMesh(mesh, f, m_enable_shaders, true, &m_material_type, &m_colors); changeToMesh(mesh); @@ -371,19 +409,14 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client) break; } case NDT_NORMAL: - case NDT_ALLFACES: { + case NDT_ALLFACES: + case NDT_LIQUID: + case NDT_FLOWINGLIQUID: { setCube(f, def.wield_scale); break; } default: { - MeshMakeData mesh_make_data(client, false); - MapNode mesh_make_node(id, 255, 0); - mesh_make_data.fillSingleNode(&mesh_make_node); - MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); - scene::SMesh *mesh = cloneMesh(mapblock_mesh.getMesh()); - translateMesh(mesh, v3f(-BS, -BS, -BS)); - postProcessNodeMesh(mesh, f, m_enable_shaders, true, - &m_material_type, &m_colors); + mesh = createSpecialNodeMesh(client, id, &m_colors); changeToMesh(mesh); mesh->drop(); m_meshnode->setScale( @@ -395,6 +428,7 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client) u32 material_count = m_meshnode->getMaterialCount(); for (u32 i = 0; i < material_count; ++i) { video::SMaterial &material = m_meshnode->getMaterial(i); + material.MaterialType = m_material_type; material.setFlag(video::EMF_BACK_FACE_CULLING, true); material.setFlag(video::EMF_BILINEAR_FILTER, m_bilinear_filter); material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter); @@ -531,30 +565,8 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) break; } default: { - MeshMakeData mesh_make_data(client, false); - MapNode mesh_make_node(id, 255, 0); - mesh_make_data.fillSingleNode(&mesh_make_node); - MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); - mesh = cloneMesh(mapblock_mesh.getMesh()); - translateMesh(mesh, v3f(-BS, -BS, -BS)); + mesh = createSpecialNodeMesh(client, id, &result->buffer_colors); scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); - - u32 mc = mesh->getMeshBufferCount(); - for (u32 i = 0; i < mc; ++i) { - video::SMaterial &material1 = - mesh->getMeshBuffer(i)->getMaterial(); - video::SMaterial &material2 = - mapblock_mesh.getMesh()->getMeshBuffer(i)->getMaterial(); - material1.setTexture(0, material2.getTexture(0)); - material1.setTexture(1, material2.getTexture(1)); - material1.setTexture(2, material2.getTexture(2)); - material1.setTexture(3, material2.getTexture(3)); - material1.MaterialType = material2.MaterialType; - } - // add overlays (since getMesh() returns - // the base layer only) - postProcessNodeMesh(mesh, f, false, false, nullptr, - &result->buffer_colors, f.drawtype == NDT_NORMAL); } } }