better grass generation (integration to sunlight propagation algorithms)
authorPerttu Ahola <celeron55@gmail.com>
Sun, 26 Dec 2010 12:34:34 +0000 (14:34 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Sun, 26 Dec 2010 12:34:34 +0000 (14:34 +0200)
src/map.cpp
src/mapblock.cpp
src/mapblock.h

index 1bd4f299f05f6eb75884641e30170151a930a825..93c4d50529dca1059cbd9dd5566d9415aa5c9302 100644 (file)
@@ -570,6 +570,8 @@ v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
        Starting point gets sunlight.
 
        Returns the lowest y value of where the sunlight went.
+
+       Mud is turned into grass in where the sunlight stops.
 */
 s16 Map::propagateSunlight(v3s16 start,
                core::map<v3s16, MapBlock*> & modified_blocks)
@@ -599,7 +601,17 @@ s16 Map::propagateSunlight(v3s16 start,
 
                        modified_blocks.insert(blockpos, block);
                }
-               else{
+               else
+               {
+                       // Turn mud into grass
+                       if(n.d == CONTENT_MUD)
+                       {
+                               n.d = CONTENT_GRASS;
+                               block->setNode(relpos, n);
+                               modified_blocks.insert(blockpos, block);
+                       }
+
+                       // Sunlight goes no further
                        break;
                }
        }
@@ -1912,10 +1924,6 @@ continue_generating:
                }
        }
        
-       // This is the basic material of what the visible flat ground
-       // will consist of
-       u8 material = CONTENT_GRASS;
-
        u8 water_material = CONTENT_WATER;
        if(g_settings.getBool("endless_water"))
                water_material = CONTENT_OCEAN;
@@ -1981,7 +1989,66 @@ continue_generating:
                                Calculate material
                        */
 
-                       if(real_y <= surface_y - surface_depth)
+                       // If node is over heightmap y, it's air or water
+                       if(real_y > surface_y)
+                       {
+                               // If under water level, it's water
+                               if(real_y < WATER_LEVEL)
+                               {
+                                       n.d = water_material;
+                                       n.setLight(LIGHTBANK_DAY,
+                                                       diminish_light(LIGHT_SUN, WATER_LEVEL-real_y+1));
+                               }
+                               // else air
+                               else
+                                       n.d = CONTENT_AIR;
+                       }
+                       // Else it's ground or dungeons (air)
+                       else
+                       {
+                               // Create dungeons
+                               if(underground_emptiness[
+                                               ued*ued*(z0*ued/MAP_BLOCKSIZE)
+                                               +ued*(y0*ued/MAP_BLOCKSIZE)
+                                               +(x0*ued/MAP_BLOCKSIZE)])
+                               {
+                                       n.d = CONTENT_AIR;
+                               }
+                               else
+                               {
+                                       // If it's surface_depth under ground, it's stone
+                                       if(real_y <= surface_y - surface_depth)
+                                       {
+                                               n.d = CONTENT_STONE;
+                                       }
+                                       else
+                                       {
+                                               // It is mud if it is under the first ground
+                                               // level or under water
+                                               if(real_y < WATER_LEVEL || real_y <= surface_y - 1)
+                                               {
+                                                       n.d = CONTENT_MUD;
+                                               }
+                                               else
+                                               {
+                                                       n.d = CONTENT_GRASS;
+                                               }
+
+                                               //n.d = CONTENT_MUD;
+                                               
+                                               /*// If under water level, it's mud
+                                               if(real_y < WATER_LEVEL)
+                                                       n.d = CONTENT_MUD;
+                                               // Only the topmost node is grass
+                                               else if(real_y <= surface_y - 1)
+                                                       n.d = CONTENT_MUD;
+                                               else
+                                                       n.d = CONTENT_GRASS;*/
+                                       }
+                               }
+                       }
+#if 0
+                       else if(real_y <= surface_y - surface_depth)
                        {
                                // Create dungeons
                                if(underground_emptiness[
@@ -2009,19 +2076,7 @@ continue_generating:
                                else
                                        n.d = material;
                        }
-                       // If node is over heightmap y
-                       else{
-                               // If under water level, it's water
-                               if(real_y < WATER_LEVEL)
-                               {
-                                       n.d = water_material;
-                                       n.setLight(LIGHTBANK_DAY,
-                                                       diminish_light(LIGHT_SUN, WATER_LEVEL-real_y+1));
-                               }
-                               // else air
-                               else
-                                       n.d = CONTENT_AIR;
-                       }
+#endif
                        block->setNode(v3s16(x0,y0,z0), n);
                }
        }
index 60efa2fcfa1f015728fb3966d2df9d413b0d622b..20287732253d2a4f9fb17426187338ace1c78fc6 100644 (file)
@@ -860,7 +860,9 @@ void MapBlock::updateMesh(u32 daynight_ratio)
        is_underground is set.
 
        At the moment, all sunlighted nodes are added to light_sources.
-       TODO: This could be optimized.
+       - SUGG: This could be optimized
+
+       Turns sunglighted mud into grass.
 */
 bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
 {
@@ -880,10 +882,6 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
                                MapNode n = getNodeParent(v3s16(x, MAP_BLOCKSIZE, z));
                                if(n.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
                                {
-                                       /*if(is_underground)
-                                       {
-                                               no_sunlight = true;
-                                       }*/
                                        no_sunlight = true;
                                }
                        }
@@ -891,15 +889,14 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
                        {
                                no_top_block = true;
                                
-                               // TODO: This makes over-ground roofed places sunlighted
+                               // NOTE: This makes over-ground roofed places sunlighted
                                // Assume sunlight, unless is_underground==true
                                if(is_underground)
                                {
                                        no_sunlight = true;
                                }
                                
-                               // TODO: There has to be some way to allow this behaviour
-                               // As of now, it just makes everything dark.
+                               // NOTE: As of now, it just would make everything dark.
                                // No sunlight here
                                //no_sunlight = true;
                        }
@@ -928,7 +925,15 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
 
                                                light_sources.insert(pos_relative + pos, true);
                                        }
-                                       else{
+                                       else
+                                       {
+                                               // Turn mud into grass
+                                               if(n.d == CONTENT_MUD)
+                                               {
+                                                       n.d = CONTENT_GRASS;
+                                               }
+
+                                               // Sunlight goes no further
                                                break;
                                        }
                                }
index 586c10228f1f36e0880bc49c297b776b899be6d9..743dad9276fdd647f6bf82ea10bce6b0f7b9a462 100644 (file)
@@ -310,7 +310,8 @@ public:
        // Updates all DAYNIGHT_CACHE_COUNT meshes
        void updateMeshes(s32 first_i=0);*/
 #endif // !SERVER
-
+       
+       // See comments in mapblock.cpp
        bool propagateSunlight(core::map<v3s16, bool> & light_sources);
        
        // Copies data to VoxelManipulator to getPosRelative()