\r
IrrlichtWrapper *g_irrlicht;\r
\r
-// All range-related stuff below is locked behind this\r
-JMutex g_range_mutex;\r
-\r
-// Blocks are viewed in this range from the player\r
-float g_viewing_range_nodes = 60;\r
-//s16 g_viewing_range_nodes = 0;\r
-\r
-// This is updated by the client's fetchBlocks routine\r
-//s16 g_actual_viewing_range_nodes = VIEWING_RANGE_NODES_DEFAULT;\r
-\r
-// If true, the preceding value has no meaning and all blocks\r
-// already existing in memory are drawn\r
-bool g_viewing_range_all = false;\r
-\r
-// This is the freetime ratio imposed by the dynamic viewing\r
-// range changing code.\r
-// It is controlled by the main loop to the smallest value that\r
-// inhibits glitches (dtime jitter) in the main loop.\r
-//float g_freetime_ratio = FREETIME_RATIO_MAX;\r
+MapDrawControl draw_control;\r
\r
/*\r
Settings.\r
// Viewing range selection\r
if(event.KeyInput.Key == irr::KEY_KEY_R)\r
{\r
- JMutexAutoLock lock(g_range_mutex);\r
- if(g_viewing_range_all)\r
+ if(draw_control.range_all)\r
{\r
- g_viewing_range_all = false;\r
+ draw_control.range_all = false;\r
dstream<<DTIME<<"Disabled full viewing range"<<std::endl;\r
}\r
else\r
{\r
- g_viewing_range_all = true;\r
+ draw_control.range_all = true;\r
dstream<<DTIME<<"Enabled full viewing range"<<std::endl;\r
}\r
}\r
void updateViewingRange(f32 frametime, Client *client)\r
{\r
// Range_all messes up frametime_avg\r
- if(g_viewing_range_all == true)\r
+ if(draw_control.range_all == true)\r
return;\r
\r
float wanted_fps = g_settings.getFloat("wanted_fps");\r
\r
float fraction_unbiased = frametime_avg / frametime_wanted;\r
\r
- float fraction = pow(fraction_unbiased, 20./(float)g_viewing_range_nodes);\r
+ float fraction = pow(fraction_unbiased, 20./(float)draw_control.wanted_range);\r
\r
/*float fraction = 1.0;\r
// If frametime is too high\r
s16 viewing_range_nodes_min = g_settings.getS16("viewing_range_nodes_min");\r
s16 viewing_range_nodes_max = g_settings.getS16("viewing_range_nodes_max");\r
\r
- s16 n = (float)g_viewing_range_nodes / fraction;\r
+ s16 n = (float)draw_control.wanted_range / fraction;\r
if(n < viewing_range_nodes_min)\r
n = viewing_range_nodes_min;\r
if(n > viewing_range_nodes_max)\r
\r
bool can_change = true;\r
\r
- if(client->isFetchingBlocks() == true && n > g_viewing_range_nodes)\r
+ if(client->isFetchingBlocks() == true && n > draw_control.wanted_range)\r
can_change = false;\r
\r
if(can_change)\r
- g_viewing_range_nodes = n;\r
+ draw_control.wanted_range = n;\r
\r
- /*dstream<<"g_viewing_range_nodes = "\r
- <<g_viewing_range_nodes<<std::endl;*/\r
+ /*dstream<<"draw_control.wanted_range = "\r
+ <<draw_control.wanted_range<<std::endl;*/\r
}\r
#endif\r
\r
void updateViewingRange(f32 frametime_in, Client *client)\r
{\r
- if(g_viewing_range_all == true)\r
+ if(draw_control.range_all == true)\r
return;\r
\r
static f32 added_frametime = 0;\r
<<": Collected "<<added_frames<<" frames, total of "\r
<<added_frametime<<"s."<<std::endl;\r
\r
- f32 frametime = added_frametime / added_frames;\r
+ dstream<<"draw_control.blocks_drawn="\r
+ <<draw_control.blocks_drawn\r
+ <<", draw_control.blocks_would_have_drawn="\r
+ <<draw_control.blocks_would_have_drawn\r
+ <<std::endl;\r
+ \r
+ float range_min = g_settings.getS16("viewing_range_nodes_min");\r
+ float range_max = g_settings.getS16("viewing_range_nodes_max");\r
+ \r
+ draw_control.wanted_min_range = range_min;\r
+ draw_control.wanted_max_blocks = (1.2*draw_control.blocks_drawn)+1;\r
+ \r
+ float block_draw_ratio = 1.0;\r
+ if(draw_control.blocks_would_have_drawn != 0)\r
+ {\r
+ block_draw_ratio = (float)draw_control.blocks_drawn\r
+ / (float)draw_control.blocks_would_have_drawn;\r
+ }\r
+\r
+ // Calculate the average frametime in the case that all wanted\r
+ // blocks had been drawn\r
+ f32 frametime = added_frametime / added_frames / block_draw_ratio;\r
+ \r
added_frametime = 0.0;\r
added_frames = 0;\r
\r
return;\r
}\r
\r
- float range = g_viewing_range_nodes;\r
+ float range = draw_control.wanted_range;\r
float new_range = range;\r
\r
static s16 range_old = 0;\r
// A high value here results in slow changing range (0.0025)\r
// SUGG: This could be dynamically adjusted so that when\r
// the camera is turning, this is lower\r
- float min_time_per_range = 0.001;\r
+ //float min_time_per_range = 0.0015;\r
+ float min_time_per_range = 0.0010;\r
+ //float min_time_per_range = 0.05 / range;\r
if(time_per_range < min_time_per_range)\r
+ {\r
time_per_range = min_time_per_range;\r
- \r
- dstream<<"time_per_range="<<time_per_range<<std::endl;\r
+ dstream<<"time_per_range="<<time_per_range<<" (min)"<<std::endl;\r
+ }\r
+ else\r
+ {\r
+ dstream<<"time_per_range="<<time_per_range<<std::endl;\r
+ }\r
\r
f32 wanted_range_change = wanted_frametime_change / time_per_range;\r
// Dampen the change a bit to kill oscillations\r
//wanted_range_change *= 0.9;\r
- wanted_range_change *= 0.75;\r
+ //wanted_range_change *= 0.75;\r
+ wanted_range_change *= 0.5;\r
dstream<<"wanted_range_change="<<wanted_range_change<<std::endl;\r
\r
// If needed range change is very small, just return\r
new_range += wanted_range_change;\r
dstream<<"new_range="<<new_range/*<<std::endl*/;\r
\r
- float range_min = g_settings.getS16("viewing_range_nodes_min");\r
- float range_max = g_settings.getS16("viewing_range_nodes_max");\r
- \r
float new_range_unclamped = new_range;\r
if(new_range < range_min)\r
new_range = range_min;\r
else\r
dstream<<std::endl;\r
\r
- JMutexAutoLock lock(g_range_mutex);\r
-\r
- g_viewing_range_nodes = new_range;\r
+ draw_control.wanted_range = new_range;\r
\r
range_old = new_range;\r
frametime_old = frametime;\r
\r
// Initialize random seed\r
srand(time(0));\r
+ mysrand(time(0));\r
\r
/*\r
Run unit tests\r
run_tests();\r
}\r
\r
- /*\r
- Global range mutex\r
- */\r
- g_range_mutex.Init();\r
- assert(g_range_mutex.IsInitialized());\r
-\r
// Read map parameters from settings\r
\r
HMParams hm_params;\r
Create client\r
*/\r
\r
- Client client(device, playername,\r
- g_range_mutex,\r
- g_viewing_range_nodes,\r
- g_viewing_range_all);\r
+ Client client(device, playername, draw_control);\r
\r
g_client = &client;\r
\r
\r
if(g_settings.getBool("enable_fog") == true)\r
{\r
- f32 range = g_viewing_range_nodes * BS;\r
- if(g_viewing_range_all)\r
+ f32 range = draw_control.wanted_range * BS;\r
+ if(draw_control.range_all)\r
range = 100000*BS;\r
\r
driver->setFog(\r
wchar_t temptext[150];\r
\r
static float drawtime_avg = 0;\r
- drawtime_avg = drawtime_avg * 0.98 + (float)drawtime*0.02;\r
+ drawtime_avg = drawtime_avg * 0.95 + (float)drawtime*0.05;\r
static float beginscenetime_avg = 0;\r
- beginscenetime_avg = beginscenetime_avg * 0.98 + (float)beginscenetime*0.02;\r
+ beginscenetime_avg = beginscenetime_avg * 0.95 + (float)beginscenetime*0.05;\r
static float scenetime_avg = 0;\r
- scenetime_avg = scenetime_avg * 0.98 + (float)scenetime*0.02;\r
+ scenetime_avg = scenetime_avg * 0.95 + (float)scenetime*0.05;\r
static float endscenetime_avg = 0;\r
- endscenetime_avg = endscenetime_avg * 0.98 + (float)endscenetime*0.02;\r
+ endscenetime_avg = endscenetime_avg * 0.95 + (float)endscenetime*0.05;\r
\r
swprintf(temptext, 150, L"Minetest-c55 ("\r
L"F: item=%i"\r
L")"\r
L" drawtime=%.0f, beginscenetime=%.0f, scenetime=%.0f, endscenetime=%.0f",\r
g_selected_item,\r
- g_viewing_range_all,\r
+ draw_control.range_all,\r
drawtime_avg,\r
beginscenetime_avg,\r
scenetime_avg,\r
busytime_jitter1_min_sample,\r
busytime_jitter1_max_sample,\r
dtime_jitter1_max_fraction * 100.0,\r
- g_viewing_range_nodes\r
+ draw_control.wanted_range\r
);\r
\r
guitext2->setText(temptext);\r
ClientMap::ClientMap(
Client *client,
- JMutex &range_mutex,
- float &viewing_range_nodes,
- bool &viewing_range_all,
+ MapDrawControl &control,
scene::ISceneNode* parent,
scene::ISceneManager* mgr,
s32 id
scene::ISceneNode(parent, mgr, id),
m_client(client),
mesh(NULL),
- m_range_mutex(range_mutex),
- m_viewing_range_nodes(viewing_range_nodes),
- m_viewing_range_all(viewing_range_all)
+ m_control(control)
{
mesh_mutex.Init();
*/
int time1 = time(0);
- //s32 daynight_i = m_client->getDayNightIndex();
u32 daynight_ratio = m_client->getDayNightRatio();
- /*
- Collect all blocks that are in the view range
-
- Should not optimize more here as we want to auto-update
- all changed nodes in viewing range at the next step.
- */
-
- float viewing_range_nodes;
- bool viewing_range_all;
- {
- JMutexAutoLock lock(m_range_mutex);
- viewing_range_nodes = m_viewing_range_nodes;
- viewing_range_all = m_viewing_range_all;
- }
-
m_camera_mutex.Lock();
v3f camera_position = m_camera_position;
v3f camera_direction = m_camera_direction;
camera_position.Y / BS,
camera_position.Z / BS);
- v3s16 box_nodes_d = viewing_range_nodes * v3s16(1,1,1);
+ v3s16 box_nodes_d = m_control.wanted_range * v3s16(1,1,1);
v3s16 p_nodes_min = cam_pos_nodes - box_nodes_d;
v3s16 p_nodes_max = cam_pos_nodes + box_nodes_d;
// For limiting number of mesh updates per frame
u32 mesh_update_count = 0;
+
+ u32 blocks_would_have_drawn = 0;
+ u32 blocks_drawn = 0;
//NOTE: The sectors map should be locked but we're not doing it
// because it'd cause too much delays
int timecheck_counter = 0;
-
core::map<v2s16, MapSector*>::Iterator si;
si = m_sectors.getIterator();
for(; si.atEnd() == false; si++)
MapSector *sector = si.getNode()->getValue();
v2s16 sp = sector->getPos();
- if(viewing_range_all == false)
+ if(m_control.range_all == false)
{
if(sp.X < p_blocks_min.X
|| sp.X > p_blocks_max.X
// Total distance
f32 d = blockpos_relative.getLength();
- if(viewing_range_all == false)
+ if(m_control.range_all == false)
{
// If block is far away, don't draw it
- if(d > viewing_range_nodes * BS)
+ if(d > m_control.wanted_range * BS)
// This is nicer when fog is used
- //if((dforward+d)/2 > viewing_range_nodes * BS)
+ //if((dforward+d)/2 > m_control.wanted_range * BS)
continue;
}
}
f32 faraway = BS*50;
- //f32 faraway = viewing_range_nodes * BS;
+ //f32 faraway = m_control.wanted_range * BS;
/*
This has to be done with the mesh_mutex unlocked
if(mesh == NULL)
continue;
+
+ blocks_would_have_drawn++;
+ if(blocks_drawn >= m_control.wanted_max_blocks
+ && m_control.range_all == false
+ && d > m_control.wanted_min_range * BS)
+ continue;
+ blocks_drawn++;
u32 c = mesh->getMeshBufferCount();
}
} // foreach sectorblocks
}
+
+ m_control.blocks_drawn = blocks_drawn;
+ m_control.blocks_would_have_drawn = blocks_would_have_drawn;
/*dstream<<"renderMap(): is_transparent_pass="<<is_transparent_pass
<<", rendered "<<vertex_count<<" vertices."<<std::endl;*/