]> git.lizzy.rs Git - minetest.git/blobdiff - src/mapblock_mesh.cpp
Light update for map blocks
[minetest.git] / src / mapblock_mesh.cpp
index 2520b5459ad1c1361cafc7c42bc1e94de7967c03..933dfc32aa8e5ce4eb9246c06e56123a9e499088 100644 (file)
@@ -48,49 +48,43 @@ MeshMakeData::MeshMakeData(Client *client, bool use_shaders,
        m_use_tangent_vertices(use_tangent_vertices)
 {}
 
-void MeshMakeData::fill(MapBlock *block)
+void MeshMakeData::fillBlockDataBegin(const v3s16 &blockpos)
 {
-       m_blockpos = block->getPos();
+       m_blockpos = blockpos;
 
        v3s16 blockpos_nodes = m_blockpos*MAP_BLOCKSIZE;
 
-       /*
-               Copy data
-       */
-
-       // Allocate this block + neighbors
        m_vmanip.clear();
        VoxelArea voxel_area(blockpos_nodes - v3s16(1,1,1) * MAP_BLOCKSIZE,
                        blockpos_nodes + v3s16(1,1,1) * MAP_BLOCKSIZE*2-v3s16(1,1,1));
        m_vmanip.addArea(voxel_area);
+}
 
-       {
-               //TimeTaker timer("copy central block data");
-               // 0ms
+void MeshMakeData::fillBlockData(const v3s16 &block_offset, MapNode *data)
+{
+       v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
+       VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1));
 
-               // Copy our data
-               block->copyTo(m_vmanip);
-       }
-       {
-               //TimeTaker timer("copy neighbor block data");
-               // 0ms
+       v3s16 bp = m_blockpos + block_offset;
+       v3s16 blockpos_nodes = bp * MAP_BLOCKSIZE;
+       m_vmanip.copyFrom(data, data_area, v3s16(0,0,0), blockpos_nodes, data_size);
+}
 
-               /*
-                       Copy neighbors. This is lightning fast.
-                       Copying only the borders would be *very* slow.
-               */
+void MeshMakeData::fill(MapBlock *block)
+{
+       fillBlockDataBegin(block->getPos());
 
-               // Get map
-               Map *map = block->getParent();
+       fillBlockData(v3s16(0,0,0), block->getData());
 
-               for(u16 i=0; i<26; i++)
-               {
-                       const v3s16 &dir = g_26dirs[i];
-                       v3s16 bp = m_blockpos + dir;
-                       MapBlock *b = map->getBlockNoCreateNoEx(bp);
-                       if(b)
-                               b->copyTo(m_vmanip);
-               }
+       // Get map for reading neigbhor blocks
+       Map *map = block->getParent();
+
+       for (u16 i=0; i<26; i++) {
+               const v3s16 &dir = g_26dirs[i];
+               v3s16 bp = m_blockpos + dir;
+               MapBlock *b = map->getBlockNoCreateNoEx(bp);
+               if(b)
+                       fillBlockData(dir, b->getData());
        }
 }
 
@@ -855,8 +849,9 @@ static void updateFastFaceRow(
                        makes_face, p_corrected, face_dir_corrected,
                        lights, tile);
 
-       for(u16 j=0; j<MAP_BLOCKSIZE; j++)
-       {
+       // Unroll this variable which has a significant build cost
+       TileSpec next_tile;
+       for (u16 j = 0; j < MAP_BLOCKSIZE; j++) {
                // If tiling can be done, this is set to false in the next step
                bool next_is_different = true;
 
@@ -866,12 +861,11 @@ static void updateFastFaceRow(
                v3s16 next_p_corrected;
                v3s16 next_face_dir_corrected;
                u16 next_lights[4] = {0,0,0,0};
-               TileSpec next_tile;
+
 
                // If at last position, there is nothing to compare to and
                // the face must be drawn anyway
-               if(j != MAP_BLOCKSIZE - 1)
-               {
+               if (j != MAP_BLOCKSIZE - 1) {
                        p_next = p + translate_dir;
 
                        getTileInfo(data, p_next, face_dir,
@@ -879,7 +873,7 @@ static void updateFastFaceRow(
                                        next_face_dir_corrected, next_lights,
                                        next_tile);
 
-                       if(next_makes_face == makes_face
+                       if (next_makes_face == makes_face
                                        && next_p_corrected == p_corrected + translate_dir
                                        && next_face_dir_corrected == face_dir_corrected
                                        && next_lights[0] == lights[0]
@@ -894,38 +888,14 @@ static void updateFastFaceRow(
                                        && tile.emissive_light == next_tile.emissive_light) {
                                next_is_different = false;
                                continuous_tiles_count++;
-                       } else {
-                               /*if(makes_face){
-                                       g_profiler->add("Meshgen: diff: next_makes_face != makes_face",
-                                                       next_makes_face != makes_face ? 1 : 0);
-                                       g_profiler->add("Meshgen: diff: n_p_corr != p_corr + t_dir",
-                                                       (next_p_corrected != p_corrected + translate_dir) ? 1 : 0);
-                                       g_profiler->add("Meshgen: diff: next_f_dir_corr != f_dir_corr",
-                                                       next_face_dir_corrected != face_dir_corrected ? 1 : 0);
-                                       g_profiler->add("Meshgen: diff: next_lights[] != lights[]",
-                                                       (next_lights[0] != lights[0] ||
-                                                       next_lights[0] != lights[0] ||
-                                                       next_lights[0] != lights[0] ||
-                                                       next_lights[0] != lights[0]) ? 1 : 0);
-                                       g_profiler->add("Meshgen: diff: !(next_tile == tile)",
-                                                       !(next_tile == tile) ? 1 : 0);
-                               }*/
                        }
-                       /*g_profiler->add("Meshgen: Total faces checked", 1);
-                       if(makes_face)
-                               g_profiler->add("Meshgen: Total makes_face checked", 1);*/
-               } else {
-                       /*if(makes_face)
-                               g_profiler->add("Meshgen: diff: last position", 1);*/
                }
 
-               if(next_is_different)
-               {
+               if (next_is_different) {
                        /*
                                Create a face if there should be one
                        */
-                       if(makes_face)
-                       {
+                       if (makes_face) {
                                // Floating point conversion of the position vector
                                v3f pf(p_corrected.X, p_corrected.Y, p_corrected.Z);
                                // Center point of face (kind of)
@@ -957,11 +927,9 @@ static void updateFastFaceRow(
                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;
+               std::memcpy(lights, next_lights, ARRLEN(lights) * sizeof(u16));
+               if (next_is_different)
+                       tile = next_tile;
                p = p_next;
        }
 }
@@ -1108,7 +1076,10 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
                - whatever
        */
 
-       mapblock_mesh_generate_special(data, collector);
+       {
+               MapblockMeshGenerator generator(data, &collector);
+               generator.generate();
+       }
 
        /*
                Convert MeshCollector to SMesh