tested out and commented out some new stuff for the terrain generator, to be used...
authorPerttu Ahola <celeron55@gmail.com>
Tue, 26 Apr 2011 12:38:42 +0000 (15:38 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Tue, 26 Apr 2011 12:38:42 +0000 (15:38 +0300)
src/light.cpp
src/map.cpp
src/noise.cpp
src/noise.h
src/server.cpp

index 5dade2e16e9177f793ed12b6b3f0ff66334e6d3c..f214d6ea06615f1c5512600e66ca80e395a99b35 100644 (file)
@@ -19,27 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "light.h"
 
-// This is reasonable with classic lighting with a light source
-/*u8 light_decode_table[LIGHT_MAX+1] = 
-{
-2,
-3,
-4,
-6,
-9,
-13,
-18,
-25,
-32,
-35,
-45,
-57,
-69,
-79,
-255
-};*/
-
-
+#if 1
 // This is good
 // a_n+1 = a_n * 0.786
 // Length of LIGHT_MAX+1 means LIGHT_MAX is the last value.
@@ -62,6 +42,48 @@ u8 light_decode_table[LIGHT_MAX+1] =
 200,
 255,
 };
+#else
+// Use for debugging in dark
+u8 light_decode_table[LIGHT_MAX+1] = 
+{
+58,
+64,
+72,
+80,
+88,
+98,
+109,
+121,
+135,
+150,
+167,
+185,
+206,
+229,
+255,
+};
+#endif
+
+// This is reasonable with classic lighting with a light source
+/*u8 light_decode_table[LIGHT_MAX+1] = 
+{
+2,
+3,
+4,
+6,
+9,
+13,
+18,
+25,
+32,
+35,
+45,
+57,
+69,
+79,
+255
+};*/
+
 
 // As in minecraft, a_n+1 = a_n * 0.8
 // NOTE: This doesn't really work that well because this defines
