From 3891bc43e084b9bd1c345638dfbbffa9d71658c9 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Mon, 17 Jan 2011 02:40:53 +0200 Subject: [PATCH] fine-tuning of map generator and server and stuff. --- src/defaultsettings.cpp | 5 +- src/main.cpp | 5 +- src/map.cpp | 241 +++++++++++++++++++++++++--------------- src/map.h | 2 +- src/materials.cpp | 4 +- src/player.cpp | 21 +++- src/server.cpp | 55 +++++++-- src/server.h | 14 ++- src/test.cpp | 2 +- src/utility.cpp | 55 +++++++++ src/utility.h | 7 ++ 11 files changed, 298 insertions(+), 113 deletions(-) diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index dd4a7b2ef..d3e193f9e 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -61,10 +61,11 @@ void set_default_settings() g_settings.setDefault("active_object_range", "2"); g_settings.setDefault("max_simultaneous_block_sends_per_client", "1"); g_settings.setDefault("max_simultaneous_block_sends_server_total", "4"); + g_settings.setDefault("water_moves", "true"); g_settings.setDefault("disable_water_climb", "true"); g_settings.setDefault("endless_water", "true"); - g_settings.setDefault("max_block_send_distance", "5"); - g_settings.setDefault("max_block_generate_distance", "5"); + g_settings.setDefault("max_block_send_distance", "6"); + g_settings.setDefault("max_block_generate_distance", "6"); g_settings.setDefault("time_send_interval", "20"); g_settings.setDefault("time_speed", "96"); g_settings.setDefault("server_unload_unused_sectors_timeout", "60"); diff --git a/src/main.cpp b/src/main.cpp index f36f17a1d..51d94aba4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -168,6 +168,8 @@ TODO: Check what goes wrong with caching map to disk (Kray) TODO: When server sees that client is removing an inexistent block or adding a block to an existent position, resend the MapBlock. +TODO: Generate map from the area the client is looking at + Objects: TODO: Better handling of objects and mobs @@ -1409,10 +1411,11 @@ int main(int argc, char *argv[]) video::E_DRIVER_TYPE driverType; #ifdef _WIN32 - //driverType = video::EDT_DIRECT3D9; // Doesn't seem to work + //driverType = video::EDT_DIRECT3D9; driverType = video::EDT_OPENGL; #else driverType = video::EDT_OPENGL; + //driverType = video::EDT_BURNINGSVIDEO; #endif // create device and exit if creation failed diff --git a/src/map.cpp b/src/map.cpp index c290f69e9..d15ac0a7b 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1317,17 +1317,26 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp): */ { + dstream<<"Generating map point attribute lists"<addPoint(p, Attribute(plants_amount)); + } + + for(u32 i=0; i<1000; i++) + { + /*u32 lim = MAP_GENERATION_LIMIT; + if(i < 400) + lim = 2000;*/ + + u32 lim = 500 + MAP_GENERATION_LIMIT * i / 1000; + + v3s16 p( + -lim + myrand()%(lim*2), + 0, + -lim + myrand()%(lim*2) + ); + float caves_amount = 0; if(myrand()%5 == 0) { @@ -1370,20 +1397,21 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp): caves_amount = 0.05; } - list_plants_amount->addPoint(p, Attribute(plants_amount)); list_caves_amount->addPoint(p, Attribute(caves_amount)); } -#if 1 - for(u32 i=0; i<3000; i++) + + for(u32 i=0; i<5000; i++) { - u32 lim = MAP_GENERATION_LIMIT; - if(i < 100) - lim = 1000; + /*u32 lim = MAP_GENERATION_LIMIT; + if(i < 400) + lim = 2000;*/ + + u32 lim = 1000 + MAP_GENERATION_LIMIT * i / 5000; v3s16 p( - -lim + myrand()%(lim*2), + -lim + (myrand()%(lim*2)), 0, - -lim + myrand()%(lim*2) + -lim + (myrand()%(lim*2)) ); /*s32 bh_i = (myrand()%200) - 50; @@ -1404,13 +1432,13 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp): if(myrand()%4 == 0) { baseheight = 100; - randmax = 100; + randmax = 50; randfactor = 0.63; } - else if(myrand()%5 == 0) + else if(myrand()%6 == 0) { baseheight = 200; - randmax = 200; + randmax = 100; randfactor = 0.66; } else if(myrand()%4 == 0) @@ -1423,7 +1451,7 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp): { baseheight = 0; randmax = 30; - randfactor = 0.60; + randfactor = 0.63; } else { @@ -1436,68 +1464,16 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp): list_randmax->addPoint(p, Attribute(randmax)); list_randfactor->addPoint(p, Attribute(randfactor)); } -#endif /*list_baseheight->addPoint(v3s16(0,0,0), Attribute(5)); list_randmax->addPoint(v3s16(0,0,0), Attribute(20)); list_randfactor->addPoint(v3s16(0,0,0), Attribute(0.6));*/ - } - -#if 0 - { - PointAttributeList *palist = m_padb.getList("hm_baseheight"); - - { - v3s16 p(0,0,0); - Attribute attr; - attr.set("5"); - palist->addPoint(p, attr); - } - /*{ - v3s16 p(-50,-50,0); - Attribute attr; - attr.set("-10"); - palist->addPoint(p, attr); - } - - { - v3s16 p(50,0,50); - Attribute attr; - attr.set("200"); - palist->addPoint(p, attr); - }*/ + // Easy spawn point + /*list_baseheight->addPoint(v3s16(0,0,0), Attribute(0)); + list_randmax->addPoint(v3s16(0,0,0), Attribute(10)); + list_randfactor->addPoint(v3s16(0,0,0), Attribute(0.65));*/ } -#endif -#if 0 - { - PointAttributeList *palist = m_padb.getList("plants_amount"); - - // Back - { - v3s16 p(0,0,-100); - Attribute attr; - attr.set("0"); - palist->addPoint(p, attr); - } - - // Front right - { - v3s16 p(100,0,100); - Attribute attr; - attr.set("2.0"); - palist->addPoint(p, attr); - } - - // Front left - { - v3s16 p(-100,0,100); - Attribute attr; - attr.set("0.2"); - palist->addPoint(p, attr); - } - } -#endif /* Try to load map; if not found, create a new one. @@ -1704,6 +1680,8 @@ MapSector * ServerMap::emergeSector(v2s16 p2d) Get local attributes */ + //dstream<<"emergeSector(): Reading point attribute lists"<getInterpolatedFloat(nodepos2d); + //dstream<<"emergeSector(): done."< 0.001) { if(myrand()%(s32)(200.0 / m_params.ravines_amount) == 0) { @@ -2061,13 +2041,32 @@ MapBlock * ServerMap::emergeBlock( bool some_part_underground = block_y * MAP_BLOCKSIZE <= highest_ground_y; + bool mostly_underwater_surface = false; + if(highest_ground_y < WATER_LEVEL + && some_part_underground && !completely_underground) + mostly_underwater_surface = true; + /* Get local attributes */ + + //dstream<<"emergeBlock(): Getting local attributes"<getInterpolatedFloat(nodepos2d); + { + /* + NOTE: BEWARE: Too big amount of attribute points slows verything + down by a lot. + 1 interpolation from 5000 points takes 2-3ms. + */ + //TimeTaker timer("emergeBlock() local attribute retrieval"); + v2s16 nodepos2d = p2d * MAP_BLOCKSIZE; + PointAttributeList *list_caves_amount = m_padb.getList("caves_amount"); + caves_amount = list_caves_amount->getInterpolatedFloat(nodepos2d); + } + + //dstream<<"emergeBlock(): Done"<getPos()] = block; @@ -2336,9 +2350,9 @@ continue_generating: /* Add meseblocks */ - for(s16 i=0; i< underground_level/4 + 1; i++) + for(s16 i=0; igetPos(), block); } - + + /* + Debug information + */ + if(0) + { + dstream + <<"lighting_invalidated_blocks.size()" + <<", has_dungeons" + <<", completely_ug" + <<", some_part_ug" + <<" "<getPos(), camera_position, + camera_direction, range) == false) + { + continue; + } + +#if 0 v3s16 blockpos_nodes = block->getPosRelative(); // Block center position @@ -3434,8 +3479,6 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) { // If block is far away, don't draw it if(d > m_control.wanted_range * BS) - // This is nicer when fog is used - //if((dforward+d)/2 > m_control.wanted_range * BS) continue; } @@ -3460,7 +3503,23 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) if(cosangle < cos(FOV_ANGLE/2. * 4./3.)) continue; } +#endif + + v3s16 blockpos_nodes = block->getPosRelative(); + // Block center position + v3f blockpos( + ((float)blockpos_nodes.X + MAP_BLOCKSIZE/2) * BS, + ((float)blockpos_nodes.Y + MAP_BLOCKSIZE/2) * BS, + ((float)blockpos_nodes.Z + MAP_BLOCKSIZE/2) * BS + ); + + // Block position relative to camera + v3f blockpos_relative = blockpos - camera_position; + + // Total distance + f32 d = blockpos_relative.getLength(); + /* Draw the faces of the block */ diff --git a/src/map.h b/src/map.h index 3385d7c68..d858a9907 100644 --- a/src/map.h +++ b/src/map.h @@ -206,7 +206,7 @@ public: their differing fetch methods. */ virtual MapSector * emergeSector(v2s16 p) = 0; - + // Returns InvalidPositionException if not found MapBlock * getBlockNoCreate(v3s16 p); // Returns NULL if not found diff --git a/src/materials.cpp b/src/materials.cpp index 1c177e9a3..bc39619fc 100644 --- a/src/materials.cpp +++ b/src/materials.cpp @@ -13,9 +13,9 @@ void setStoneLikeDiggingProperties(u8 material, float toughness) DiggingProperties(true, 15.0*toughness, 0)); g_material_properties[material].setDiggingProperties("WPick", - DiggingProperties(true, 1.5*toughness, 65535./20.*toughness)); + DiggingProperties(true, 1.5*toughness, 65535./30.*toughness)); g_material_properties[material].setDiggingProperties("STPick", - DiggingProperties(true, 0.7*toughness, 65535./60.*toughness)); + DiggingProperties(true, 0.7*toughness, 65535./100.*toughness)); /*g_material_properties[material].setDiggingProperties("MesePick", DiggingProperties(true, 0.0*toughness, 65535./20.*toughness));*/ diff --git a/src/player.cpp b/src/player.cpp index 3c06283a0..72e44f0e0 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -46,6 +46,20 @@ Player::~Player() // Y direction is ignored void Player::accelerate(v3f target_speed, f32 max_increase) { + v3f d_wanted = target_speed - m_speed; + d_wanted.Y = 0; + f32 dl_wanted = d_wanted.getLength(); + f32 dl = dl_wanted; + if(dl > max_increase) + dl = max_increase; + + v3f d = d_wanted.normalize() * dl; + + m_speed.X += d.X; + m_speed.Z += d.Z; + //m_speed += d; + +#if 0 // old code if(m_speed.X < target_speed.X - max_increase) m_speed.X += max_increase; else if(m_speed.X > target_speed.X + max_increase) @@ -63,6 +77,7 @@ void Player::accelerate(v3f target_speed, f32 max_increase) m_speed.Z = target_speed.Z; else if(m_speed.Z > target_speed.Z) m_speed.Z = target_speed.Z; +#endif } /* @@ -209,7 +224,7 @@ void LocalPlayer::move(f32 dtime, Map &map) position += m_speed * dtime; // Skip collision detection if player is non-local - if(isLocal() == false) + if(isLocal() == false || HAXMODE) { setPosition(position); return; @@ -286,10 +301,6 @@ void LocalPlayer::move(f32 dtime, Map &map) { // Doing nothing here will block the player from // walking over map borders - - // Go over borders in debug mode - if(HAXMODE) - continue; } core::aabbox3d nodebox = Map::getNodeBox( diff --git a/src/server.cpp b/src/server.cpp index da643339b..3b3dfb657 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -328,6 +328,13 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, v3s16 center_nodepos = floatToInt(playerpos); v3s16 center = getNodeBlockPos(center_nodepos); + + // Camera position and direction + v3f camera_pos = + playerpos + v3f(0, BS+BS/2, 0); + v3f camera_dir = v3f(0,0,1); + camera_dir.rotateYZBy(player->getPitch()); + camera_dir.rotateXZBy(player->getYaw()); /* Get the starting value of the block finder radius. @@ -496,6 +503,15 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, if(abs(p.Y - center.Y) > d_max_gen - d_max_gen / 3) generate = false; } + + /* + Don't draw if not in sight + */ + + if(isBlockInSight(p, camera_pos, camera_dir, 10000*BS) == false) + { + continue; + } /* Don't send already sent blocks @@ -511,6 +527,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, { /* Ignore block if it is not at ground surface + but don't ignore water surface blocks */ v2s16 p2d(p.X*MAP_BLOCKSIZE + MAP_BLOCKSIZE/2, p.Z*MAP_BLOCKSIZE + MAP_BLOCKSIZE/2); @@ -519,7 +536,8 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, if(y > GROUNDHEIGHT_VALID_MINVALUE) { f32 by = p.Y*MAP_BLOCKSIZE + MAP_BLOCKSIZE/2; - if(fabs(by - y) > MAP_BLOCKSIZE + MAP_BLOCKSIZE/3) + if(fabs(by - y) > MAP_BLOCKSIZE + MAP_BLOCKSIZE/3 + && fabs(by - WATER_LEVEL) >= MAP_BLOCKSIZE) continue; } } @@ -839,8 +857,11 @@ void RemoteClient::GotBlock(v3s16 p) if(m_blocks_sending.find(p) != NULL) m_blocks_sending.remove(p); else - dstream<<"RemoteClient::GotBlock(): Didn't find in" - " m_blocks_sending"< GROUNDHEIGHT_VALID_MINVALUE); // Don't go underwater if(groundheight < WATER_LEVEL) + { + //dstream<<"-> Underwater"<emergeBlock(blockpos); // Don't go inside ground try{ - v3s16 footpos(nodepos.X, groundheight+1, nodepos.Y); - v3s16 headpos(nodepos.X, groundheight+2, nodepos.Y); + /*v3s16 footpos(nodepos.X, groundheight+1, nodepos.Y); + v3s16 headpos(nodepos.X, groundheight+2, nodepos.Y);*/ + v3s16 footpos = nodepos3d + v3s16(0,0,0); + v3s16 headpos = nodepos3d + v3s16(0,1,0); if(m_env.getMap().getNode(footpos).d != CONTENT_AIR || m_env.getMap().getNode(headpos).d != CONTENT_AIR) { + dstream<<"-> Inside ground"< Invalid position"<addPoint(v2s16(BS1*2,BS1), Attribute(0)); padb.getList("hm_randmax")->addPoint(v2s16(BS1*2,BS1), Attribute(30)); - padb.getList("hm_randfactor")->addPoint(v2s16(BS1*2,BS1), Attribute(0.9)); + padb.getList("hm_randfactor")->addPoint(v2s16(BS1*2,BS1), Attribute(0.63)); UnlimitedHeightmap hm1(BS1, &padb); diff --git a/src/utility.cpp b/src/utility.cpp index d6ca48153..6f16b7658 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "utility.h" #include "irrlichtwrapper.h" #include "gettime.h" +#include "mapblock.h" TimeTaker::TimeTaker(const char *name, u32 *result) { @@ -328,4 +329,58 @@ lopuks sit otetaan a/b } #endif +/* + blockpos: position of block in block coordinates + camera_pos: position of camera in nodes + camera_dir: an unit vector pointing to camera direction + range: viewing range +*/ +bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range) +{ + v3s16 blockpos_nodes = blockpos_b * MAP_BLOCKSIZE; + + // Block center position + v3f blockpos( + ((float)blockpos_nodes.X + MAP_BLOCKSIZE/2) * BS, + ((float)blockpos_nodes.Y + MAP_BLOCKSIZE/2) * BS, + ((float)blockpos_nodes.Z + MAP_BLOCKSIZE/2) * BS + ); + + // Block position relative to camera + v3f blockpos_relative = blockpos - camera_pos; + + // Distance in camera direction (+=front, -=back) + f32 dforward = blockpos_relative.dotProduct(camera_dir); + + // Total distance + f32 d = blockpos_relative.getLength(); + + // If block is far away, it's not in sight + if(d > range * BS) + return false; + + // Maximum radius of a block + f32 block_max_radius = 0.5*1.44*1.44*MAP_BLOCKSIZE*BS; + + // If block is (nearly) touching the camera, don't + // bother validating further (that is, render it anyway) + if(d > block_max_radius * 1.5) + { + // Cosine of the angle between the camera direction + // and the block direction (camera_dir is an unit vector) + f32 cosangle = dforward / d; + + // Compensate for the size of the block + // (as the block has to be shown even if it's a bit off FOV) + // This is an estimate. + cosangle += block_max_radius / dforward; + + // If block is not in the field of view, skip it + //if(cosangle < cos(FOV_ANGLE/2)) + if(cosangle < cos(FOV_ANGLE/2. * 4./3.)) + return false; + } + + return true; +} diff --git a/src/utility.h b/src/utility.h index 28cc95ddd..c4f45ba0f 100644 --- a/src/utility.h +++ b/src/utility.h @@ -1574,5 +1574,12 @@ private: core::map m_lists; }; +/* + Miscellaneous functions +*/ + +bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range); + + #endif -- 2.25.1