Improve default inventory+wield images of node drawtypes (#9299)

This commit is contained in:
Wuzzy 2020-07-23 19:54:58 +02:00 committed by GitHub
parent 8ca602150d
commit 808fa5ecb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 126 additions and 104 deletions

@ -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_mask_square.png`: mask used for the square minimap
* `minimap_overlay_round.png`: overlay texture for the round minimap * `minimap_overlay_round.png`: overlay texture for the round minimap
* `minimap_overlay_square.png`: overlay texture for the square 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 * `object_marker_red.png`: texture for players on the minimap
* `player_marker.png`: texture for the own player on the square minimap * `player_marker.png`: texture for the own player on the square minimap

@ -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}; p = {0, 0, 0};
n = MapNode(node, 0xff, 0x00); n = MapNode(node, 0xff, param2);
f = &nodedef->get(n); f = &nodedef->get(n);
drawNode(); drawNode();
} }

@ -174,5 +174,5 @@ public:
public: public:
MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output); MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output);
void generate(); void generate();
void renderSingle(content_t node); void renderSingle(content_t node, u8 param2 = 0x00);
}; };

@ -303,13 +303,24 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename,
} }
} }
scene::SMesh *createSpecialNodeMesh(Client *client, content_t id, std::vector<ItemPartColor> *colors) scene::SMesh *createSpecialNodeMesh(Client *client, content_t id, std::vector<ItemPartColor> *colors, const ContentFeatures &f)
{ {
MeshMakeData mesh_make_data(client, false, false); MeshMakeData mesh_make_data(client, false, false);
MeshCollector collector; MeshCollector collector;
mesh_make_data.setSmoothLighting(false); mesh_make_data.setSmoothLighting(false);
MapblockMeshGenerator gen(&mesh_make_data, &collector); 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(); colors->clear();
scene::SMesh *mesh = new scene::SMesh(); scene::SMesh *mesh = new scene::SMesh();
for (auto &prebuffers : collector.prebuffers) for (auto &prebuffers : collector.prebuffers)
@ -319,8 +330,9 @@ scene::SMesh *createSpecialNodeMesh(Client *client, content_t id, std::vector<It
p.layer.texture = frame.texture; p.layer.texture = frame.texture;
p.layer.normal_texture = frame.normal_texture; p.layer.normal_texture = frame.normal_texture;
} }
for (video::S3DVertex &v : p.vertices) for (video::S3DVertex &v : p.vertices) {
v.Color.setAlpha(255); v.Color.setAlpha(255);
}
scene::SMeshBuffer *buf = new scene::SMeshBuffer(); scene::SMeshBuffer *buf = new scene::SMeshBuffer();
buf->Material.setTexture(0, p.layer.texture); buf->Material.setTexture(0, p.layer.texture);
p.layer.applyMaterialOptions(buf->Material); p.layer.applyMaterialOptions(buf->Material);
@ -368,73 +380,61 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che
// Handle nodes // Handle nodes
// See also CItemDefManager::createClientCached() // See also CItemDefManager::createClientCached()
if (def.type == ITEM_NODE) { if (def.type == ITEM_NODE) {
if (f.mesh_ptr[0]) { bool cull_backface = f.needsBackfaceCulling();
// e.g. mesh nodes and nodeboxes
mesh = cloneMesh(f.mesh_ptr[0]); // Select rendering method
postProcessNodeMesh(mesh, f, m_enable_shaders, true, switch (f.drawtype) {
&m_material_type, &m_colors); 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); changeToMesh(mesh);
mesh->drop(); mesh->drop();
// mesh is pre-scaled by BS * f->visual_scale
m_meshnode->setScale( m_meshnode->setScale(
def.wield_scale * WIELD_SCALE_FACTOR def.wield_scale * WIELD_SCALE_FACTOR
/ (BS * f.visual_scale)); / (BS * f.visual_scale));
} else { break;
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));
}
}
} }
u32 material_count = m_meshnode->getMaterialCount(); u32 material_count = m_meshnode->getMaterialCount();
for (u32 i = 0; i < material_count; ++i) { for (u32 i = 0; i < material_count; ++i) {
video::SMaterial &material = m_meshnode->getMaterial(i); video::SMaterial &material = m_meshnode->getMaterial(i);
material.MaterialType = m_material_type; material.MaterialType = m_material_type;
material.MaterialTypeParam = 0.5f; 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_BILINEAR_FILTER, m_bilinear_filter);
material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter); material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter);
} }
return; return;
} } else if (!def.inventory_image.empty()) {
else if (!def.inventory_image.empty()) {
setExtruded(def.inventory_image, def.inventory_overlay, def.wield_scale, setExtruded(def.inventory_image, def.inventory_overlay, def.wield_scale,
tsrc, 1); tsrc, 1);
m_colors.emplace_back(); m_colors.emplace_back();
@ -529,6 +529,8 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
// Shading is on by default // Shading is on by default
result->needs_shading = true; result->needs_shading = true;
bool cull_backface = f.needsBackfaceCulling();
// If inventory_image is defined, it overrides everything else // If inventory_image is defined, it overrides everything else
if (!def.inventory_image.empty()) { if (!def.inventory_image.empty()) {
mesh = getExtrudedMesh(tsrc, def.inventory_image, 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)); result->buffer_colors.emplace_back(true, video::SColor(0xFFFFFFFF));
// Items with inventory images do not need shading // Items with inventory images do not need shading
result->needs_shading = false; 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) { } else if (def.type == ITEM_NODE) {
if (f.mesh_ptr[0]) { switch (f.drawtype) {
mesh = cloneMesh(f.mesh_ptr[0]); case NDT_NORMAL:
scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); 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, postProcessNodeMesh(mesh, f, false, false, nullptr,
&result->buffer_colors); &result->buffer_colors, true);
} else { break;
switch (f.drawtype) { }
case NDT_PLANTLIKE: { case NDT_PLANTLIKE: {
mesh = getExtrudedMesh(tsrc, mesh = getExtrudedMesh(tsrc,
tsrc->getTextureName(f.tiles[0].layers[0].texture_id), tsrc->getTextureName(f.tiles[0].layers[0].texture_id),
tsrc->getTextureName(f.tiles[0].layers[1].texture_id)); tsrc->getTextureName(f.tiles[0].layers[1].texture_id));
// Add color // Add color
const TileLayer &l0 = f.tiles[0].layers[0]; const TileLayer &l0 = f.tiles[0].layers[0];
result->buffer_colors.emplace_back(l0.has_color, l0.color); result->buffer_colors.emplace_back(l0.has_color, l0.color);
const TileLayer &l1 = f.tiles[0].layers[1]; const TileLayer &l1 = f.tiles[0].layers[1];
result->buffer_colors.emplace_back(l1.has_color, l1.color); result->buffer_colors.emplace_back(l1.has_color, l1.color);
break; break;
} }
case NDT_PLANTLIKE_ROOTED: { case NDT_PLANTLIKE_ROOTED: {
mesh = getExtrudedMesh(tsrc, mesh = getExtrudedMesh(tsrc,
tsrc->getTextureName(f.special_tiles[0].layers[0].texture_id), ""); tsrc->getTextureName(f.special_tiles[0].layers[0].texture_id), "");
// Add color // Add color
const TileLayer &l0 = f.special_tiles[0].layers[0]; const TileLayer &l0 = f.special_tiles[0].layers[0];
result->buffer_colors.emplace_back(l0.has_color, l0.color); result->buffer_colors.emplace_back(l0.has_color, l0.color);
break; break;
} }
case NDT_NORMAL: default:
case NDT_ALLFACES: // Render non-trivial drawtypes like the actual node
case NDT_LIQUID: mesh = createSpecialNodeMesh(client, id, &result->buffer_colors, f);
case NDT_FLOWINGLIQUID: { scaleMesh(mesh, v3f(0.12, 0.12, 0.12));
scene::IMesh *cube = g_extrusion_mesh_cache->createCube(); break;
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));
}
}
} }
u32 mc = mesh->getMeshBufferCount(); u32 mc = mesh->getMeshBufferCount();
@ -593,7 +598,7 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
material.MaterialTypeParam = 0.5f; material.MaterialTypeParam = 0.5f;
material.setFlag(video::EMF_BILINEAR_FILTER, false); material.setFlag(video::EMF_BILINEAR_FILTER, false);
material.setFlag(video::EMF_TRILINEAR_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); material.setFlag(video::EMF_LIGHTING, false);
} }

@ -425,6 +425,22 @@ struct ContentFeatures
/* /*
Some handy methods 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{ bool isLiquid() const{
return (liquid_type != LIQUID_NONE); return (liquid_type != LIQUID_NONE);
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B