diff options
Diffstat (limited to 'src/client/clientmap.cpp')
-rw-r--r-- | src/client/clientmap.cpp | 240 |
1 files changed, 125 insertions, 115 deletions
diff --git a/src/client/clientmap.cpp b/src/client/clientmap.cpp index dea354c96..d41b66741 100644 --- a/src/client/clientmap.cpp +++ b/src/client/clientmap.cpp @@ -26,20 +26,24 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapblock.h" #include "profiler.h" #include "settings.h" -#include "camera.h" // CameraModes +#include "camera.h" // CameraModes #include "util/basic_macros.h" #include <algorithm> #include "client/renderingengine.h" -ClientMap::ClientMap(Client *client, MapDrawControl &control, s32 id) : - Map(dout_client, client), - scene::ISceneNode( - RenderingEngine::get_scene_manager()->getRootSceneNode(), - RenderingEngine::get_scene_manager(), id), - m_client(client), m_control(control) +ClientMap::ClientMap( + Client *client, + MapDrawControl &control, + s32 id +): + Map(dout_client, client), + scene::ISceneNode(RenderingEngine::get_scene_manager()->getRootSceneNode(), + RenderingEngine::get_scene_manager(), id), + m_client(client), + m_control(control) { - m_box = aabb3f(-BS * 1000000, -BS * 1000000, -BS * 1000000, BS * 1000000, - BS * 1000000, BS * 1000000); + m_box = aabb3f(-BS*1000000,-BS*1000000,-BS*1000000, + BS*1000000,BS*1000000,BS*1000000); /* TODO: Add a callback function so these can be updated when a setting * changes. At this point in time it doesn't matter (e.g. /set @@ -50,12 +54,13 @@ ClientMap::ClientMap(Client *client, MapDrawControl &control, s32 id) : * (as opposed to the this local caching). This can be addressed in * a later release. */ - m_cache_trilinear_filter = g_settings->getBool("trilinear_filter"); - m_cache_bilinear_filter = g_settings->getBool("bilinear_filter"); + m_cache_trilinear_filter = g_settings->getBool("trilinear_filter"); + m_cache_bilinear_filter = g_settings->getBool("bilinear_filter"); m_cache_anistropic_filter = g_settings->getBool("anisotropic_filter"); + } -MapSector *ClientMap::emergeSector(v2s16 p2d) +MapSector * ClientMap::emergeSector(v2s16 p2d) { // Check that it doesn't exist already MapSector *sector = getSectorNoGenerate(p2d); @@ -71,7 +76,8 @@ MapSector *ClientMap::emergeSector(v2s16 p2d) void ClientMap::OnRegisterSceneNode() { - if (IsVisible) { + if(IsVisible) + { SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); } @@ -79,23 +85,29 @@ void ClientMap::OnRegisterSceneNode() ISceneNode::OnRegisterSceneNode(); } -void ClientMap::getBlocksInViewRange( - v3s16 cam_pos_nodes, v3s16 *p_blocks_min, v3s16 *p_blocks_max) +void ClientMap::getBlocksInViewRange(v3s16 cam_pos_nodes, + v3s16 *p_blocks_min, v3s16 *p_blocks_max) { v3s16 box_nodes_d = m_control.wanted_range * v3s16(1, 1, 1); // Define p_nodes_min/max as v3s32 because 'cam_pos_nodes -/+ box_nodes_d' // can exceed the range of v3s16 when a large view range is used near the // world edges. - v3s32 p_nodes_min(cam_pos_nodes.X - box_nodes_d.X, - cam_pos_nodes.Y - box_nodes_d.Y, cam_pos_nodes.Z - box_nodes_d.Z); - v3s32 p_nodes_max(cam_pos_nodes.X + box_nodes_d.X, - cam_pos_nodes.Y + box_nodes_d.Y, cam_pos_nodes.Z + box_nodes_d.Z); + v3s32 p_nodes_min( + cam_pos_nodes.X - box_nodes_d.X, + cam_pos_nodes.Y - box_nodes_d.Y, + cam_pos_nodes.Z - box_nodes_d.Z); + v3s32 p_nodes_max( + cam_pos_nodes.X + box_nodes_d.X, + cam_pos_nodes.Y + box_nodes_d.Y, + cam_pos_nodes.Z + box_nodes_d.Z); // Take a fair amount as we will be dropping more out later // Umm... these additions are a bit strange but they are needed. - *p_blocks_min = v3s16(p_nodes_min.X / MAP_BLOCKSIZE - 3, + *p_blocks_min = v3s16( + p_nodes_min.X / MAP_BLOCKSIZE - 3, p_nodes_min.Y / MAP_BLOCKSIZE - 3, p_nodes_min.Z / MAP_BLOCKSIZE - 3); - *p_blocks_max = v3s16(p_nodes_max.X / MAP_BLOCKSIZE + 1, + *p_blocks_max = v3s16( + p_nodes_max.X / MAP_BLOCKSIZE + 1, p_nodes_max.Y / MAP_BLOCKSIZE + 1, p_nodes_max.Z / MAP_BLOCKSIZE + 1); } @@ -134,13 +146,14 @@ void ClientMap::updateDrawList() bool occlusion_culling_enabled = true; if (g_settings->getBool("free_move") && g_settings->getBool("noclip")) { MapNode n = getNode(cam_pos_nodes); - if (n.getContent() == CONTENT_IGNORE || m_nodedef->get(n).solidness == 2) + if (n.getContent() == CONTENT_IGNORE || + m_nodedef->get(n).solidness == 2) occlusion_culling_enabled = false; } // Uncomment to debug occluded blocks in the wireframe mode // TODO: Include this as a flag for an extended debugging setting - // if (occlusion_culling_enabled && m_control.show_wireframe) + //if (occlusion_culling_enabled && m_control.show_wireframe) // occlusion_culling_enabled = porting::getTimeS() & 1; for (const auto §or_it : m_sectors) { @@ -177,9 +190,10 @@ void ClientMap::updateDrawList() float d = 0.0; if (!isBlockInSight(block->getPos(), camera_position, - camera_direction, camera_fov, range, &d)) + camera_direction, camera_fov, range, &d)) continue; + /* Ignore if mesh doesn't exist */ @@ -192,9 +206,7 @@ void ClientMap::updateDrawList() Occlusion culling */ if ((!m_control.range_all && d > m_control.wanted_range * BS) || - (occlusion_culling_enabled && - isBlockOccluded(block, - cam_pos_nodes))) { + (occlusion_culling_enabled && isBlockOccluded(block, cam_pos_nodes))) { blocks_occlusion_culled++; continue; } @@ -221,7 +233,7 @@ void ClientMap::updateDrawList() struct MeshBufList { video::SMaterial m; - std::vector<scene::IMeshBuffer *> bufs; + std::vector<scene::IMeshBuffer*> bufs; }; struct MeshBufListList @@ -245,8 +257,8 @@ struct MeshBufListList std::vector<MeshBufList> &list = lists[layer]; const video::SMaterial &m = buf->getMaterial(); for (MeshBufList &l : list) { - // comparing a full material is quite expensive so we don't do it - // if not even first texture is equal + // comparing a full material is quite expensive so we don't do it if + // not even first texture is equal if (l.m.TextureLayer[0].Texture != m.TextureLayer[0].Texture) continue; @@ -262,7 +274,7 @@ struct MeshBufListList } }; -void ClientMap::renderMap(video::IVideoDriver *driver, s32 pass) +void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) { bool is_transparent_pass = pass == scene::ESNRP_TRANSPARENT; @@ -297,7 +309,7 @@ void ClientMap::renderMap(video::IVideoDriver *driver, s32 pass) // For limiting number of mesh animations per frame u32 mesh_animate_count = 0; - // u32 mesh_animate_count_far = 0; + //u32 mesh_animate_count_far = 0; /* Draw the selected MapBlocks @@ -313,23 +325,22 @@ void ClientMap::renderMap(video::IVideoDriver *driver, s32 pass) continue; float d = 0.0; - if (!isBlockInSight(block->getPos(), camera_position, camera_direction, - camera_fov, 100000 * BS, &d)) + if (!isBlockInSight(block->getPos(), camera_position, + camera_direction, camera_fov, 100000 * BS, &d)) continue; // Mesh animation if (pass == scene::ESNRP_SOLID) { - // MutexAutoLock lock(block->mesh_mutex); + //MutexAutoLock lock(block->mesh_mutex); MapBlockMesh *mapBlockMesh = block->mesh; assert(mapBlockMesh); // Pretty random but this should work somewhat nicely bool faraway = d >= BS * 50; if (mapBlockMesh->isAnimationForced() || !faraway || - mesh_animate_count < (m_control.range_all ? 200 - : 50)) { + mesh_animate_count < (m_control.range_all ? 200 : 50)) { - bool animated = mapBlockMesh->animate(faraway, - animation_time, crack, daynight_ratio); + bool animated = mapBlockMesh->animate(faraway, animation_time, + crack, daynight_ratio); if (animated) mesh_animate_count++; } else { @@ -341,7 +352,7 @@ void ClientMap::renderMap(video::IVideoDriver *driver, s32 pass) Get the meshbuffers of the block */ { - // MutexAutoLock lock(block->mesh_mutex); + //MutexAutoLock lock(block->mesh_mutex); MapBlockMesh *mapBlockMesh = block->mesh; assert(mapBlockMesh); @@ -354,30 +365,23 @@ void ClientMap::renderMap(video::IVideoDriver *driver, s32 pass) for (u32 i = 0; i < c; i++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(i); - video::SMaterial &material = buf->getMaterial(); - video::IMaterialRenderer *rnd = - driver->getMaterialRenderer( - material.MaterialType); + video::SMaterial& material = buf->getMaterial(); + video::IMaterialRenderer* rnd = + driver->getMaterialRenderer(material.MaterialType); bool transparent = (rnd && rnd->isTransparent()); if (transparent == is_transparent_pass) { if (buf->getVertexCount() == 0) - errorstream << "Block [" - << analyze_block(block) - << "] contains an " - "empty meshbuf" - << std::endl; - - material.setFlag( - video::EMF_TRILINEAR_FILTER, - m_cache_trilinear_filter); - material.setFlag( - video::EMF_BILINEAR_FILTER, - m_cache_bilinear_filter); - material.setFlag( - video::EMF_ANISOTROPIC_FILTER, - m_cache_anistropic_filter); + errorstream << "Block [" << analyze_block(block) + << "] contains an empty meshbuf" << std::endl; + + material.setFlag(video::EMF_TRILINEAR_FILTER, + m_cache_trilinear_filter); + material.setFlag(video::EMF_BILINEAR_FILTER, + m_cache_bilinear_filter); + material.setFlag(video::EMF_ANISOTROPIC_FILTER, + m_cache_anistropic_filter); material.setFlag(video::EMF_WIREFRAME, - m_control.show_wireframe); + m_control.show_wireframe); drawbufs.add(buf, layer); } @@ -393,9 +397,8 @@ void ClientMap::renderMap(video::IVideoDriver *driver, s32 pass) for (MeshBufList &list : lists) { // Check and abort if the machine is swapping a lot if (draw.getTimerTime() > 2000) { - infostream << "ClientMap::renderMap(): Rendering took " - ">2s, " - << "returning." << std::endl; + infostream << "ClientMap::renderMap(): Rendering took >2s, " << + "returning." << std::endl; return; } driver->setMaterial(list.m); @@ -417,9 +420,9 @@ void ClientMap::renderMap(video::IVideoDriver *driver, s32 pass) } static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step, - float step_multiplier, float start_distance, float end_distance, - const NodeDefManager *ndef, u32 daylight_factor, float sunlight_min_d, - int *result, bool *sunlight_seen) + float step_multiplier, float start_distance, float end_distance, + const NodeDefManager *ndef, u32 daylight_factor, float sunlight_min_d, + int *result, bool *sunlight_seen) { int brightness_sum = 0; int brightness_count = 0; @@ -435,7 +438,7 @@ static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step, { v3s16 p = floatToInt(p0 /*+ dir * 3*BS*/, BS); MapNode n = map->getNode(p); - if (ndef->get(n).param_type == CPT_LIGHT && + if(ndef->get(n).param_type == CPT_LIGHT && !ndef->get(n).sunlight_propagates) allow_allowing_non_sunlight_propagates = true; } @@ -443,14 +446,14 @@ static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step, { v3s16 p = floatToInt(pf, BS); MapNode n = map->getNode(p); - if (n.getContent() == CONTENT_IGNORE) { - float newd = 2 * BS; - pf = p0 + dir * 2 * newd; + if(n.getContent() == CONTENT_IGNORE){ + float newd = 2*BS; + pf = p0 + dir * 2*newd; distance = newd; sunlight_min_d = 0; } } - for (int i = 0; distance < end_distance; i++) { + for (int i=0; distance < end_distance; i++) { pf += dir * step; distance += step; step *= step_multiplier; @@ -465,10 +468,10 @@ static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step, if (ndef->get(n).param_type != CPT_LIGHT || (!ndef->get(n).sunlight_propagates && - !allow_non_sunlight_propagates)) { + !allow_non_sunlight_propagates)){ nonlight_seen = true; noncount++; - if (noncount >= 4) + if(noncount >= 4) break; continue; } @@ -481,7 +484,7 @@ static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step, brightness_count++; } *result = 0; - if (brightness_count == 0) + if(brightness_count == 0) return false; *result = brightness_sum / brightness_count; /*std::cerr<<"Sampled "<<brightness_count<<" points; result=" @@ -489,73 +492,78 @@ static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step, return true; } -int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor, int oldvalue, - bool *sunlight_seen_result) +int ClientMap::getBackgroundBrightness(float max_d, u32 daylight_factor, + int oldvalue, bool *sunlight_seen_result) { ScopeProfiler sp(g_profiler, "CM::getBackgroundBrightness", SPT_AVG); - static v3f z_directions[50] = {v3f(-100, 0, 0)}; - static f32 z_offsets[sizeof(z_directions) / sizeof(*z_directions)] = { - -1000, + static v3f z_directions[50] = { + v3f(-100, 0, 0) + }; + static f32 z_offsets[sizeof(z_directions)/sizeof(*z_directions)] = { + -1000, }; - if (z_directions[0].X < -99) { - for (u32 i = 0; i < sizeof(z_directions) / sizeof(*z_directions); i++) { + if(z_directions[0].X < -99){ + for(u32 i=0; i<sizeof(z_directions)/sizeof(*z_directions); i++){ // Assumes FOV of 72 and 16/9 aspect ratio - z_directions[i] = v3f(0.02 * myrand_range(-100, 100), 1.0, - 0.01 * myrand_range(-100, 100)) - .normalize(); - z_offsets[i] = 0.01 * myrand_range(0, 100); + z_directions[i] = v3f( + 0.02 * myrand_range(-100, 100), + 1.0, + 0.01 * myrand_range(-100, 100) + ).normalize(); + z_offsets[i] = 0.01 * myrand_range(0,100); } } int sunlight_seen_count = 0; - float sunlight_min_d = max_d * 0.8; - if (sunlight_min_d > 35 * BS) - sunlight_min_d = 35 * BS; + float sunlight_min_d = max_d*0.8; + if(sunlight_min_d > 35*BS) + sunlight_min_d = 35*BS; std::vector<int> values; - for (u32 i = 0; i < sizeof(z_directions) / sizeof(*z_directions); i++) { + for(u32 i=0; i<sizeof(z_directions)/sizeof(*z_directions); i++){ v3f z_dir = z_directions[i]; core::CMatrix4<f32> a; - a.buildRotateFromTo(v3f(0, 1, 0), z_dir); + a.buildRotateFromTo(v3f(0,1,0), z_dir); v3f dir = m_camera_direction; a.rotateVect(dir); int br = 0; - float step = BS * 1.5; - if (max_d > 35 * BS) + float step = BS*1.5; + if(max_d > 35*BS) step = max_d / 35 * 1.5; float off = step * z_offsets[i]; bool sunlight_seen_now = false; - bool ok = getVisibleBrightness(this, m_camera_position, dir, step, 1.0, - max_d * 0.6 + off, max_d, m_nodedef, daylight_factor, - sunlight_min_d, &br, &sunlight_seen_now); - if (sunlight_seen_now) + bool ok = getVisibleBrightness(this, m_camera_position, dir, + step, 1.0, max_d*0.6+off, max_d, m_nodedef, daylight_factor, + sunlight_min_d, + &br, &sunlight_seen_now); + if(sunlight_seen_now) sunlight_seen_count++; - if (!ok) + if(!ok) continue; values.push_back(br); // Don't try too much if being in the sun is clear - if (sunlight_seen_count >= 20) + if(sunlight_seen_count >= 20) break; } int brightness_sum = 0; int brightness_count = 0; std::sort(values.begin(), values.end()); u32 num_values_to_use = values.size(); - if (num_values_to_use >= 10) - num_values_to_use -= num_values_to_use / 2; - else if (num_values_to_use >= 7) - num_values_to_use -= num_values_to_use / 3; + if(num_values_to_use >= 10) + num_values_to_use -= num_values_to_use/2; + else if(num_values_to_use >= 7) + num_values_to_use -= num_values_to_use/3; u32 first_value_i = (values.size() - num_values_to_use) / 2; - for (u32 i = first_value_i; i < first_value_i + num_values_to_use; i++) { + for (u32 i=first_value_i; i < first_value_i + num_values_to_use; i++) { brightness_sum += values[i]; brightness_count++; } int ret = 0; - if (brightness_count == 0) { + if(brightness_count == 0){ MapNode n = getNode(floatToInt(m_camera_position, BS)); - if (m_nodedef->get(n).param_type == CPT_LIGHT) { + if(m_nodedef->get(n).param_type == CPT_LIGHT){ ret = decode_light(n.getLightBlend(daylight_factor, m_nodedef)); } else { ret = oldvalue; @@ -578,25 +586,27 @@ void ClientMap::renderPostFx(CameraMode cam_mode) // - If the player is in a solid node, make everything black. // - If the player is in liquid, draw a semi-transparent overlay. // - Do not if player is in third person mode - const ContentFeatures &features = m_nodedef->get(n); + const ContentFeatures& features = m_nodedef->get(n); video::SColor post_effect_color = features.post_effect_color; - if (features.solidness == 2 && - !((g_settings->getBool("noclip") || - g_settings->getBool("freecam")) && - m_client->checkLocalPrivilege("noclip")) && - cam_mode == CAMERA_MODE_FIRST) { + if(features.solidness == 2 && !((g_settings->getBool("noclip") || g_settings->getBool("freecam")) && + m_client->checkLocalPrivilege("noclip")) && + cam_mode == CAMERA_MODE_FIRST) + { post_effect_color = video::SColor(255, 0, 0, 0); } - if (post_effect_color.getAlpha() != 0) { + if (post_effect_color.getAlpha() != 0) + { // Draw a full-screen rectangle - video::IVideoDriver *driver = SceneManager->getVideoDriver(); + video::IVideoDriver* driver = SceneManager->getVideoDriver(); v2u32 ss = driver->getScreenSize(); - core::rect<s32> rect(0, 0, ss.X, ss.Y); + core::rect<s32> rect(0,0, ss.X, ss.Y); driver->draw2DRectangle(post_effect_color, rect); } } void ClientMap::PrintInfo(std::ostream &out) { - out << "ClientMap: "; + out<<"ClientMap: "; } + + |