From ee6bb5a315cc13aa51cda509d02780c21333af44 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Tue, 14 Nov 2017 21:23:34 +0300 Subject: Fix item and wield meshes (#6596) --- src/wieldmesh.cpp | 78 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 33 deletions(-) (limited to 'src/wieldmesh.cpp') 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); } } } -- cgit v1.2.3