Fix item and wield meshes (#6596)
authorVitaliy <silverunicorn2011@yandex.ru>
Tue, 14 Nov 2017 18:23:34 +0000 (21:23 +0300)
committersfan5 <sfan5@live.de>
Tue, 14 Nov 2017 18:23:34 +0000 (19:23 +0100)
src/content_mapblock.cpp
src/content_mapblock.h
src/mapblock_mesh.h
src/wieldmesh.cpp

index c2a25037c3b842a97eed1624bbc4ee852590e749..2b0948b3e97f0f6ff9972a0a1f35b072848101bc 100644 (file)
@@ -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();
+}
index 93e3fe53cac5a4064a360fdb90bacb6ea7b15725..5c07077a9f0fc84caf0580995f8925b1d14fcc60 100644 (file)
@@ -145,4 +145,5 @@ public:
 public:
        MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output);
        void generate();
+       void renderSingle(content_t node);
 };
index 13e3da9a1da0338789f52f232c16c4ae5c88dc6c..eccc1dcd0ac136e12cbde39e6b00043edf80a366 100644 (file)
@@ -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 <array>
 #include <map>
 
 class Client;
@@ -187,7 +188,7 @@ struct PreMeshBuffer
 
 struct MeshCollector
 {
-       std::vector<PreMeshBuffer> prebuffers[MAX_TILE_LAYERS];
+       std::array<std::vector<PreMeshBuffer>, MAX_TILE_LAYERS> prebuffers;
        bool m_use_tangent_vertices;
 
        MeshCollector(bool use_tangent_vertices):
index 98e7b5fa1b2a6b4314253443bd038533014b9e19..db256c6185fc4583d2110da5527188ae4e77e67c 100644 (file)
@@ -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<ItemPartColor> *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);
                                }
                        }
                }