]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/mapblock.cpp
Moved the temporary mapgen test files and added a modified map.cpp too... These are...
[dragonfireclient.git] / src / mapblock.cpp
index 284c64300394c02330622e46c8fc0fc3a94737f4..58b23bd146e6001d50055a18357c1e1ae308bde7 100644 (file)
@@ -223,45 +223,6 @@ void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
                );
        }
 
-       /*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(dir == v3s16(0,0,1))
-       {
-               for(u16 i=0; i<4; i++)
-                       vertex_pos[i].rotateXZBy(0);
-       }
-       else if(dir == v3s16(0,0,-1))
-       {
-               for(u16 i=0; i<4; i++)
-                       vertex_pos[i].rotateXZBy(180);
-       }
-       else if(dir == v3s16(1,0,0))
-       {
-               for(u16 i=0; i<4; i++)
-                       vertex_pos[i].rotateXZBy(-90);
-       }
-       else if(dir == v3s16(-1,0,0))
-       {
-               for(u16 i=0; i<4; i++)
-                       vertex_pos[i].rotateXZBy(90);
-       }
-       else if(dir == v3s16(0,1,0))
-       {
-               for(u16 i=0; i<4; i++)
-                       vertex_pos[i].rotateYZBy(-90);
-       }
-       else if(dir == v3s16(0,-1,0))
-       {
-               for(u16 i=0; i<4; i++)
-                       vertex_pos[i].rotateYZBy(90);
-       }*/
-
        for(u16 i=0; i<4; i++)
        {
                vertex_pos[i].X *= scale.X;
@@ -472,6 +433,73 @@ u8 getSmoothLight(v3s16 p, v3s16 corner,
        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
@@ -496,11 +524,14 @@ void updateFastFaceRow(
        
        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++)
        {
@@ -508,11 +539,12 @@ void updateFastFaceRow(
                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
@@ -520,15 +552,20 @@ void updateFastFaceRow(
                {
                        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;
                        }
@@ -542,50 +579,28 @@ void updateFastFaceRow(
                        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
                
-               // Disable tiling of textures if smooth lighting is used
-               if(smooth_lighting)
-                       end_of_texture = true;
-               
                if(next_is_different || end_of_texture)
                {
                        /*
                                Create a face if there should be one
                        */
-                       // 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);
-                               u8 li0=255, li1=255, li2=255, li3=255;
-
-                               // First node
-                               v3s16 p_first = p - (continuous_tiles_count-1) * translate_dir;
 
                                if(translate_dir.X != 0)
                                {
@@ -600,171 +615,21 @@ void updateFastFaceRow(
                                        scale.Z = continuous_tiles_count;
                                }
                                
-#if 1
-                               v3s16 p_map_leftmost;
-                               v3s16 p_map_rightmost;
-                               v3s16 face_dir_corrected;
-                               TileSpec tile;
-
-                               if(mf == 1)
-                               {
-                                       tile = tile0;
-                                       face_dir_corrected = face_dir;
-                                       p_map_leftmost = p + blockpos_nodes;
-                                       p_map_rightmost = p_first + blockpos_nodes;
-                               }
-                               else
-                               {
-                                       // Offset to the actual solid block
-                                       p_map_leftmost = p + blockpos_nodes + face_dir;
-                                       p_map_rightmost = p_first + blockpos_nodes + face_dir;
-                                       /*if(face_dir == v3s16(0,0,1))
-                                       {
-                                               v3s16 orig_leftmost = p_map_leftmost;
-                                               v3s16 orig_rightmost = p_map_leftmost;
-                                               p_map_leftmost = orig_rightmost;
-                                               p_map_rightmost = orig_leftmost;
-                                       }*/
-                                       sp += face_dir_f;
-                                       face_dir_corrected = -face_dir;
-                                       tile = tile1;
-                               }
-
-                               if(smooth_lighting == false)
-                               {
-                                       li0 = li1 = li2 = li3 = decode_light(light);
-                               }
-                               else
-                               {
-                                       v3s16 vertex_dirs[4];
-                                       getNodeVertexDirs(face_dir_corrected, vertex_dirs);
-                                       
-                                       li0 = getSmoothLight(p_map_rightmost, vertex_dirs[0],
-                                                       vmanip, daynight_ratio);
-                                       li1 = getSmoothLight(p_map_leftmost, vertex_dirs[1],
-                                                       vmanip, daynight_ratio);
-                                       li2 = getSmoothLight(p_map_leftmost, vertex_dirs[2],
-                                                       vmanip, daynight_ratio);
-                                       li3 = getSmoothLight(p_map_rightmost, vertex_dirs[3],
-                                                       vmanip, daynight_ratio);
-                               }
-
-                               makeFastFace(tile, li0, li1, li2, li3,
+                               makeFastFace(tile, lights[0], lights[1], lights[2], lights[3],
                                                sp, face_dir_corrected, scale,
                                                posRelative_f, dest);
-#else
-                               v3s16 p_map = p + blockpos_nodes;
-                               v3s16 p_map_first = p_first + blockpos_nodes;
-
-                               // If node at sp (tile0) is more solid
-                               if(mf == 1)
-                               {
-                                       if(smooth_lighting)
-                                       {
-                                               if(face_dir == v3s16(0,0,1))
-                                               {
-                                                       // Going along X+, faces in Z+
-                                                       li0 = getSmoothLight(p_map_first, v3s16(-1,-1,1),
-                                                                       vmanip, daynight_ratio);
-                                                       li1 = getSmoothLight(p_map, v3s16(1,-1,1),
-                                                                       vmanip, daynight_ratio);
-                                                       li2 = getSmoothLight(p_map, v3s16(1,1,1),
-                                                                       vmanip, daynight_ratio);
-                                                       li3 = getSmoothLight(p_map_first, v3s16(-1,1,1),
-                                                                       vmanip, daynight_ratio);
-                                               }
-                                               else if(face_dir == v3s16(0,1,0))
-                                               {
-                                                       // Going along X+, faces in Y+
-                                                       li0 = getSmoothLight(p_map_first, v3s16( 1,1,-1),
-                                                                       vmanip, daynight_ratio);
-                                                       li1 = getSmoothLight(p_map, v3s16(-1,1,-1),
-                                                                       vmanip, daynight_ratio);
-                                                       li2 = getSmoothLight(p_map, v3s16(-1,1,1),
-                                                                       vmanip, daynight_ratio);
-                                                       li3 = getSmoothLight(p_map_first, v3s16( 1,1,1),
-                                                                       vmanip, daynight_ratio);
-                                               }
-                                               else if(face_dir == v3s16(1,0,0))
-                                               {
-                                                       // Going along Z+, faces in X+
-                                                       li0 = getSmoothLight(p_map_first, v3s16(1,-1,1),
-                                                                       vmanip, daynight_ratio);
-                                                       li1 = getSmoothLight(p_map, v3s16(1,-1,-1),
-                                                                       vmanip, daynight_ratio);
-                                                       li2 = getSmoothLight(p_map, v3s16(1,1,-1),
-                                                                       vmanip, daynight_ratio);
-                                                       li3 = getSmoothLight(p_map_first, v3s16(1,1,1),
-                                                                       vmanip, daynight_ratio);
-                                               }
-                                               else assert(0);
-                                       }
-
-                                       makeFastFace(tile0, li0, li1, li2, li3,
-                                                       sp, face_dir, scale,
-                                                       posRelative_f, dest);
-                               }
-                               // If node at sp is less solid (mf == 2)
-                               else
-                               {
-                                       if(smooth_lighting)
-                                       {
-                                               // Offset to the actual solid block
-                                               p_map += face_dir;
-                                               p_map_first += face_dir;
-                                               
-                                               if(face_dir == v3s16(0,0,1))
-                                               {
-                                                       // Going along X+, faces in Z-
-                                                       li0 = getSmoothLight(p_map, v3s16(1,-1,-1),
-                                                                       vmanip, daynight_ratio);
-                                                       li1 = getSmoothLight(p_map_first, v3s16(-1,-1,-1),
-                                                                       vmanip, daynight_ratio);
-                                                       li2 = getSmoothLight(p_map_first, v3s16(-1,1,-1),
-                                                                       vmanip, daynight_ratio);
-                                                       li3 = getSmoothLight(p_map, v3s16(1,1,-1),
-                                                                       vmanip, daynight_ratio);
-                                               }
-                                               else if(face_dir == v3s16(0,1,0))
-                                               {
-                                                       // Going along X+, faces in Y-
-                                                       li0 = getSmoothLight(p_map_first, v3s16(-1,-1,1),
-                                                                       vmanip, daynight_ratio);
-                                                       li1 = getSmoothLight(p_map, v3s16(1,-1,1),
-                                                                       vmanip, daynight_ratio);
-                                                       li2 = getSmoothLight(p_map, v3s16(1,-1,-1),
-                                                                       vmanip, daynight_ratio);
-                                                       li3 = getSmoothLight(p_map_first, v3s16(-1,-1,-1),
-                                                                       vmanip, daynight_ratio);
-                                               }
-                                               else if(face_dir == v3s16(1,0,0))
-                                               {
-                                                       // Going along Z+, faces in X-
-                                                       li0 = getSmoothLight(p_map_first, v3s16(-1,-1,-1),
-                                                                       vmanip, daynight_ratio);
-                                                       li1 = getSmoothLight(p_map, v3s16(-1,-1,1),
-                                                                       vmanip, daynight_ratio);
-                                                       li2 = getSmoothLight(p_map, v3s16(-1,1,1),
-                                                                       vmanip, daynight_ratio);
-                                                       li3 = getSmoothLight(p_map_first, v3s16(-1,1,-1),
-                                                                       vmanip, daynight_ratio);
-                                               }
-                                               else assert(0);
-                                       }
-
-                                       makeFastFace(tile1, li0, li1, li2, li3,
-                                                       sp+face_dir_f, -face_dir, scale,
-                                                       posRelative_f, dest);
-                               }
-#endif
                        }
 
                        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;
@@ -981,6 +846,7 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data)
                        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 = f.tile.texture.atlas;
                        if(texture == NULL)
@@ -989,8 +855,18 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data)
                        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);
                }
        }
 
@@ -1025,6 +901,17 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data)
                        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++)
@@ -1530,6 +1417,72 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data)
                                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);
+                       }
+               }
+
+
+
        }
 
        /*
@@ -2233,9 +2186,17 @@ void MapBlock::serialize(std::ostream &os, u8 version)
                {
                        if(version <= 15)
                        {
-                               std::ostringstream oss(std::ios_base::binary);
-                               m_node_metadata.serialize(oss);
-                               os<<serializeString(oss.str());
+                               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
                        {