index 4c0047a1037ab02cdf25410e36e13a333f2ad744..dc77680a9795bb9e188421741405814e4e15f767 100644 (file)
@@ -2068,7 +2068,7 @@ double base_rock_level_2d(u64 seed, v2s16 p)
 {
        // The base ground level
        double base = (double)WATER_LEVEL - (double)AVERAGE_MUD_AMOUNT
-                       + 25. * noise2d_perlin(
+                       + 20. * noise2d_perlin(
                        0.5+(float)p.X/500., 0.5+(float)p.Y/500.,
                        (seed>>32)+654879876, 6, 0.6);
        
@@ -2080,7 +2080,7 @@ double base_rock_level_2d(u64 seed, v2s16 p)
                base = base2;*/
 #if 1
        // Higher ground level
-       double higher = (double)WATER_LEVEL + 25. + 45. * noise2d_perlin(
+       double higher = (double)WATER_LEVEL + 25. + 35. * noise2d_perlin(
                        0.5+(float)p.X/250., 0.5+(float)p.Y/250.,
                        seed+85039, 5, 0.69);
        //higher = 30; // For debugging
@@ -2231,11 +2231,99 @@ void makeChunk(ChunkMakeData *data)
        /*
                Generate general ground level to full area
        */
-       
        {
        // 22ms @cs=8
-       //TimeTaker timer1("ground level");
+       TimeTaker timer1("Generating ground level");
+
+#if 0
+       NoiseBuffer noisebuf1;
+       NoiseBuffer noisebuf2;
+       {
+               v3f minpos_f(
+                       data->sectorpos_bigbase.X*MAP_BLOCKSIZE,
+                       y_nodes_min,
+                       data->sectorpos_bigbase.Y*MAP_BLOCKSIZE
+               );
+               v3f maxpos_f = minpos_f + v3f(
+                       data->sectorpos_bigbase_size*MAP_BLOCKSIZE,
+                       y_nodes_max-y_nodes_min,
+                       data->sectorpos_bigbase_size*MAP_BLOCKSIZE
+               );
+               v3f samplelength_f = v3f(4.0, 4.0, 4.0);
+
+               TimeTaker timer("noisebuf.create");
+               
+               /*noisebuf.create(data->seed+25104, 6, 0.60, 200.0,
+                               minpos_f.X, minpos_f.Y, minpos_f.Z,
+                               maxpos_f.X, maxpos_f.Y, maxpos_f.Z,
+                               samplelength_f.X, samplelength_f.Y, samplelength_f.Z);*/
+               noisebuf1.create(data->seed+25104, 3, 0.60, 25.0,
+                               minpos_f.X, minpos_f.Y, minpos_f.Z,
+                               maxpos_f.X, maxpos_f.Y, maxpos_f.Z,
+                               samplelength_f.X, samplelength_f.Y, samplelength_f.Z);
+               noisebuf2.create(data->seed+25105, 4, 0.50, 200.0,
+                               minpos_f.X, minpos_f.Y, minpos_f.Z,
+                               maxpos_f.X, maxpos_f.Y, maxpos_f.Z,
+                               samplelength_f.X, samplelength_f.Y, samplelength_f.Z);
+       }
 
+       for(s16 x=0; x<data->sectorpos_bigbase_size*MAP_BLOCKSIZE; x++)
+       for(s16 z=0; z<data->sectorpos_bigbase_size*MAP_BLOCKSIZE; z++)
+       {
+               // Node position
+               v2s16 p2d = data->sectorpos_bigbase*MAP_BLOCKSIZE + v2s16(x,z);
+               
+               // Ground height at this point
+               float surface_y_f = 0.0;
+
+               // Use perlin noise for ground height
+               surface_y_f = base_rock_level_2d(data->seed, p2d);
+               //surface_y_f = base_rock_level_2d(data->seed, p2d);
+               
+               // Convert to integer
+               s16 surface_y = (s16)surface_y_f;
+               
+               // Log it
+               if(surface_y > stone_surface_max_y)
+                       stone_surface_max_y = surface_y;
+
+               /*
+                       Fill ground with stone
+               */
+               {
+                       // Use fast index incrementing
+                       v3s16 em = data->vmanip.m_area.getExtent();
+                       u32 i = data->vmanip.m_area.index(v3s16(p2d.X, y_nodes_min, p2d.Y));
+                       for(s16 y=y_nodes_min; y<=y_nodes_max; y++)
+                       {
+                               // Skip if already generated.
+                               // This is done here because there might be a cave at
+                               // any point in ground, which could look like it
+                               // wasn't generated.
+                               if(data->vmanip.m_data[i].d != CONTENT_AIR)
+                                       break;
+
+                               /*s16 noiseval = 50.0 * noise3d_perlin(
+                                               0.5+(float)p2d.X/100.0,
+                                               0.5+(float)y/100.0,
+                                               0.5+(float)p2d.Y/100.0,
+                                               data->seed+123, 5, 0.5);*/
+                               //double noiseval = 64.0 * noisebuf1.get(p2d.X, y, p2d.Y);
+                               double noiseval = 30.0 * noisebuf1.get(p2d.X, y, p2d.Y);
+                               noiseval *= MYMAX(0, -0.2 + noisebuf2.get(p2d.X, y, p2d.Y));
+                               
+                               if(y < surface_y + noiseval)
+                               //if(noiseval > 0)
+                               //if(noiseval > y)
+                                       data->vmanip.m_data[i].d = CONTENT_STONE;
+
+                               data->vmanip.m_area.add_y(em, i, 1);
+                       }
+               }
+       }
+#endif
+       
+#if 1
        for(s16 x=0; x<data->sectorpos_bigbase_size*MAP_BLOCKSIZE; x++)
        for(s16 z=0; z<data->sectorpos_bigbase_size*MAP_BLOCKSIZE; z++)
        {
@@ -2293,6 +2381,7 @@ void makeChunk(ChunkMakeData *data)
                        }
                }
        }
+#endif
        
        }//timer1
 
@@ -2320,6 +2409,7 @@ void makeChunk(ChunkMakeData *data)
                BEGINNING OF AGING LOOP
        ******************************/
 
+#if 1
        {
        // 24ms @cs=8
        //TimeTaker timer1("caves");
@@ -2558,6 +2648,9 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
+
+#if 1
        {
        // 46ms @cs=8
        //TimeTaker timer1("ore veins");
@@ -2691,9 +2784,12 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
+
+#if 1
        {
        // 15ms @cs=8
-       //TimeTaker timer1("add mud");
+       TimeTaker timer1("add mud");
 
        /*
                Add mud to the central chunk
@@ -2706,7 +2802,7 @@ void makeChunk(ChunkMakeData *data)
                v2s16 p2d = data->sectorpos_base*MAP_BLOCKSIZE + v2s16(x,z);
                
                // Randomize mud amount
-               s16 mud_add_amount = (s16)(2.5 + 2.0 * noise2d_perlin(
+               s16 mud_add_amount = (s16)(2.5 + 1.5 * noise2d_perlin(
                                0.5+(float)p2d.X/200, 0.5+(float)p2d.Y/200,
                                data->seed+1, 3, 0.55));
 
@@ -2749,6 +2845,9 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
+
+#if 1
        {
        // 340ms @cs=8
        TimeTaker timer1("flow mud");
@@ -2903,9 +3002,12 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
+
+#if 1
        {
        // 50ms @cs=8
-       //TimeTaker timer1("add water");
+       TimeTaker timer1("add water");
 
        /*
                Add water to the central chunk (and a bit more)
@@ -2978,12 +3080,14 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
        
        } // Aging loop
        /***********************
                END OF AGING LOOP
        ************************/
 
+#if 1
        {
        //TimeTaker timer1("convert mud to sand");
 
@@ -3048,6 +3152,9 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
+
+#if 1
        {
        // 1ms @cs=8
        //TimeTaker timer1("generate trees");
@@ -3126,7 +3233,9 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
 
+#if 1
        {
        // 19ms @cs=8
        //TimeTaker timer1("grow grass");
@@ -3180,6 +3289,7 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
 
        /*
                Initial lighting (sunlight)
@@ -3191,6 +3301,7 @@ void makeChunk(ChunkMakeData *data)
        // 750ms @cs=8, can't optimize more
        TimeTaker timer1("initial lighting");
 
+       // NOTE: This is no used... umm... for some reason!
 #if 0
        /*
                Go through the edges and add all nodes that have light to light_sources
@@ -3913,6 +4024,25 @@ MapBlock * ServerMap::generateBlock(
                block->unDummify();
        }
        
+#if 1
+       /*
+               Generate a completely empty block
+       */
+       for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
+       for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
+       {
+               for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++)
+               {
+                       MapNode n;
+                       n.d = CONTENT_AIR;
+                       block->setNode(v3s16(x0,y0,z0), n);
+               }
+       }
+#else
+       /*
+               Generate a proper block
+       */
+       
        u8 water_material = CONTENT_WATERSOURCE;
        
        s32 lowest_ground_y = 32767;
@@ -4447,6 +4577,8 @@ continue_generating:
                        }
                }
        }
+
+#endif // end of proper block generation
        
        /*
                Add block to sector.
index 00772455a6b4f691fcf448517bd9959ef68c9c4b..6362f5b2cf3863c8a670c200a8fc3456d3d52f48 100644 (file)
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <math.h>
 #include "noise.h"
 #include <iostream>
+#include "debug.h"
 
 #define NOISE_MAGIC_X 1619
 #define NOISE_MAGIC_Y 31337
@@ -221,3 +222,107 @@ double noise3d_perlin_abs(double x, double y, double z, int seed,
        return a;
 }
 
+/*
+       NoiseBuffer
+*/
+
+NoiseBuffer::NoiseBuffer():
+       m_data(NULL)
+{
+}
+
+NoiseBuffer::~NoiseBuffer()
+{
+       clear();
+}
+
+void NoiseBuffer::clear()
+{
+       if(m_data)
+               delete[] m_data;
+       m_data = NULL;
+       m_size_x = 0;
+       m_size_y = 0;
+       m_size_z = 0;
+}
+
+void NoiseBuffer::create(int seed, int octaves, double persistence,
+               double pos_scale,
+               double first_x, double first_y, double first_z,
+               double last_x, double last_y, double last_z,
+               double samplelength_x, double samplelength_y, double samplelength_z)
+{
+       clear();
+       
+       m_start_x = first_x - samplelength_x;
+       m_start_y = first_y - samplelength_y;
+       m_start_z = first_z - samplelength_z;
+       m_samplelength_x = samplelength_x;
+       m_samplelength_y = samplelength_y;
+       m_samplelength_z = samplelength_z;
+
+       m_size_x = (last_x - m_start_x)/samplelength_x + 2;
+       m_size_y = (last_y - m_start_y)/samplelength_y + 2;
+       m_size_z = (last_z - m_start_z)/samplelength_z + 2;
+
+       /*dstream<<"m_size_x="<<m_size_x<<", m_size_y="<<m_size_y
+                       <<", m_size_z="<<m_size_z<<std::endl;*/
+       
+       m_data = new double[m_size_x*m_size_y*m_size_z];
+
+       for(int x=0; x<m_size_x; x++)
+       for(int y=0; y<m_size_y; y++)
+       for(int z=0; z<m_size_z; z++)
+       {
+               double xd = (m_start_x + (double)x*m_samplelength_x)/pos_scale;
+               double yd = (m_start_y + (double)y*m_samplelength_y)/pos_scale;
+               double zd = (m_start_z + (double)z*m_samplelength_z)/pos_scale;
+               intSet(x,y,z, noise3d_perlin(xd,yd,zd,seed,octaves,persistence));
+       }
+}
+
+void NoiseBuffer::intSet(int x, int y, int z, double d)
+{
+       int i = m_size_x*m_size_y*z + m_size_x*y + x;
+       assert(i >= 0);
+       assert(i < m_size_x*m_size_y*m_size_z);
+       m_data[i] = d;
+}
+
+double NoiseBuffer::intGet(int x, int y, int z)
+{
+       int i = m_size_x*m_size_y*z + m_size_x*y + x;
+       assert(i >= 0);
+       assert(i < m_size_x*m_size_y*m_size_z);
+       return m_data[i];
+}
+
+double NoiseBuffer::get(double x, double y, double z)
+{
+       x -= m_start_x;
+       y -= m_start_y;
+       z -= m_start_z;
+       x /= m_samplelength_x;
+       y /= m_samplelength_y;
+       z /= m_samplelength_z;
+       // Calculate the integer coordinates
+       int x0 = (x > 0.0 ? (int)x : (int)x - 1);
+       int y0 = (y > 0.0 ? (int)y : (int)y - 1);
+       int z0 = (z > 0.0 ? (int)z : (int)z - 1);
+       // Calculate the remaining part of the coordinates
+       double xl = x - (double)x0;
+       double yl = y - (double)y0;
+       double zl = z - (double)z0;
+       // Get values for corners of cube
+       double v000 = intGet(x0,   y0,   z0);
+       double v100 = intGet(x0+1, y0,   z0);
+       double v010 = intGet(x0,   y0+1, z0);
+       double v110 = intGet(x0+1, y0+1, z0);
+       double v001 = intGet(x0,   y0,   z0+1);
+       double v101 = intGet(x0+1, y0,   z0+1);
+       double v011 = intGet(x0,   y0+1, z0+1);
+       double v111 = intGet(x0+1, y0+1, z0+1);
+       // Interpolate
+       return triLinearInterpolation(v000,v100,v010,v110,v001,v101,v011,v111,xl,yl,zl);
+}
+
index 88b995b1e6484098e43b7bfb08d395b540513677..ba26519f24bc027d71a570f1bba7fd4fd5d59f05 100644 (file)
@@ -41,5 +41,29 @@ double noise3d_perlin(double x, double y, double z, int seed,
 double noise3d_perlin_abs(double x, double y, double z, int seed,
                int octaves, double persistence);
 
+class NoiseBuffer
+{
+public:
+       NoiseBuffer();
+       ~NoiseBuffer();
+       
+       void clear();
+       void create(int seed, int octaves, double persistence,
+                       double pos_scale,
+                       double first_x, double first_y, double first_z,
+                       double last_x, double last_y, double last_z,
+                       double samplelength_x, double samplelength_y, double samplelength_z);
+
+       void intSet(int x, int y, int z, double d);
+       double intGet(int x, int y, int z);
+       double get(double x, double y, double z);
+
+private:
+       double *m_data;
+       double m_start_x, m_start_y, m_start_z;
+       double m_samplelength_x, m_samplelength_y, m_samplelength_z;
+       int m_size_x, m_size_y, m_size_z;
+};
+
 #endif
 
index c9c115abb4d8a6f0fb2634cd3336319bb6934ed7..322af2012ab9dca73dd2b8eee355a52cb6b393ed 100644 (file)
@@ -565,7 +565,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                                        Block is not near ground level if night-time mesh
                                        doesn't differ from day-time mesh.
                                */
-                               if(d >= 3)
+                               if(d > 3)
                                {
                                        if(block->dayNightDiffed() == false)
                                                continue;
@@ -4035,6 +4035,8 @@ void setCreativeInventory(Player *player)
 
 v3f findSpawnPos(ServerMap &map)
 {
+       //return v3f(50,50,50)*BS;
+       
        v2s16 nodepos;
        s16 groundheight = 0;