mirror of
https://github.com/luanti-org/luanti.git
synced 2026-10-12 02:18:30 +00:00
Don't cull upper face of waving liquids below solid nodes (#17302)
This commit is contained in:
@@ -450,14 +450,44 @@ void MapblockMeshGenerator::drawSolidNode()
|
||||
continue;
|
||||
if (n2 == CONTENT_IGNORE)
|
||||
continue;
|
||||
// For a waving liquid source, keep the top face even when a solid node
|
||||
// is directly above: wave animation can pull the surface down and expose
|
||||
// a gap where the face was culled. Also keep backface culling off so the
|
||||
// face is visible from below e.g. looking up from underwater.
|
||||
// Submerged solids surrounded by liquid or other solid nodes on all sides are excluded.
|
||||
bool liquid_needs_top_face = face == 0
|
||||
&& cur_node.f->drawtype == NDT_LIQUID
|
||||
&& cur_node.f->waving == 3
|
||||
&& data->m_enable_waving_water;
|
||||
if (liquid_needs_top_face) {
|
||||
liquid_needs_top_face = false;
|
||||
static const v3s16 h_dirs[4] = {
|
||||
v3s16(1,0,0), v3s16(-1,0,0), v3s16(0,0,1), v3s16(0,0,-1)
|
||||
};
|
||||
for (const v3s16 &d : h_dirs) {
|
||||
const ContentFeatures &f_side = nodedef->get(data->m_vmanip.getNodeNoEx(p2 + d));
|
||||
|
||||
bool side_is_translucent = !(f_side.visuals->solidness || f_side.visuals->visual_solidness);
|
||||
bool side_is_same_flowing_liquid =
|
||||
f_side.drawtype == NDT_FLOWINGLIQUID && cur_node.f->sameLiquidRender(f_side);
|
||||
|
||||
// Draw the top face as soon there's a translucent node diagonally above to
|
||||
// avoid visual gaps in the liquid surface
|
||||
if (side_is_translucent && !side_is_same_flowing_liquid) {
|
||||
liquid_needs_top_face = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (n2 != CONTENT_AIR) {
|
||||
const ContentFeatures &f2 = nodedef->get(n2);
|
||||
if (f2.visuals->solidness == 2)
|
||||
if (f2.visuals->solidness == 2 && !liquid_needs_top_face)
|
||||
continue;
|
||||
if (cur_node.f->drawtype == NDT_LIQUID) {
|
||||
if (cur_node.f->sameLiquidRender(f2))
|
||||
continue;
|
||||
backface_culling = f2.visuals->solidness || f2.visuals->visual_solidness;
|
||||
backface_culling =
|
||||
!liquid_needs_top_face && (f2.visuals->solidness || f2.visuals->visual_solidness);
|
||||
}
|
||||
}
|
||||
faces |= 1 << face;
|
||||
|
||||
@@ -48,6 +48,7 @@ struct MeshMakeData
|
||||
bool m_generate_minimap = false;
|
||||
bool m_smooth_lighting = false;
|
||||
bool m_enable_water_reflections = false;
|
||||
bool m_enable_waving_water = false;
|
||||
|
||||
const NodeDefManager *m_nodedef;
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ MeshUpdateQueue::MeshUpdateQueue(Client *client):
|
||||
{
|
||||
m_cache_smooth_lighting = g_settings->getBool("smooth_lighting");
|
||||
m_cache_enable_water_reflections = g_settings->getBool("enable_water_reflections");
|
||||
m_cache_enable_waving_water = g_settings->getBool("enable_waving_water");
|
||||
}
|
||||
|
||||
MeshUpdateQueue::~MeshUpdateQueue()
|
||||
@@ -239,6 +240,7 @@ void MeshUpdateQueue::fillDataFromMapBlocks(QueuedMeshUpdate *q)
|
||||
data->m_generate_minimap = !!m_client->getMinimap();
|
||||
data->m_smooth_lighting = m_cache_smooth_lighting;
|
||||
data->m_enable_water_reflections = m_cache_enable_water_reflections;
|
||||
data->m_enable_waving_water = m_cache_enable_waving_water;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -106,6 +106,7 @@ private:
|
||||
// TODO: Add callback to update these when g_settings changes, and update all meshes
|
||||
bool m_cache_smooth_lighting;
|
||||
bool m_cache_enable_water_reflections;
|
||||
bool m_cache_enable_waving_water;
|
||||
|
||||
void fillDataFromMapBlocks(QueuedMeshUpdate *q);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user