#include "mapblock.h"
#include "map.h"
-// For g_materials
+// For g_settings and g_irrlicht
#include "main.h"
#include "light.h"
#include <sstream>
v3f posRelative_f(getPosRelative().X, getPosRelative().Y,
getPosRelative().Z); // floating point conversion
-
/*
Avoid interlocks by copying m_temp_mods
*/
m_temp_mods.copy(temp_mods);
}
+ bool new_style_water = g_settings.getBool("new_style_water");
+ float node_water_level = 1.0;
+ if(new_style_water)
+ node_water_level = 0.8;
+
/*
We are including the faces of the trailing edges of the block.
This means that when something changes, the caller must
const u16 indices[] = {0,1,2,2,3,0};
video::ITexture *texture = g_irrlicht->getTexture(f.tile.spec);
+ if(texture == NULL)
+ continue;
+
material.setTexture(0, texture);
if(f.tile.alpha != 255)
material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
// Includes current node
core::map<v3s16, f32> neighbor_levels;
core::map<v3s16, u8> neighbor_contents;
+ core::map<v3s16, u8> neighbor_flags;
+ const u8 neighborflag_top_is_water = 0x01;
v3s16 neighbor_dirs[9] = {
v3s16(0,0,0),
v3s16(0,0,1),
{
u8 content = CONTENT_AIR;
float level = -0.5 * BS;
+ u8 flags = 0;
try{
+ // Check neighbor
v3s16 p2 = p + neighbor_dirs[i];
MapNode n2 = getNodeParent(p2);
content = n2.d;
if(n2.d == CONTENT_WATERSOURCE)
- level = 0.5 * BS;
+ level = (-0.5+node_water_level) * BS;
else if(n2.d == CONTENT_WATER)
- level = (-0.5 + ((float)n2.param2 + 0.5) / 8.0) * BS;
+ level = (-0.5 + ((float)n2.param2 + 0.5) / 8.0
+ * node_water_level) * BS;
+
+ // Check node above neighbor.
+ // NOTE: This doesn't get executed if neighbor
+ // doesn't exist
+ p2.Y += 1;
+ n2 = getNodeParent(p2);
+ if(n2.d == CONTENT_WATERSOURCE || n2.d == CONTENT_WATER)
+ flags |= neighborflag_top_is_water;
}
catch(InvalidPositionException &e){}
neighbor_levels.insert(neighbor_dirs[i], level);
neighbor_contents.insert(neighbor_dirs[i], content);
+ neighbor_flags.insert(neighbor_dirs[i], flags);
}
//float water_level = (-0.5 + ((float)n.param2 + 0.5) / 8.0) * BS;
// Special case for source nodes
if(content == CONTENT_WATERSOURCE)
{
- cornerlevel = 0.5*BS;
+ cornerlevel = (-0.5+node_water_level)*BS;
valid_count = 1;
break;
}
{
v3s16 dir = side_dirs[i];
- //float neighbor_level = neighbor_levels[dir];
- /*if(neighbor_level > -0.5*BS + 0.001)
- continue;*/
- /*if(neighbor_level > water_level - 0.1*BS)
- continue;*/
+ /*
+ If our topside is water and neighbor's topside
+ is water, don't draw side face
+ */
+ if(top_is_water &&
+ neighbor_flags[dir] & neighborflag_top_is_water)
+ continue;
u8 neighbor_content = neighbor_contents[dir];
-
+
+ // Don't draw face if neighbor is not air or water
if(neighbor_content != CONTENT_AIR
&& neighbor_content != CONTENT_WATER)
continue;
bool neighbor_is_water = (neighbor_content == CONTENT_WATER);
-
+
+ // Don't draw any faces if neighbor is water and top is water
if(neighbor_is_water == true && top_is_water == false)
continue;
video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,0),
};
+ /*
+ If our topside is water, set upper border of face
+ at upper border of node
+ */
if(top_is_water)
{
vertices[2].Pos.Y = 0.5*BS;
vertices[3].Pos.Y = 0.5*BS;
}
+ /*
+ Otherwise upper position of face is corner levels
+ */
else
{
vertices[2].Pos.Y = corner_levels[side_corners[i][0]];
vertices[3].Pos.Y = corner_levels[side_corners[i][1]];
}
-
+
+ /*
+ If neighbor is water, lower border of face is corner
+ water levels
+ */
if(neighbor_is_water)
{
vertices[0].Pos.Y = corner_levels[side_corners[i][1]];
vertices[1].Pos.Y = corner_levels[side_corners[i][0]];
}
+ /*
+ If neighbor is not water, lower border of face is
+ lower border of node
+ */
else
{
vertices[0].Pos.Y = -0.5*BS;
collector.append(material_w1, vertices, 4, indices, 6);
}
}
+ /*
+ Add water sources to mesh
+ */
+ else if(n.d == CONTENT_WATERSOURCE && new_style_water)
+ {
+ //bool top_is_water = false;
+ bool top_is_air = false;
+ try{
+ MapNode n = getNodeParent(v3s16(x,y+1,z));
+ /*if(n.d == CONTENT_WATER || n.d == CONTENT_WATERSOURCE)
+ top_is_water = true;*/
+ if(n.d == CONTENT_AIR)
+ top_is_air = true;
+ }catch(InvalidPositionException &e){}
+
+ /*if(top_is_water == true)
+ continue;*/
+ if(top_is_air == false)
+ continue;
+
+ u8 l = decode_light(n.getLightBlend(daynight_ratio));
+ video::SColor c(WATER_ALPHA,l,l,l);
+
+ video::S3DVertex vertices[4] =
+ {
+ video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, 0,1),
+ video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c, 1,1),
+ video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,0),
+ video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,0),
+ };
+
+ for(s32 i=0; i<4; i++)
+ {
+ vertices[i].Pos.Y += (-0.5+node_water_level)*BS;
+ vertices[i].Pos += intToFloat(p + getPosRelative());
+ }
+
+ u16 indices[] = {0,1,2,2,3,0};
+ // Add to mesh collector
+ collector.append(material_w1, vertices, 4, indices, 6);
+ }
}
/*
v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1));
+ // Copy from data to VoxelManipulator
dst.copyFrom(data, data_area, v3s16(0,0,0),
getPosRelative(), data_size);
}
+void MapBlock::copyFrom(VoxelManipulator &dst)
+{
+ v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
+ VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1));
+
+ // Copy from VoxelManipulator to data
+ dst.copyTo(data, data_area, v3s16(0,0,0),
+ getPosRelative(), data_size);
+}
+
void MapBlock::stepObjects(float dtime, bool server, u32 daynight_ratio)
{
/*
data[i].param2 = s[i+nodecount*2];
}
}
+
+ /*
+ Translate nodes as specified in the translate_to fields of
+ node features
+ */
+ for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
+ {
+ MapNode &n = data[i];
+
+ MapNode *translate_to = content_features(n.d).translate_to;
+ if(translate_to)
+ {
+ dstream<<"MapBlock: WARNING: Translating node "<<n.d<<" to "
+ <<translate_to->d<<std::endl;
+ n = *translate_to;
+ }
+ }
}