From 808fa5ecb3ddfd5d993000cc6b4c972257e182db Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 23 Jul 2020 19:54:58 +0200 Subject: [PATCH] Improve default inventory+wield images of node drawtypes (#9299) --- doc/texture_packs.txt | 1 + src/client/content_mapblock.cpp | 4 +- src/client/content_mapblock.h | 2 +- src/client/wieldmesh.cpp | 207 +++++++++++----------- src/nodedef.h | 16 ++ textures/base/pack/no_texture_airlike.png | Bin 0 -> 178 bytes 6 files changed, 126 insertions(+), 104 deletions(-) create mode 100644 textures/base/pack/no_texture_airlike.png diff --git a/doc/texture_packs.txt b/doc/texture_packs.txt index e7a7dfd3c..79d65a339 100644 --- a/doc/texture_packs.txt +++ b/doc/texture_packs.txt @@ -90,6 +90,7 @@ by texture packs. All existing fallback textures can be found in the directory * `minimap_mask_square.png`: mask used for the square minimap * `minimap_overlay_round.png`: overlay texture for the round minimap * `minimap_overlay_square.png`: overlay texture for the square minimap +* `no_texture_airlike.png`: fallback inventory image for airlike nodes * `object_marker_red.png`: texture for players on the minimap * `player_marker.png`: texture for the own player on the square minimap diff --git a/src/client/content_mapblock.cpp b/src/client/content_mapblock.cpp index 3d06584c4..65a85709b 100644 --- a/src/client/content_mapblock.cpp +++ b/src/client/content_mapblock.cpp @@ -1454,10 +1454,10 @@ void MapblockMeshGenerator::generate() } } -void MapblockMeshGenerator::renderSingle(content_t node) +void MapblockMeshGenerator::renderSingle(content_t node, u8 param2) { p = {0, 0, 0}; - n = MapNode(node, 0xff, 0x00); + n = MapNode(node, 0xff, param2); f = &nodedef->get(n); drawNode(); } diff --git a/src/client/content_mapblock.h b/src/client/content_mapblock.h index 97947cdbe..487d84a07 100644 --- a/src/client/content_mapblock.h +++ b/src/client/content_mapblock.h @@ -174,5 +174,5 @@ public: public: MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output); void generate(); - void renderSingle(content_t node); + void renderSingle(content_t node, u8 param2 = 0x00); }; diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index 8cd3e29a9..a268895ed 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -303,13 +303,24 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename, } } -scene::SMesh *createSpecialNodeMesh(Client *client, content_t id, std::vector *colors) +scene::SMesh *createSpecialNodeMesh(Client *client, content_t id, std::vector *colors, const ContentFeatures &f) { MeshMakeData mesh_make_data(client, false, false); MeshCollector collector; mesh_make_data.setSmoothLighting(false); MapblockMeshGenerator gen(&mesh_make_data, &collector); - gen.renderSingle(id); + u8 param2 = 0; + if (f.param_type_2 == CPT2_WALLMOUNTED || + f.param_type_2 == CPT2_COLORED_WALLMOUNTED) { + if (f.drawtype == NDT_TORCHLIKE) + param2 = 1; + else if (f.drawtype == NDT_SIGNLIKE || + f.drawtype == NDT_NODEBOX || + f.drawtype == NDT_MESH) + param2 = 4; + } + gen.renderSingle(id, param2); + colors->clear(); scene::SMesh *mesh = new scene::SMesh(); for (auto &prebuffers : collector.prebuffers) @@ -319,8 +330,9 @@ scene::SMesh *createSpecialNodeMesh(Client *client, content_t id, std::vectorMaterial.setTexture(0, p.layer.texture); p.layer.applyMaterialOptions(buf->Material); @@ -368,73 +380,61 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che // Handle nodes // See also CItemDefManager::createClientCached() if (def.type == ITEM_NODE) { - if (f.mesh_ptr[0]) { - // e.g. mesh nodes and nodeboxes - mesh = cloneMesh(f.mesh_ptr[0]); - postProcessNodeMesh(mesh, f, m_enable_shaders, true, - &m_material_type, &m_colors); + bool cull_backface = f.needsBackfaceCulling(); + + // Select rendering method + switch (f.drawtype) { + case NDT_AIRLIKE: + setExtruded("no_texture_airlike.png", "", + v3f(1.0, 1.0, 1.0), tsrc, 1); + break; + case NDT_SIGNLIKE: + case NDT_TORCHLIKE: + case NDT_RAILLIKE: + case NDT_PLANTLIKE: + case NDT_PLANTLIKE_ROOTED: + case NDT_FLOWINGLIQUID: { + v3f wscale = def.wield_scale; + if (f.drawtype == NDT_FLOWINGLIQUID) + wscale.Z *= 0.1f; + setExtruded(tsrc->getTextureName(f.tiles[0].layers[0].texture_id), + tsrc->getTextureName(f.tiles[0].layers[1].texture_id), + wscale, tsrc, + f.tiles[0].layers[0].animation_frame_count); + // Add color + const TileLayer &l0 = f.tiles[0].layers[0]; + m_colors.emplace_back(l0.has_color, l0.color); + const TileLayer &l1 = f.tiles[0].layers[1]; + m_colors.emplace_back(l1.has_color, l1.color); + break; + } + case NDT_NORMAL: + case NDT_ALLFACES: + case NDT_LIQUID: + setCube(f, def.wield_scale); + break; + default: + // Render non-trivial drawtypes like the actual node + mesh = createSpecialNodeMesh(client, id, &m_colors, f); changeToMesh(mesh); mesh->drop(); - // mesh is pre-scaled by BS * f->visual_scale m_meshnode->setScale( - def.wield_scale * WIELD_SCALE_FACTOR - / (BS * f.visual_scale)); - } else { - switch (f.drawtype) { - case NDT_AIRLIKE: { - changeToMesh(nullptr); - break; - } - case NDT_PLANTLIKE: { - setExtruded(tsrc->getTextureName(f.tiles[0].layers[0].texture_id), - tsrc->getTextureName(f.tiles[0].layers[1].texture_id), - def.wield_scale, tsrc, - f.tiles[0].layers[0].animation_frame_count); - // Add color - const TileLayer &l0 = f.tiles[0].layers[0]; - m_colors.emplace_back(l0.has_color, l0.color); - const TileLayer &l1 = f.tiles[0].layers[1]; - m_colors.emplace_back(l1.has_color, l1.color); - break; - } - case NDT_PLANTLIKE_ROOTED: { - setExtruded(tsrc->getTextureName(f.special_tiles[0].layers[0].texture_id), - "", def.wield_scale, tsrc, - f.special_tiles[0].layers[0].animation_frame_count); - // Add color - const TileLayer &l0 = f.special_tiles[0].layers[0]; - m_colors.emplace_back(l0.has_color, l0.color); - break; - } - case NDT_NORMAL: - case NDT_ALLFACES: - case NDT_LIQUID: - case NDT_FLOWINGLIQUID: { - setCube(f, def.wield_scale); - break; - } - default: { - mesh = createSpecialNodeMesh(client, id, &m_colors); - changeToMesh(mesh); - mesh->drop(); - m_meshnode->setScale( - def.wield_scale * WIELD_SCALE_FACTOR - / (BS * f.visual_scale)); - } - } + def.wield_scale * WIELD_SCALE_FACTOR + / (BS * f.visual_scale)); + break; } + 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.MaterialTypeParam = 0.5f; - material.setFlag(video::EMF_BACK_FACE_CULLING, true); + material.setFlag(video::EMF_BACK_FACE_CULLING, cull_backface); material.setFlag(video::EMF_BILINEAR_FILTER, m_bilinear_filter); material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter); } return; - } - else if (!def.inventory_image.empty()) { + } else if (!def.inventory_image.empty()) { setExtruded(def.inventory_image, def.inventory_overlay, def.wield_scale, tsrc, 1); m_colors.emplace_back(); @@ -529,6 +529,8 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) // Shading is on by default result->needs_shading = true; + bool cull_backface = f.needsBackfaceCulling(); + // If inventory_image is defined, it overrides everything else if (!def.inventory_image.empty()) { mesh = getExtrudedMesh(tsrc, def.inventory_image, @@ -538,51 +540,54 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) result->buffer_colors.emplace_back(true, video::SColor(0xFFFFFFFF)); // Items with inventory images do not need shading result->needs_shading = false; + } else if (def.type == ITEM_NODE && f.drawtype == NDT_AIRLIKE) { + // Fallback image for airlike node + mesh = getExtrudedMesh(tsrc, "no_texture_airlike.png", + def.inventory_overlay); + result->needs_shading = false; } else if (def.type == ITEM_NODE) { - if (f.mesh_ptr[0]) { - mesh = cloneMesh(f.mesh_ptr[0]); - scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); + switch (f.drawtype) { + case NDT_NORMAL: + case NDT_ALLFACES: + case NDT_LIQUID: + case NDT_FLOWINGLIQUID: { + scene::IMesh *cube = g_extrusion_mesh_cache->createCube(); + mesh = cloneMesh(cube); + cube->drop(); + if (f.drawtype == NDT_FLOWINGLIQUID) { + scaleMesh(mesh, v3f(1.2, 0.03, 1.2)); + translateMesh(mesh, v3f(0, -0.57, 0)); + } else + scaleMesh(mesh, v3f(1.2, 1.2, 1.2)); + // add overlays postProcessNodeMesh(mesh, f, false, false, nullptr, - &result->buffer_colors); - } else { - switch (f.drawtype) { - case NDT_PLANTLIKE: { - mesh = getExtrudedMesh(tsrc, - tsrc->getTextureName(f.tiles[0].layers[0].texture_id), - tsrc->getTextureName(f.tiles[0].layers[1].texture_id)); - // Add color - const TileLayer &l0 = f.tiles[0].layers[0]; - result->buffer_colors.emplace_back(l0.has_color, l0.color); - const TileLayer &l1 = f.tiles[0].layers[1]; - result->buffer_colors.emplace_back(l1.has_color, l1.color); - break; - } - case NDT_PLANTLIKE_ROOTED: { - mesh = getExtrudedMesh(tsrc, - tsrc->getTextureName(f.special_tiles[0].layers[0].texture_id), ""); - // Add color - const TileLayer &l0 = f.special_tiles[0].layers[0]; - result->buffer_colors.emplace_back(l0.has_color, l0.color); - break; - } - case NDT_NORMAL: - case NDT_ALLFACES: - case NDT_LIQUID: - case NDT_FLOWINGLIQUID: { - scene::IMesh *cube = g_extrusion_mesh_cache->createCube(); - mesh = cloneMesh(cube); - cube->drop(); - scaleMesh(mesh, v3f(1.2, 1.2, 1.2)); - // add overlays - postProcessNodeMesh(mesh, f, false, false, nullptr, - &result->buffer_colors); - break; - } - default: { - mesh = createSpecialNodeMesh(client, id, &result->buffer_colors); - scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); - } - } + &result->buffer_colors, true); + break; + } + case NDT_PLANTLIKE: { + mesh = getExtrudedMesh(tsrc, + tsrc->getTextureName(f.tiles[0].layers[0].texture_id), + tsrc->getTextureName(f.tiles[0].layers[1].texture_id)); + // Add color + const TileLayer &l0 = f.tiles[0].layers[0]; + result->buffer_colors.emplace_back(l0.has_color, l0.color); + const TileLayer &l1 = f.tiles[0].layers[1]; + result->buffer_colors.emplace_back(l1.has_color, l1.color); + break; + } + case NDT_PLANTLIKE_ROOTED: { + mesh = getExtrudedMesh(tsrc, + tsrc->getTextureName(f.special_tiles[0].layers[0].texture_id), ""); + // Add color + const TileLayer &l0 = f.special_tiles[0].layers[0]; + result->buffer_colors.emplace_back(l0.has_color, l0.color); + break; + } + default: + // Render non-trivial drawtypes like the actual node + mesh = createSpecialNodeMesh(client, id, &result->buffer_colors, f); + scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); + break; } u32 mc = mesh->getMeshBufferCount(); @@ -593,7 +598,7 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) material.MaterialTypeParam = 0.5f; material.setFlag(video::EMF_BILINEAR_FILTER, false); material.setFlag(video::EMF_TRILINEAR_FILTER, false); - material.setFlag(video::EMF_BACK_FACE_CULLING, true); + material.setFlag(video::EMF_BACK_FACE_CULLING, cull_backface); material.setFlag(video::EMF_LIGHTING, false); } diff --git a/src/nodedef.h b/src/nodedef.h index cf03abaae..ff52f976f 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -425,6 +425,22 @@ struct ContentFeatures /* Some handy methods */ + bool needsBackfaceCulling() const + { + switch (drawtype) { + case NDT_TORCHLIKE: + case NDT_SIGNLIKE: + case NDT_FIRELIKE: + case NDT_RAILLIKE: + case NDT_PLANTLIKE: + case NDT_PLANTLIKE_ROOTED: + case NDT_MESH: + return false; + default: + return true; + } + } + bool isLiquid() const{ return (liquid_type != LIQUID_NONE); } diff --git a/textures/base/pack/no_texture_airlike.png b/textures/base/pack/no_texture_airlike.png new file mode 100644 index 0000000000000000000000000000000000000000..634ee8ca552b07a2b0bc7ecdc1848a480175a18d GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`m7Xq+Ar*{sC$aJ!FyJ}z>A$$Y ziJG@KD|_m7*4uAta_96tZl18^Z{qXgHB#yR4(m!b3OF&d&S{>hKRdx8K>R&px(#!~ zffVN*)lDX*2N(>wuJ_GkZK^V5aA^3+`Qw*K5|_7xi*(0th1?{8yI$Km8~HCrZtdM| b=~G@PGsEDqVDx&RBN#kg{an^LB{Ts5xq&{0 literal 0 HcmV?d00001