diff options
-rw-r--r-- | src/light.cpp | 64 | ||||
-rw-r--r-- | src/map.cpp | 146 | ||||
-rw-r--r-- | src/noise.cpp | 105 | ||||
-rw-r--r-- | src/noise.h | 24 | ||||
-rw-r--r-- | src/server.cpp | 4 |
5 files changed, 314 insertions, 29 deletions
diff --git a/src/light.cpp b/src/light.cpp index 5dade2e16..f214d6ea0 100644 --- a/src/light.cpp +++ b/src/light.cpp @@ -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 diff --git a/src/map.cpp b/src/map.cpp index 4c0047a10..dc77680a9 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -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,10 +2231,41 @@ 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++) @@ -2242,6 +2273,63 @@ void makeChunk(ChunkMakeData *data) // 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++) + { + // Node position + v2s16 p2d = data->sectorpos_bigbase*MAP_BLOCKSIZE + v2s16(x,z); + /* Skip of already generated */ @@ -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. diff --git a/src/noise.cpp b/src/noise.cpp index 00772455a..6362f5b2c 100644 --- a/src/noise.cpp +++ b/src/noise.cpp @@ -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); +} + diff --git a/src/noise.h b/src/noise.h index 88b995b1e..ba26519f2 100644 --- a/src/noise.h +++ b/src/noise.h @@ -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 diff --git a/src/server.cpp b/src/server.cpp index c9c115abb..322af2012 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -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; |