#include "mapblock.h"
#include "map.h"
-// For g_settings and g_irrlicht
+// For g_settings
#include "main.h"
#include "light.h"
#include <sstream>
+#ifndef SERVER
void MeshMakeData::fill(u32 daynight_ratio, MapBlock *block)
{
m_daynight_ratio = daynight_ratio;
}
}
}
+#endif
/*
Parameters must consist of air and !air.
#ifndef SERVER
-void makeFastFace(TileSpec tile, u8 light, v3f p,
- v3s16 dir, v3f scale, v3f posRelative_f,
- core::array<FastFace> &dest)
+/*
+ vertex_dirs: v3s16[4]
+*/
+void getNodeVertexDirs(v3s16 dir, v3s16 *vertex_dirs)
{
- FastFace face;
-
- // Position is at the center of the cube.
- v3f pos = p * BS;
- posRelative_f *= BS;
-
- v3f vertex_pos[4];
- // If looking towards z+, this is the face that is behind
- // the center point, facing towards z+.
- vertex_pos[0] = v3f(-BS/2,-BS/2,BS/2);
- vertex_pos[1] = v3f( BS/2,-BS/2,BS/2);
- vertex_pos[2] = v3f( BS/2, BS/2,BS/2);
- vertex_pos[3] = v3f(-BS/2, BS/2,BS/2);
-
+ /*
+ If looked from outside the node towards the face, the corners are:
+ 0: bottom-right
+ 1: bottom-left
+ 2: top-left
+ 3: top-right
+ */
if(dir == v3s16(0,0,1))
{
- for(u16 i=0; i<4; i++)
- vertex_pos[i].rotateXZBy(0);
+ // If looking towards z+, this is the face that is behind
+ // the center point, facing towards z+.
+ vertex_dirs[0] = v3s16(-1,-1, 1);
+ vertex_dirs[1] = v3s16( 1,-1, 1);
+ vertex_dirs[2] = v3s16( 1, 1, 1);
+ vertex_dirs[3] = v3s16(-1, 1, 1);
}
else if(dir == v3s16(0,0,-1))
{
- for(u16 i=0; i<4; i++)
- vertex_pos[i].rotateXZBy(180);
+ // faces towards Z-
+ vertex_dirs[0] = v3s16( 1,-1,-1);
+ vertex_dirs[1] = v3s16(-1,-1,-1);
+ vertex_dirs[2] = v3s16(-1, 1,-1);
+ vertex_dirs[3] = v3s16( 1, 1,-1);
}
else if(dir == v3s16(1,0,0))
{
- for(u16 i=0; i<4; i++)
- vertex_pos[i].rotateXZBy(-90);
+ // faces towards X+
+ vertex_dirs[0] = v3s16( 1,-1, 1);
+ vertex_dirs[1] = v3s16( 1,-1,-1);
+ vertex_dirs[2] = v3s16( 1, 1,-1);
+ vertex_dirs[3] = v3s16( 1, 1, 1);
}
else if(dir == v3s16(-1,0,0))
{
- for(u16 i=0; i<4; i++)
- vertex_pos[i].rotateXZBy(90);
+ // faces towards X-
+ vertex_dirs[0] = v3s16(-1,-1,-1);
+ vertex_dirs[1] = v3s16(-1,-1, 1);
+ vertex_dirs[2] = v3s16(-1, 1, 1);
+ vertex_dirs[3] = v3s16(-1, 1,-1);
}
else if(dir == v3s16(0,1,0))
{
- for(u16 i=0; i<4; i++)
- vertex_pos[i].rotateYZBy(-90);
+ // faces towards Y+ (assume Z- as "down" in texture)
+ vertex_dirs[0] = v3s16( 1, 1,-1);
+ vertex_dirs[1] = v3s16(-1, 1,-1);
+ vertex_dirs[2] = v3s16(-1, 1, 1);
+ vertex_dirs[3] = v3s16( 1, 1, 1);
}
else if(dir == v3s16(0,-1,0))
{
- for(u16 i=0; i<4; i++)
- vertex_pos[i].rotateYZBy(90);
+ // faces towards Y- (assume Z+ as "down" in texture)
+ vertex_dirs[0] = v3s16( 1,-1, 1);
+ vertex_dirs[1] = v3s16(-1,-1, 1);
+ vertex_dirs[2] = v3s16(-1,-1,-1);
+ vertex_dirs[3] = v3s16( 1,-1,-1);
+ }
+}
+
+inline video::SColor lightColor(u8 alpha, u8 light)
+{
+ return video::SColor(alpha,light,light,light);
+}
+
+void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
+ v3s16 dir, v3f scale, v3f posRelative_f,
+ core::array<FastFace> &dest)
+{
+ FastFace face;
+
+ // Position is at the center of the cube.
+ v3f pos = p * BS;
+ posRelative_f *= BS;
+
+ v3f vertex_pos[4];
+ v3s16 vertex_dirs[4];
+ getNodeVertexDirs(dir, vertex_dirs);
+ for(u16 i=0; i<4; i++)
+ {
+ vertex_pos[i] = v3f(
+ BS/2*vertex_dirs[i].X,
+ BS/2*vertex_dirs[i].Y,
+ BS/2*vertex_dirs[i].Z
+ );
}
for(u16 i=0; i<4; i++)
v3f zerovector = v3f(0,0,0);
- //u8 li = decode_light(light);
- u8 li = light;
- //u8 li = 255; //DEBUG
-
u8 alpha = tile.alpha;
/*u8 alpha = 255;
if(tile.id == TILE_WATER)
alpha = WATER_ALPHA;*/
- video::SColor c = video::SColor(alpha,li,li,li);
-
float x0 = tile.texture.pos.X;
float y0 = tile.texture.pos.Y;
float w = tile.texture.size.X;
float h = tile.texture.size.Y;
+ /*video::SColor c = lightColor(alpha, li);
+
face.vertices[0] = video::S3DVertex(vertex_pos[0], v3f(0,1,0), c,
core::vector2d<f32>(x0+w*abs_scale, y0+h));
face.vertices[1] = video::S3DVertex(vertex_pos[1], v3f(0,1,0), c,
face.vertices[2] = video::S3DVertex(vertex_pos[2], v3f(0,1,0), c,
core::vector2d<f32>(x0, y0));
face.vertices[3] = video::S3DVertex(vertex_pos[3], v3f(0,1,0), c,
+ core::vector2d<f32>(x0+w*abs_scale, y0));*/
+
+ face.vertices[0] = video::S3DVertex(vertex_pos[0], v3f(0,1,0),
+ lightColor(alpha, li0),
+ core::vector2d<f32>(x0+w*abs_scale, y0+h));
+ face.vertices[1] = video::S3DVertex(vertex_pos[1], v3f(0,1,0),
+ lightColor(alpha, li1),
+ core::vector2d<f32>(x0, y0+h));
+ face.vertices[2] = video::S3DVertex(vertex_pos[2], v3f(0,1,0),
+ lightColor(alpha, li2),
+ core::vector2d<f32>(x0, y0));
+ face.vertices[3] = video::S3DVertex(vertex_pos[3], v3f(0,1,0),
+ lightColor(alpha, li3),
core::vector2d<f32>(x0+w*abs_scale, y0));
face.tile = tile;
//f->tile = TILE_STONE;
dest.push_back(face);
- //return f;
}
/*
return mn.d;
}
+v3s16 dirs8[8] = {
+ v3s16(0,0,0),
+ v3s16(0,0,1),
+ v3s16(0,1,0),
+ v3s16(0,1,1),
+ v3s16(1,0,0),
+ v3s16(1,1,0),
+ v3s16(1,0,1),
+ v3s16(1,1,1),
+};
+
+// Calculate lighting at the XYZ- corner of p
+u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio)
+{
+ u16 ambient_occlusion = 0;
+ u16 light = 0;
+ u16 light_count = 0;
+ for(u32 i=0; i<8; i++)
+ {
+ MapNode n = vmanip.getNodeNoEx(p - dirs8[i]);
+ if(content_features(n.d).param_type == CPT_LIGHT)
+ {
+ light += decode_light(n.getLightBlend(daynight_ratio));
+ light_count++;
+ }
+ else
+ {
+ if(n.d != CONTENT_IGNORE)
+ ambient_occlusion++;
+ }
+ }
+
+ if(light_count == 0)
+ return 255;
+
+ light /= light_count;
+
+ if(ambient_occlusion > 4)
+ {
+ ambient_occlusion -= 4;
+ light = (float)light / ((float)ambient_occlusion * 0.5 + 1.0);
+ }
+
+ return light;
+}
+
+// Calculate lighting at the given corner of p
+u8 getSmoothLight(v3s16 p, v3s16 corner,
+ VoxelManipulator &vmanip, u32 daynight_ratio)
+{
+ if(corner.X == 1) p.X += 1;
+ else assert(corner.X == -1);
+ if(corner.Y == 1) p.Y += 1;
+ else assert(corner.Y == -1);
+ if(corner.Z == 1) p.Z += 1;
+ else assert(corner.Z == -1);
+
+ return getSmoothLight(p, vmanip, daynight_ratio);
+}
+
+void getTileInfo(
+ // Input:
+ v3s16 blockpos_nodes,
+ v3s16 p,
+ v3s16 face_dir,
+ u32 daynight_ratio,
+ VoxelManipulator &vmanip,
+ NodeModMap &temp_mods,
+ bool smooth_lighting,
+ // Output:
+ bool &makes_face,
+ v3s16 &p_corrected,
+ v3s16 &face_dir_corrected,
+ u8 *lights,
+ TileSpec &tile
+ )
+{
+ MapNode n0 = vmanip.getNodeNoEx(blockpos_nodes + p);
+ MapNode n1 = vmanip.getNodeNoEx(blockpos_nodes + p + face_dir);
+ TileSpec tile0 = getNodeTile(n0, p, face_dir, temp_mods);
+ TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods);
+
+ // This is hackish
+ u8 content0 = getNodeContent(p, n0, temp_mods);
+ u8 content1 = getNodeContent(p + face_dir, n1, temp_mods);
+ u8 mf = face_contents(content0, content1);
+
+ if(mf == 0)
+ {
+ makes_face = false;
+ return;
+ }
+
+ makes_face = true;
+
+ if(mf == 1)
+ {
+ tile = tile0;
+ p_corrected = p;
+ face_dir_corrected = face_dir;
+ }
+ else
+ {
+ tile = tile1;
+ p_corrected = p + face_dir;
+ face_dir_corrected = -face_dir;
+ }
+
+ if(smooth_lighting == false)
+ {
+ lights[0] = lights[1] = lights[2] = lights[3] =
+ decode_light(getFaceLight(daynight_ratio, n0, n1, face_dir));
+ }
+ else
+ {
+ v3s16 vertex_dirs[4];
+ getNodeVertexDirs(face_dir_corrected, vertex_dirs);
+ for(u16 i=0; i<4; i++)
+ {
+ lights[i] = getSmoothLight(blockpos_nodes + p_corrected,
+ vertex_dirs[i], vmanip, daynight_ratio);
+ }
+ }
+
+ return;
+}
+
/*
startpos:
translate_dir: unit vector with only one of x, y or z
core::array<FastFace> &dest,
NodeModMap &temp_mods,
VoxelManipulator &vmanip,
- v3s16 blockpos_nodes)
+ v3s16 blockpos_nodes,
+ bool smooth_lighting)
{
v3s16 p = startpos;
u16 continuous_tiles_count = 0;
- MapNode n0 = vmanip.getNodeNoEx(blockpos_nodes + p);
- MapNode n1 = vmanip.getNodeNoEx(blockpos_nodes + p + face_dir);
- TileSpec tile0 = getNodeTile(n0, p, face_dir, temp_mods);
- TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods);
- u8 light = getFaceLight(daynight_ratio, n0, n1, face_dir);
+ bool makes_face;
+ v3s16 p_corrected;
+ v3s16 face_dir_corrected;
+ u8 lights[4];
+ TileSpec tile;
+ getTileInfo(blockpos_nodes, p, face_dir, daynight_ratio,
+ vmanip, temp_mods, smooth_lighting,
+ makes_face, p_corrected, face_dir_corrected, lights, tile);
for(u16 j=0; j<length; j++)
{
+ // If tiling can be done, this is set to false in the next step
bool next_is_different = true;
v3s16 p_next;
- MapNode n0_next;
- MapNode n1_next;
- TileSpec tile0_next;
- TileSpec tile1_next;
- u8 light_next = 0;
+
+ bool next_makes_face;
+ v3s16 next_p_corrected;
+ v3s16 next_face_dir_corrected;
+ u8 next_lights[4];
+ TileSpec next_tile;
// If at last position, there is nothing to compare to and
// the face must be drawn anyway
{
p_next = p + translate_dir;
- n0_next = vmanip.getNodeNoEx(blockpos_nodes + p_next);
- n1_next = vmanip.getNodeNoEx(blockpos_nodes + p_next + face_dir);
- tile0_next = getNodeTile(n0_next, p_next, face_dir, temp_mods);
- tile1_next = getNodeTile(n1_next,p_next+face_dir,-face_dir, temp_mods);
- light_next = getFaceLight(daynight_ratio, n0_next, n1_next, face_dir);
-
- if(tile0_next == tile0
- && tile1_next == tile1
- && light_next == light)
+ getTileInfo(blockpos_nodes, p_next, face_dir, daynight_ratio,
+ vmanip, temp_mods, smooth_lighting,
+ next_makes_face, next_p_corrected,
+ next_face_dir_corrected, next_lights,
+ next_tile);
+
+ if(next_makes_face == makes_face
+ && next_p_corrected == p_corrected
+ && next_face_dir_corrected == face_dir_corrected
+ && next_lights[0] == lights[0]
+ && next_lights[1] == lights[1]
+ && next_lights[2] == lights[2]
+ && next_lights[3] == lights[3]
+ && next_tile == tile)
{
next_is_different = false;
}
If there is no texture, it can be tiled infinitely.
If tiled==0, it means the texture can be tiled infinitely.
Otherwise check tiled agains continuous_tiles_count.
-
- This check has to be made for both tiles, because this is
- a bit hackish and we know which one we're using only when
- the decision to make the faces is made.
*/
- if(tile0.texture.atlas != NULL && tile0.texture.tiled != 0)
+ if(tile.texture.atlas != NULL && tile.texture.tiled != 0)
{
- if(tile0.texture.tiled <= continuous_tiles_count)
- end_of_texture = true;
- }
- if(tile1.texture.atlas != NULL && tile1.texture.tiled != 0)
- {
- if(tile1.texture.tiled <= continuous_tiles_count)
+ if(tile.texture.tiled <= continuous_tiles_count)
end_of_texture = true;
}
+ // Do this to disable tiling textures
//end_of_texture = true; //DEBUG
if(next_is_different || end_of_texture)
/*
Create a face if there should be one
*/
- //u8 mf = face_contents(tile0, tile1);
- // This is hackish
- u8 content0 = getNodeContent(p, n0, temp_mods);
- u8 content1 = getNodeContent(p + face_dir, n1, temp_mods);
- u8 mf = face_contents(content0, content1);
-
- if(mf != 0)
+ if(makes_face)
{
// Floating point conversion of the position vector
- v3f pf(p.X, p.Y, p.Z);
+ v3f pf(p_corrected.X, p_corrected.Y, p_corrected.Z);
// Center point of face (kind of)
v3f sp = pf - ((f32)continuous_tiles_count / 2. - 0.5) * translate_dir_f;
v3f scale(1,1,1);
- if(translate_dir.X != 0){
+
+ if(translate_dir.X != 0)
+ {
scale.X = continuous_tiles_count;
}
- if(translate_dir.Y != 0){
+ if(translate_dir.Y != 0)
+ {
scale.Y = continuous_tiles_count;
}
- if(translate_dir.Z != 0){
+ if(translate_dir.Z != 0)
+ {
scale.Z = continuous_tiles_count;
}
- //FastFace *f;
-
- // If node at sp (tile0) is more solid
- if(mf == 1)
- {
- makeFastFace(tile0, decode_light(light),
- sp, face_dir, scale,
- posRelative_f, dest);
- }
- // If node at sp is less solid (mf == 2)
- else
- {
- makeFastFace(tile1, decode_light(light),
- sp+face_dir_f, -face_dir, scale,
- posRelative_f, dest);
- }
- //dest.push_back(f);
+ makeFastFace(tile, lights[0], lights[1], lights[2], lights[3],
+ sp, face_dir_corrected, scale,
+ posRelative_f, dest);
}
continuous_tiles_count = 0;
- n0 = n0_next;
- n1 = n1_next;
- tile0 = tile0_next;
- tile1 = tile1_next;
- light = light_next;
+
+ makes_face = next_makes_face;
+ p_corrected = next_p_corrected;
+ face_dir_corrected = next_face_dir_corrected;
+ lights[0] = next_lights[0];
+ lights[1] = next_lights[1];
+ lights[2] = next_lights[2];
+ lights[3] = next_lights[3];
+ tile = next_tile;
}
p = p_next;
*/
bool new_style_water = g_settings.getBool("new_style_water");
bool new_style_leaves = g_settings.getBool("new_style_leaves");
+ bool smooth_lighting = g_settings.getBool("smooth_lighting");
float node_water_level = 1.0;
if(new_style_water)
//TimeTaker timer2("updateMesh() collect");
/*
- Go through every y,z and get top faces in rows of x+
+ Go through every y,z and get top(y+) faces in rows of x+
*/
for(s16 y=0; y<MAP_BLOCKSIZE; y++){
for(s16 z=0; z<MAP_BLOCKSIZE; z++){
fastfaces_new,
data->m_temp_mods,
data->m_vmanip,
- blockpos_nodes);
+ blockpos_nodes,
+ smooth_lighting);
}
}
/*
- Go through every x,y and get right faces in rows of z+
+ Go through every x,y and get right(x+) faces in rows of z+
*/
for(s16 x=0; x<MAP_BLOCKSIZE; x++){
for(s16 y=0; y<MAP_BLOCKSIZE; y++){
fastfaces_new,
data->m_temp_mods,
data->m_vmanip,
- blockpos_nodes);
+ blockpos_nodes,
+ smooth_lighting);
}
}
/*
- Go through every y,z and get back faces in rows of x+
+ Go through every y,z and get back(z+) faces in rows of x+
*/
for(s16 z=0; z<MAP_BLOCKSIZE; z++){
for(s16 y=0; y<MAP_BLOCKSIZE; y++){
fastfaces_new,
data->m_temp_mods,
data->m_vmanip,
- blockpos_nodes);
+ blockpos_nodes,
+ smooth_lighting);
}
}
}
FastFace &f = fastfaces_new[i];
const u16 indices[] = {0,1,2,2,3,0};
+ const u16 indices_alternate[] = {0,1,3,2,3,1};
- //video::ITexture *texture = g_irrlicht->getTexture(f.tile.spec);
video::ITexture *texture = f.tile.texture.atlas;
if(texture == NULL)
continue;
material.setTexture(0, texture);
f.tile.applyMaterialOptions(material);
+
+ const u16 *indices_p = indices;
+
+ /*
+ Revert triangles for nicer looking gradient if vertices
+ 1 and 3 have same color or 0 and 2 have different color.
+ */
+ if(f.vertices[0].Color != f.vertices[2].Color
+ || f.vertices[1].Color == f.vertices[3].Color)
+ indices_p = indices_alternate;
- collector.append(material, f.vertices, 4, indices, 6);
+ collector.append(material, f.vertices, 4, indices_p, 6);
}
}
// Flowing water material
video::SMaterial material_water1;
material_water1.setFlag(video::EMF_LIGHTING, false);
- //material_water1.setFlag(video::EMF_BACK_FACE_CULLING, false);
+ material_water1.setFlag(video::EMF_BACK_FACE_CULLING, false);
material_water1.setFlag(video::EMF_BILINEAR_FILTER, false);
material_water1.setFlag(video::EMF_FOG_ENABLE, true);
material_water1.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
- //TODO
- //material_water1.setTexture(0, g_irrlicht->getTexture("water.png"));
AtlasPointer pa_water1 = g_texturesource->getTexture(
g_texturesource->getTextureId("water.png"));
material_water1.setTexture(0, pa_water1.atlas);
material_leaves1.setFlag(video::EMF_BILINEAR_FILTER, false);
material_leaves1.setFlag(video::EMF_FOG_ENABLE, true);
material_leaves1.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
- //TODO
- //material_leaves1.setTexture(0, g_irrlicht->getTexture("leaves.png"));
AtlasPointer pa_leaves1 = g_texturesource->getTexture(
g_texturesource->getTextureId("leaves.png"));
material_leaves1.setTexture(0, pa_leaves1.atlas);
+ // Glass material
+ video::SMaterial material_glass;
+ material_glass.setFlag(video::EMF_LIGHTING, false);
+ material_glass.setFlag(video::EMF_BILINEAR_FILTER, false);
+ material_glass.setFlag(video::EMF_FOG_ENABLE, true);
+ material_glass.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+ AtlasPointer pa_glass = g_texturesource->getTexture(
+ g_texturesource->getTextureId("glass.png"));
+ material_glass.setTexture(0, pa_glass.atlas);
+
+
for(s16 z=0; z<MAP_BLOCKSIZE; z++)
for(s16 y=0; y<MAP_BLOCKSIZE; y++)
for(s16 x=0; x<MAP_BLOCKSIZE; x++)
else if(n.d == CONTENT_WATER)
{
bool top_is_water = false;
- MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
- if(n.d == CONTENT_WATER || n.d == CONTENT_WATERSOURCE)
+ MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
+ if(ntop.d == CONTENT_WATER || ntop.d == CONTENT_WATERSOURCE)
top_is_water = true;
- u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+ u8 l = 0;
+ // Use the light of the node on top if possible
+ if(content_features(ntop.d).param_type == CPT_LIGHT)
+ l = decode_light(ntop.getLightBlend(data->m_daynight_ratio));
+ // Otherwise use the light of this node (the water)
+ else
+ l = decode_light(n.getLightBlend(data->m_daynight_ratio));
video::SColor c(WATER_ALPHA,l,l,l);
// Neighbor water levels (key = relative position)
collector.append(material_leaves1, vertices, 4, indices, 6);
}
}
+ /*
+ Add glass
+ */
+ else if(n.d == CONTENT_GLASS)
+ {
+ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+ video::SColor c(255,l,l,l);
+
+ for(u32 j=0; j<6; j++)
+ {
+ video::S3DVertex vertices[4] =
+ {
+ video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c,
+ pa_glass.x0(), pa_glass.y1()),
+ video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c,
+ pa_glass.x1(), pa_glass.y1()),
+ video::S3DVertex(BS/2,BS/2,BS/2, 0,0,0, c,
+ pa_glass.x1(), pa_glass.y0()),
+ video::S3DVertex(-BS/2,BS/2,BS/2, 0,0,0, c,
+ pa_glass.x0(), pa_glass.y0()),
+ };
+
+ if(j == 0)
+ {
+ for(u16 i=0; i<4; i++)
+ vertices[i].Pos.rotateXZBy(0);
+ }
+ else if(j == 1)
+ {
+ for(u16 i=0; i<4; i++)
+ vertices[i].Pos.rotateXZBy(180);
+ }
+ else if(j == 2)
+ {
+ for(u16 i=0; i<4; i++)
+ vertices[i].Pos.rotateXZBy(-90);
+ }
+ else if(j == 3)
+ {
+ for(u16 i=0; i<4; i++)
+ vertices[i].Pos.rotateXZBy(90);
+ }
+ else if(j == 4)
+ {
+ for(u16 i=0; i<4; i++)
+ vertices[i].Pos.rotateYZBy(-90);
+ }
+ else if(j == 5)
+ {
+ for(u16 i=0; i<4; i++)
+ vertices[i].Pos.rotateYZBy(90);
+ }
+
+ for(u16 i=0; i<4; i++)
+ {
+ vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
+ }
+
+ u16 indices[] = {0,1,2,2,3,0};
+ // Add to mesh collector
+ collector.append(material_glass, vertices, 4, indices, 6);
+ }
+ }
+
+
+
}
/*
//std::cout<<"added "<<fastfaces.getSize()<<" faces."<<std::endl;
}
+#endif // !SERVER
/*
MapBlock
if(dummy == false)
reallocate();
- m_spawn_timer = -10000;
+ //m_spawn_timer = -10000;
#ifndef SERVER
m_mesh_expired = false;
}
}
+#ifndef SERVER
+
#if 1
void MapBlock::updateMesh(u32 daynight_ratio)
{
Step objects
*/
m_objects.step(dtime, server, daynight_ratio);
-
+
+#if 0
/*
Spawn some objects at random.
}
}
}
+#endif
setChangedFlag();
}
*/
if(version >= 14)
{
- m_node_metadata.serialize(os);
+ if(version <= 15)
+ {
+ try{
+ std::ostringstream oss(std::ios_base::binary);
+ m_node_metadata.serialize(oss);
+ os<<serializeString(oss.str());
+ }
+ // This will happen if the string is longer than 65535
+ catch(SerializationError &e)
+ {
+ // Use an empty string
+ os<<serializeString("");
+ }
+ }
+ else
+ {
+ std::ostringstream oss(std::ios_base::binary);
+ m_node_metadata.serialize(oss);
+ compressZlib(oss.str(), os);
+ //os<<serializeLongString(oss.str());
+ }
}
}
}
if(!ser_ver_supported(version))
throw VersionMismatchException("ERROR: MapBlock format not supported");
+ // These have no lighting info
+ if(version <= 1)
+ {
+ setLightingExpired(true);
+ }
+
// These have no compression
if(version <= 3 || version == 5 || version == 6)
{
*/
if(version >= 14)
{
- m_node_metadata.deSerialize(is);
+ // Ignore errors
+ try{
+ if(version <= 15)
+ {
+ std::string data = deSerializeString(is);
+ std::istringstream iss(data, std::ios_base::binary);
+ m_node_metadata.deSerialize(iss);
+ }
+ else
+ {
+ //std::string data = deSerializeLongString(is);
+ std::ostringstream oss(std::ios_base::binary);
+ decompressZlib(is, oss);
+ std::istringstream iss(oss.str(), std::ios_base::binary);
+ m_node_metadata.deSerialize(iss);
+ }
+ }
+ catch(SerializationError &e)
+ {
+ dstream<<"WARNING: MapBlock::deSerialize(): Ignoring an error"
+ <<" while deserializing node metadata"<<std::endl;
+ }
}
}