Fix water-glass and water-lava surfaces
parent
fea55a9b87
commit
045e32b6ec
|
@ -364,6 +364,9 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
assert(content_features(n).special_material);
|
assert(content_features(n).special_material);
|
||||||
video::SMaterial &liquid_material =
|
video::SMaterial &liquid_material =
|
||||||
*content_features(n).special_material;
|
*content_features(n).special_material;
|
||||||
|
video::SMaterial &liquid_material_bfculled =
|
||||||
|
*content_features(n).special_material2;
|
||||||
|
|
||||||
assert(content_features(n).special_atlas);
|
assert(content_features(n).special_atlas);
|
||||||
AtlasPointer &pa_liquid1 =
|
AtlasPointer &pa_liquid1 =
|
||||||
*content_features(n).special_atlas;
|
*content_features(n).special_atlas;
|
||||||
|
@ -516,10 +519,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
content_t neighbor_content = neighbor_contents[dir];
|
content_t neighbor_content = neighbor_contents[dir];
|
||||||
|
ContentFeatures &n_feat = content_features(neighbor_content);
|
||||||
|
|
||||||
// Don't draw face if neighbor is not air or liquid
|
// Don't draw face if neighbor is blocking the view
|
||||||
if(neighbor_content != CONTENT_AIR
|
if(n_feat.solidness == 2)
|
||||||
&& content_liquid(neighbor_content) == false)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool neighbor_is_same_liquid = (neighbor_content == c_source
|
bool neighbor_is_same_liquid = (neighbor_content == c_source
|
||||||
|
@ -530,6 +533,12 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
if(neighbor_is_same_liquid == true
|
if(neighbor_is_same_liquid == true
|
||||||
&& top_is_same_liquid == false)
|
&& top_is_same_liquid == false)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Use backface culled material if neighbor doesn't have a
|
||||||
|
// solidness of 0
|
||||||
|
video::SMaterial *current_material = &liquid_material;
|
||||||
|
if(n_feat.solidness != 0 || n_feat.visual_solidness != 0)
|
||||||
|
current_material = &liquid_material_bfculled;
|
||||||
|
|
||||||
video::S3DVertex vertices[4] =
|
video::S3DVertex vertices[4] =
|
||||||
{
|
{
|
||||||
|
@ -603,7 +612,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
||||||
|
|
||||||
u16 indices[] = {0,1,2,2,3,0};
|
u16 indices[] = {0,1,2,2,3,0};
|
||||||
// Add to mesh collector
|
// Add to mesh collector
|
||||||
collector.append(liquid_material, vertices, 4, indices, 6);
|
collector.append(*current_material, vertices, 4, indices, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -415,6 +415,12 @@ void content_mapnode_init()
|
||||||
AtlasPointer *pa_water1 = new AtlasPointer(g_texturesource->getTexture(
|
AtlasPointer *pa_water1 = new AtlasPointer(g_texturesource->getTexture(
|
||||||
g_texturesource->getTextureId("water.png")));
|
g_texturesource->getTextureId("water.png")));
|
||||||
f->special_material->setTexture(0, pa_water1->atlas);
|
f->special_material->setTexture(0, pa_water1->atlas);
|
||||||
|
|
||||||
|
// Flowing water material, backface culled
|
||||||
|
f->special_material2 = new video::SMaterial;
|
||||||
|
*f->special_material2 = *f->special_material;
|
||||||
|
f->special_material2->setFlag(video::EMF_BACK_FACE_CULLING, true);
|
||||||
|
|
||||||
f->special_atlas = pa_water1;
|
f->special_atlas = pa_water1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -460,7 +466,7 @@ void content_mapnode_init()
|
||||||
f->post_effect_color = video::SColor(64, 100, 100, 200);
|
f->post_effect_color = video::SColor(64, 100, 100, 200);
|
||||||
if(f->special_material == NULL && g_texturesource)
|
if(f->special_material == NULL && g_texturesource)
|
||||||
{
|
{
|
||||||
// Flowing water material
|
// New-style water source material (mostly unused)
|
||||||
f->special_material = new video::SMaterial;
|
f->special_material = new video::SMaterial;
|
||||||
f->special_material->setFlag(video::EMF_LIGHTING, false);
|
f->special_material->setFlag(video::EMF_LIGHTING, false);
|
||||||
f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
|
f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
|
||||||
|
@ -482,7 +488,7 @@ void content_mapnode_init()
|
||||||
f->light_propagates = false;
|
f->light_propagates = false;
|
||||||
f->light_source = LIGHT_MAX-1;
|
f->light_source = LIGHT_MAX-1;
|
||||||
f->solidness = 0; // Drawn separately, makes no faces
|
f->solidness = 0; // Drawn separately, makes no faces
|
||||||
f->visual_solidness = 2;
|
f->visual_solidness = 1; // Does not completely cover block boundaries
|
||||||
f->walkable = false;
|
f->walkable = false;
|
||||||
f->pointable = false;
|
f->pointable = false;
|
||||||
f->diggable = false;
|
f->diggable = false;
|
||||||
|
@ -503,10 +509,17 @@ void content_mapnode_init()
|
||||||
f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false);
|
f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||||
f->special_material->setFlag(video::EMF_FOG_ENABLE, true);
|
f->special_material->setFlag(video::EMF_FOG_ENABLE, true);
|
||||||
f->special_material->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
f->special_material->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||||
|
|
||||||
AtlasPointer *pa_lava1 = new AtlasPointer(
|
AtlasPointer *pa_lava1 = new AtlasPointer(
|
||||||
g_texturesource->getTexture(
|
g_texturesource->getTexture(
|
||||||
g_texturesource->getTextureId("lava.png")));
|
g_texturesource->getTextureId("lava.png")));
|
||||||
f->special_material->setTexture(0, pa_lava1->atlas);
|
f->special_material->setTexture(0, pa_lava1->atlas);
|
||||||
|
|
||||||
|
// Flowing lava material, backface culled
|
||||||
|
f->special_material2 = new video::SMaterial;
|
||||||
|
*f->special_material2 = *f->special_material;
|
||||||
|
f->special_material2->setFlag(video::EMF_BACK_FACE_CULLING, true);
|
||||||
|
|
||||||
f->special_atlas = pa_lava1;
|
f->special_atlas = pa_lava1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -550,7 +563,7 @@ void content_mapnode_init()
|
||||||
f->post_effect_color = video::SColor(192, 255, 64, 0);
|
f->post_effect_color = video::SColor(192, 255, 64, 0);
|
||||||
if(f->special_material == NULL && g_texturesource)
|
if(f->special_material == NULL && g_texturesource)
|
||||||
{
|
{
|
||||||
// Flowing lava material
|
// New-style lava source material (mostly unused)
|
||||||
f->special_material = new video::SMaterial;
|
f->special_material = new video::SMaterial;
|
||||||
f->special_material->setFlag(video::EMF_LIGHTING, false);
|
f->special_material->setFlag(video::EMF_LIGHTING, false);
|
||||||
f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
|
f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
|
||||||
|
@ -561,6 +574,7 @@ void content_mapnode_init()
|
||||||
g_texturesource->getTexture(
|
g_texturesource->getTexture(
|
||||||
g_texturesource->getTextureId("lava.png")));
|
g_texturesource->getTextureId("lava.png")));
|
||||||
f->special_material->setTexture(0, pa_lava1->atlas);
|
f->special_material->setTexture(0, pa_lava1->atlas);
|
||||||
|
|
||||||
f->special_atlas = pa_lava1;
|
f->special_atlas = pa_lava1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -427,7 +427,8 @@ void getTileInfo(
|
||||||
// This is hackish
|
// This is hackish
|
||||||
content_t content0 = getNodeContent(p, n0, temp_mods);
|
content_t content0 = getNodeContent(p, n0, temp_mods);
|
||||||
content_t content1 = getNodeContent(p + face_dir, n1, temp_mods);
|
content_t content1 = getNodeContent(p + face_dir, n1, temp_mods);
|
||||||
u8 mf = face_contents(content0, content1);
|
bool equivalent = false;
|
||||||
|
u8 mf = face_contents(content0, content1, &equivalent);
|
||||||
|
|
||||||
if(mf == 0)
|
if(mf == 0)
|
||||||
{
|
{
|
||||||
|
@ -450,6 +451,10 @@ void getTileInfo(
|
||||||
face_dir_corrected = -face_dir;
|
face_dir_corrected = -face_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eg. water and glass
|
||||||
|
if(equivalent)
|
||||||
|
tile.material_flags |= MATERIAL_FLAG_BACKFACE_CULLING;
|
||||||
|
|
||||||
if(smooth_lighting == false)
|
if(smooth_lighting == false)
|
||||||
{
|
{
|
||||||
lights[0] = lights[1] = lights[2] = lights[3] =
|
lights[0] = lights[1] = lights[2] = lights[3] =
|
||||||
|
|
|
@ -174,6 +174,57 @@ void init_mapnode()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Nodes make a face if contents differ and solidness differs.
|
||||||
|
Return value:
|
||||||
|
0: No face
|
||||||
|
1: Face uses m1's content
|
||||||
|
2: Face uses m2's content
|
||||||
|
equivalent: Whether the blocks share the same face (eg. water and glass)
|
||||||
|
*/
|
||||||
|
u8 face_contents(content_t m1, content_t m2, bool *equivalent)
|
||||||
|
{
|
||||||
|
*equivalent = false;
|
||||||
|
|
||||||
|
if(m1 == CONTENT_IGNORE || m2 == CONTENT_IGNORE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bool contents_differ = (m1 != m2);
|
||||||
|
|
||||||
|
// Contents don't differ for different forms of same liquid
|
||||||
|
if(content_liquid(m1) && content_liquid(m2)
|
||||||
|
&& make_liquid_flowing(m1) == make_liquid_flowing(m2))
|
||||||
|
contents_differ = false;
|
||||||
|
|
||||||
|
u8 c1 = content_solidness(m1);
|
||||||
|
u8 c2 = content_solidness(m2);
|
||||||
|
|
||||||
|
bool solidness_differs = (c1 != c2);
|
||||||
|
bool makes_face = contents_differ && solidness_differs;
|
||||||
|
|
||||||
|
if(makes_face == false)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(c1 == 0)
|
||||||
|
c1 = content_features(m1).visual_solidness;
|
||||||
|
if(c2 == 0)
|
||||||
|
c2 = content_features(m2).visual_solidness;
|
||||||
|
|
||||||
|
if(c1 == c2){
|
||||||
|
*equivalent = true;
|
||||||
|
// If same solidness, liquid takes precense
|
||||||
|
if(content_features(m1).liquid_type != LIQUID_NONE)
|
||||||
|
return 1;
|
||||||
|
if(content_features(m2).liquid_type != LIQUID_NONE)
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c1 > c2)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
v3s16 facedir_rotate(u8 facedir, v3s16 dir)
|
v3s16 facedir_rotate(u8 facedir, v3s16 dir)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -121,6 +121,7 @@ struct ContentFeatures
|
||||||
video::SColor post_effect_color;
|
video::SColor post_effect_color;
|
||||||
// Special irrlicht material, used sometimes
|
// Special irrlicht material, used sometimes
|
||||||
video::SMaterial *special_material;
|
video::SMaterial *special_material;
|
||||||
|
video::SMaterial *special_material2;
|
||||||
AtlasPointer *special_atlas;
|
AtlasPointer *special_atlas;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -199,6 +200,7 @@ struct ContentFeatures
|
||||||
vertex_alpha = 255;
|
vertex_alpha = 255;
|
||||||
post_effect_color = video::SColor(0, 0, 0, 0);
|
post_effect_color = video::SColor(0, 0, 0, 0);
|
||||||
special_material = NULL;
|
special_material = NULL;
|
||||||
|
special_material2 = NULL;
|
||||||
special_atlas = NULL;
|
special_atlas = NULL;
|
||||||
#endif
|
#endif
|
||||||
param_type = CPT_NONE;
|
param_type = CPT_NONE;
|
||||||
|
@ -377,44 +379,9 @@ inline bool content_buildable_to(content_t m)
|
||||||
0: No face
|
0: No face
|
||||||
1: Face uses m1's content
|
1: Face uses m1's content
|
||||||
2: Face uses m2's content
|
2: Face uses m2's content
|
||||||
|
equivalent: Whether the blocks share the same face (eg. water and glass)
|
||||||
*/
|
*/
|
||||||
inline u8 face_contents(content_t m1, content_t m2)
|
u8 face_contents(content_t m1, content_t m2, bool *equivalent);
|
||||||
{
|
|
||||||
if(m1 == CONTENT_IGNORE || m2 == CONTENT_IGNORE)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
bool contents_differ = (m1 != m2);
|
|
||||||
|
|
||||||
// Contents don't differ for different forms of same liquid
|
|
||||||
if(content_liquid(m1) && content_liquid(m2)
|
|
||||||
&& make_liquid_flowing(m1) == make_liquid_flowing(m2))
|
|
||||||
contents_differ = false;
|
|
||||||
|
|
||||||
bool solidness_differs = (content_solidness(m1) != content_solidness(m2));
|
|
||||||
bool makes_face = contents_differ && solidness_differs;
|
|
||||||
|
|
||||||
if(makes_face == false)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
u8 c1 = content_solidness(m1);
|
|
||||||
u8 c2 = content_solidness(m2);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Special case for half-transparent content.
|
|
||||||
|
|
||||||
This makes eg. the water (solidness=1) surrounding an underwater
|
|
||||||
glass block (solidness=0, visual_solidness=1) not get drawn.
|
|
||||||
*/
|
|
||||||
if(c1 == 1 && c2 == 0 && content_features(m2).visual_solidness != 0)
|
|
||||||
return 0;
|
|
||||||
if(c2 == 1 && c1 == 0 && content_features(m1).visual_solidness != 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(c1 > c2)
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Packs directions like (1,0,0), (1,-1,0)
|
Packs directions like (1,0,0), (1,-1,0)
|
||||||
|
|
Loading…
Reference in New Issue