mirror of
https://github.com/minetest/minetest.git
synced 2024-08-20 13:34:17 +02:00
day/night working client side
This commit is contained in:
parent
240499dc2c
commit
0ca9423b8b
@ -23,6 +23,8 @@
|
||||
#random_input = false
|
||||
#client_delete_unused_sectors_timeout = 1200
|
||||
|
||||
#enable_fog = true
|
||||
|
||||
# Server side stuff
|
||||
|
||||
# - The possible generators are:
|
||||
@ -51,8 +53,8 @@
|
||||
#max_simultaneous_block_sends_per_client = 1
|
||||
#max_simultaneous_block_sends_server_total = 4
|
||||
|
||||
#max_block_send_distance = 8
|
||||
#max_block_generate_distance = 6
|
||||
#max_block_send_distance = 5
|
||||
#max_block_generate_distance = 4
|
||||
|
||||
#disable_water_climb = true
|
||||
# Note that this gets applied at map generation time
|
||||
|
132
src/client.cpp
132
src/client.cpp
@ -47,6 +47,8 @@ void * ClientUpdateThread::Thread()
|
||||
{
|
||||
m_client->asyncStep();
|
||||
|
||||
//m_client->updateSomeExpiredMeshes();
|
||||
|
||||
bool was = m_client->AsyncProcessData();
|
||||
|
||||
if(was == false)
|
||||
@ -84,7 +86,15 @@ Client::Client(IrrlichtDevice *device,
|
||||
m_inventory_updated(false),
|
||||
m_time(0),
|
||||
m_time_counter(0.0)
|
||||
//m_daynight_i(0)
|
||||
//m_daynight_ratio(1000)
|
||||
{
|
||||
m_packetcounter_timer = 0.0;
|
||||
m_delete_unused_sectors_timer = 0.0;
|
||||
m_connection_reinit_timer = 0.0;
|
||||
m_avg_rtt_timer = 0.0;
|
||||
m_playerpos_send_timer = 0.0;
|
||||
|
||||
//m_fetchblock_mutex.Init();
|
||||
m_incoming_queue_mutex.Init();
|
||||
m_env_mutex.Init();
|
||||
@ -154,14 +164,41 @@ void Client::step(float dtime)
|
||||
m_time += seconds;
|
||||
if(seconds > 0)
|
||||
{
|
||||
dstream<<"m_time="<<m_time<<std::endl;
|
||||
JMutexAutoLock envlock(m_env_mutex);
|
||||
//dstream<<"m_time="<<m_time<<std::endl;
|
||||
/*JMutexAutoLock envlock(m_env_mutex);
|
||||
u32 dr = 500+500*sin((float)((m_time/10)%7)/7.*2.*PI);
|
||||
if(dr != m_env.getDaylightRatio())
|
||||
if(dr != m_env.getDayNightRatio())
|
||||
{
|
||||
dstream<<"dr="<<dr<<std::endl;
|
||||
m_env.setDaylightRatio(dr);
|
||||
m_env.setDayNightRatio(dr);
|
||||
m_env.expireMeshes();
|
||||
}*/
|
||||
#if 1
|
||||
s32 d = 4;
|
||||
s32 t = (m_time/10)%d;
|
||||
s32 dn = 0;
|
||||
if(t == d/2-1 || t == d-1)
|
||||
dn = 1;
|
||||
else if(t < d/2-1)
|
||||
dn = 0;
|
||||
else
|
||||
dn = 2;
|
||||
|
||||
u32 dr = 1000;
|
||||
if(dn == 0)
|
||||
dr = 1000;
|
||||
if(dn == 1)
|
||||
dr = 600;
|
||||
if(dn == 2)
|
||||
dr = 300;
|
||||
#else
|
||||
u32 dr = 1000;
|
||||
#endif
|
||||
if(dr != m_env.getDayNightRatio())
|
||||
{
|
||||
dstream<<"dr="<<dr<<std::endl;
|
||||
m_env.setDayNightRatio(dr);
|
||||
m_env.expireMeshes(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -186,7 +223,7 @@ void Client::step(float dtime)
|
||||
Packet counter
|
||||
*/
|
||||
{
|
||||
static float counter = -0.001;
|
||||
float &counter = m_packetcounter_timer;
|
||||
counter -= dtime;
|
||||
if(counter <= 0.0)
|
||||
{
|
||||
@ -206,12 +243,13 @@ void Client::step(float dtime)
|
||||
clear caches
|
||||
*/
|
||||
|
||||
static float counter = -0.001;
|
||||
float &counter = m_delete_unused_sectors_timer;
|
||||
counter -= dtime;
|
||||
if(counter <= 0.0)
|
||||
{
|
||||
// 3 minute interval
|
||||
counter = 180.0;
|
||||
//counter = 180.0;
|
||||
counter = 60.0;
|
||||
|
||||
JMutexAutoLock lock(m_env_mutex);
|
||||
|
||||
@ -290,7 +328,7 @@ void Client::step(float dtime)
|
||||
|
||||
if(connected == false)
|
||||
{
|
||||
static float counter = -0.001;
|
||||
float &counter = m_connection_reinit_timer;
|
||||
counter -= dtime;
|
||||
if(counter <= 0.0)
|
||||
{
|
||||
@ -354,12 +392,7 @@ void Client::step(float dtime)
|
||||
}
|
||||
|
||||
{
|
||||
// Fetch some nearby blocks
|
||||
//fetchBlocks();
|
||||
}
|
||||
|
||||
{
|
||||
static float counter = 0.0;
|
||||
float &counter = m_avg_rtt_timer;
|
||||
counter += dtime;
|
||||
if(counter >= 10)
|
||||
{
|
||||
@ -371,8 +404,7 @@ void Client::step(float dtime)
|
||||
}
|
||||
}
|
||||
{
|
||||
// Update at reasonable intervals (0.2s)
|
||||
static float counter = 0.0;
|
||||
float &counter = m_playerpos_send_timer;
|
||||
counter += dtime;
|
||||
if(counter >= 0.2)
|
||||
{
|
||||
@ -1121,7 +1153,7 @@ bool Client::AsyncProcessPacket(LazyMeshUpdater &mesh_updater)
|
||||
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
|
||||
|
||||
/*dstream<<DTIME<<"Client: Thread: BLOCKDATA for ("
|
||||
<<p.X<<","<<p.Y<<","<<p.Z<<"): ";*/
|
||||
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
|
||||
|
||||
std::string datastring((char*)&data[8], datasize-8);
|
||||
std::istringstream istr(datastring, std::ios_base::binary);
|
||||
@ -1780,9 +1812,71 @@ void Client::printDebugInfo(std::ostream &os)
|
||||
<<std::endl;
|
||||
}
|
||||
|
||||
float Client::getDaylightRatio()
|
||||
/*s32 Client::getDayNightIndex()
|
||||
{
|
||||
assert(m_daynight_i >= 0 && m_daynight_i < DAYNIGHT_CACHE_COUNT);
|
||||
return m_daynight_i;
|
||||
}*/
|
||||
|
||||
u32 Client::getDayNightRatio()
|
||||
{
|
||||
JMutexAutoLock envlock(m_env_mutex);
|
||||
return m_env.getDaylightRatio();
|
||||
return m_env.getDayNightRatio();
|
||||
}
|
||||
|
||||
/*void Client::updateSomeExpiredMeshes()
|
||||
{
|
||||
TimeTaker timer("updateSomeExpiredMeshes()", g_device);
|
||||
|
||||
Player *player;
|
||||
{
|
||||
JMutexAutoLock envlock(m_env_mutex);
|
||||
player = m_env.getLocalPlayer();
|
||||
}
|
||||
|
||||
u32 daynight_ratio = getDayNightRatio();
|
||||
|
||||
v3f playerpos = player->getPosition();
|
||||
v3f playerspeed = player->getSpeed();
|
||||
|
||||
v3s16 center_nodepos = floatToInt(playerpos);
|
||||
v3s16 center = getNodeBlockPos(center_nodepos);
|
||||
|
||||
u32 counter = 0;
|
||||
|
||||
s16 d_max = 5;
|
||||
|
||||
for(s16 d = 0; d <= d_max; d++)
|
||||
{
|
||||
core::list<v3s16> list;
|
||||
getFacePositions(list, d);
|
||||
|
||||
core::list<v3s16>::Iterator li;
|
||||
for(li=list.begin(); li!=list.end(); li++)
|
||||
{
|
||||
v3s16 p = *li + center;
|
||||
MapBlock *block = NULL;
|
||||
try
|
||||
{
|
||||
//JMutexAutoLock envlock(m_env_mutex);
|
||||
block = m_env.getMap().getBlockNoCreate(p);
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
{
|
||||
}
|
||||
|
||||
if(block == NULL)
|
||||
continue;
|
||||
|
||||
if(block->getMeshExpired() == false)
|
||||
continue;
|
||||
|
||||
block->updateMesh(daynight_ratio);
|
||||
|
||||
counter++;
|
||||
if(counter >= 5)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
|
40
src/client.h
40
src/client.h
@ -36,35 +36,19 @@ public:
|
||||
|
||||
class Client;
|
||||
|
||||
class ClientUpdateThread : public JThread
|
||||
class ClientUpdateThread : public SimpleThread
|
||||
{
|
||||
bool run;
|
||||
JMutex run_mutex;
|
||||
|
||||
Client *m_client;
|
||||
|
||||
public:
|
||||
|
||||
ClientUpdateThread(Client *client) : JThread(), run(true), m_client(client)
|
||||
ClientUpdateThread(Client *client):
|
||||
SimpleThread(),
|
||||
m_client(client)
|
||||
{
|
||||
run_mutex.Init();
|
||||
}
|
||||
|
||||
void * Thread();
|
||||
|
||||
bool getRun()
|
||||
{
|
||||
run_mutex.Lock();
|
||||
bool run_cached = run;
|
||||
run_mutex.Unlock();
|
||||
return run_cached;
|
||||
}
|
||||
void setRun(bool a_run)
|
||||
{
|
||||
run_mutex.Lock();
|
||||
run = a_run;
|
||||
run_mutex.Unlock();
|
||||
}
|
||||
};
|
||||
|
||||
struct IncomingPacket
|
||||
@ -98,6 +82,7 @@ struct IncomingPacket
|
||||
if(*m_refcount == 0){
|
||||
if(m_data != NULL)
|
||||
delete[] m_data;
|
||||
delete m_refcount;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -237,7 +222,10 @@ public:
|
||||
// Prints a line or two of info
|
||||
void printDebugInfo(std::ostream &os);
|
||||
|
||||
float getDaylightRatio();
|
||||
//s32 getDayNightIndex();
|
||||
u32 getDayNightRatio();
|
||||
|
||||
//void updateSomeExpiredMeshes();
|
||||
|
||||
private:
|
||||
|
||||
@ -252,6 +240,12 @@ private:
|
||||
// This sends the player's current name etc to the server
|
||||
void sendPlayerInfo();
|
||||
|
||||
float m_packetcounter_timer;
|
||||
float m_delete_unused_sectors_timer;
|
||||
float m_connection_reinit_timer;
|
||||
float m_avg_rtt_timer;
|
||||
float m_playerpos_send_timer;
|
||||
|
||||
ClientUpdateThread m_thread;
|
||||
|
||||
// NOTE: If connection and environment are both to be locked,
|
||||
@ -290,6 +284,10 @@ private:
|
||||
// Access these only in main thread.
|
||||
u32 m_time;
|
||||
float m_time_counter;
|
||||
|
||||
// 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
|
||||
//s32 m_daynight_i;
|
||||
//u32 m_daynight_ratio;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -445,6 +445,7 @@ Peer::Peer(u16 a_id, Address a_address)
|
||||
address = a_address;
|
||||
timeout_counter = 0.0;
|
||||
//resend_timeout = RESEND_TIMEOUT_MINIMUM;
|
||||
ping_timer = 0.0;
|
||||
resend_timeout = 0.5;
|
||||
avg_rtt = -1.0;
|
||||
has_sent_with_id = false;
|
||||
|
@ -39,32 +39,29 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#define PI 3.14159
|
||||
|
||||
#define SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT (60*10)
|
||||
//#define SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT (60*10)
|
||||
#define SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT (60)
|
||||
#define SERVER_MAP_SAVE_INTERVAL (60)
|
||||
/*#define SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT (10)
|
||||
#define SERVER_MAP_SAVE_INTERVAL (10)*/
|
||||
|
||||
// This is the same as in minecraft and everything else
|
||||
#define FOV_ANGLE (PI/2.5)
|
||||
//#define FOV_ANGLE (PI/2.25)
|
||||
|
||||
// The absolute working limit is (2^15 - viewing_range).
|
||||
#define MAP_GENERATION_LIMIT (31000)
|
||||
|
||||
//#define MAX_SIMULTANEOUS_BLOCK_SENDS 2
|
||||
|
||||
// Time after building, during which the following limit
|
||||
// is in use
|
||||
#define FULL_BLOCK_SEND_ENABLE_MIN_TIME_FROM_BUILDING 2.0
|
||||
//#define LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS 1
|
||||
// This many blocks are sent when player is building
|
||||
#define LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS 0
|
||||
|
||||
// Override for the previous one when distance is low
|
||||
// Override for the previous one when distance of block
|
||||
// is very low
|
||||
#define BLOCK_SEND_DISABLE_LIMITS_MAX_D 1
|
||||
|
||||
//#define MAX_SIMULTANEOUS_BLOCK_SENDS_SERVER_TOTAL 4
|
||||
|
||||
// Viewing range stuff
|
||||
|
||||
//#define HEIGHTMAP_RANGE_NODES 300
|
||||
|
||||
//#define FREETIME_RATIO 0.2
|
||||
#define FREETIME_RATIO 0.15
|
||||
|
||||
@ -75,10 +72,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#define SIGN_TEXT_MAX_LENGTH 50
|
||||
|
||||
// The distance of how far objects will be sent to client
|
||||
//#define ACTIVE_OBJECT_D_BLOCKS 2
|
||||
|
||||
// Wether to catch all std::exceptions.
|
||||
// Whether to catch all std::exceptions.
|
||||
// Assert will be called on such an event.
|
||||
#define CATCH_UNHANDLED_EXCEPTIONS 1
|
||||
|
||||
@ -88,7 +82,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
#define MAX_OBJECTDATA_SIZE 450
|
||||
|
||||
//#define WATER_LEVEL (-5)
|
||||
#define WATER_LEVEL (0)
|
||||
|
||||
#endif
|
||||
|
@ -24,7 +24,7 @@ Environment::Environment(Map *map, std::ostream &dout):
|
||||
m_dout(dout)
|
||||
{
|
||||
m_map = map;
|
||||
m_daylight_ratio = 0.2;
|
||||
m_daynight_ratio = 0.2;
|
||||
}
|
||||
|
||||
Environment::~Environment()
|
||||
@ -36,7 +36,9 @@ Environment::~Environment()
|
||||
delete (*i);
|
||||
}
|
||||
|
||||
delete m_map;
|
||||
// The map is removed by the SceneManager
|
||||
m_map->drop();
|
||||
//delete m_map;
|
||||
}
|
||||
|
||||
void Environment::step(float dtime)
|
||||
@ -153,7 +155,7 @@ void Environment::step(float dtime)
|
||||
{
|
||||
v3s16 p_blocks = getNodeBlockPos(bottompos);
|
||||
MapBlock *b = m_map->getBlockNoCreate(p_blocks);
|
||||
b->updateMesh(m_daylight_ratio);
|
||||
b->updateMesh(m_daynight_ratio);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -243,21 +245,21 @@ void Environment::printPlayers(std::ostream &o)
|
||||
|
||||
void Environment::updateMeshes(v3s16 blockpos)
|
||||
{
|
||||
m_map->updateMeshes(blockpos, m_daylight_ratio);
|
||||
m_map->updateMeshes(blockpos, m_daynight_ratio);
|
||||
}
|
||||
|
||||
void Environment::expireMeshes()
|
||||
void Environment::expireMeshes(bool only_daynight_diffed)
|
||||
{
|
||||
m_map->expireMeshes();
|
||||
m_map->expireMeshes(only_daynight_diffed);
|
||||
}
|
||||
|
||||
void Environment::setDaylightRatio(u32 r)
|
||||
void Environment::setDayNightRatio(u32 r)
|
||||
{
|
||||
m_daylight_ratio = r;
|
||||
m_daynight_ratio = r;
|
||||
}
|
||||
|
||||
u32 Environment::getDaylightRatio()
|
||||
u32 Environment::getDayNightRatio()
|
||||
{
|
||||
return m_daylight_ratio;
|
||||
return m_daynight_ratio;
|
||||
}
|
||||
|
||||
|
@ -61,16 +61,16 @@ public:
|
||||
void printPlayers(std::ostream &o);
|
||||
|
||||
void updateMeshes(v3s16 blockpos);
|
||||
void expireMeshes();
|
||||
void setDaylightRatio(u32 r);
|
||||
u32 getDaylightRatio();
|
||||
void expireMeshes(bool only_daynight_diffed);
|
||||
void setDayNightRatio(u32 r);
|
||||
u32 getDayNightRatio();
|
||||
|
||||
private:
|
||||
Map *m_map;
|
||||
core::list<Player*> m_players;
|
||||
// Debug output goes here
|
||||
std::ostream &m_dout;
|
||||
u32 m_daylight_ratio;
|
||||
u32 m_daynight_ratio;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -19,6 +19,67 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#include "light.h"
|
||||
|
||||
/*u32 daynight_cache_ratios[DAYNIGHT_CACHE_COUNT] =
|
||||
{
|
||||
1000,
|
||||
600,
|
||||
300
|
||||
};*/
|
||||
|
||||
u8 light_decode_table[LIGHT_MAX+1] =
|
||||
{
|
||||
0,
|
||||
6,
|
||||
8,
|
||||
11,
|
||||
14,
|
||||
19,
|
||||
26,
|
||||
34,
|
||||
45,
|
||||
61,
|
||||
81,
|
||||
108,
|
||||
143,
|
||||
191,
|
||||
255,
|
||||
};
|
||||
/*u8 light_decode_table[LIGHT_MAX+1] =
|
||||
{
|
||||
0,
|
||||
3,
|
||||
6,
|
||||
10,
|
||||
18,
|
||||
25,
|
||||
35,
|
||||
50,
|
||||
75,
|
||||
95,
|
||||
120,
|
||||
150,
|
||||
185,
|
||||
215,
|
||||
255,
|
||||
};*/
|
||||
/*u8 light_decode_table[LIGHT_MAX+1] =
|
||||
{
|
||||
0,
|
||||
5,
|
||||
12,
|
||||
22,
|
||||
35,
|
||||
50,
|
||||
65,
|
||||
85,
|
||||
100,
|
||||
120,
|
||||
140,
|
||||
160,
|
||||
185,
|
||||
215,
|
||||
255,
|
||||
};*/
|
||||
// LIGHT_MAX is 14, 0-14 is 15 values
|
||||
/*u8 light_decode_table[LIGHT_MAX+1] =
|
||||
{
|
||||
@ -38,24 +99,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
191,
|
||||
255,
|
||||
};*/
|
||||
u8 light_decode_table[LIGHT_MAX+1] =
|
||||
{
|
||||
0,
|
||||
5,
|
||||
12,
|
||||
22,
|
||||
35,
|
||||
50,
|
||||
65,
|
||||
85,
|
||||
100,
|
||||
120,
|
||||
140,
|
||||
160,
|
||||
185,
|
||||
215,
|
||||
255,
|
||||
};
|
||||
|
||||
#if 0
|
||||
/*
|
||||
|
@ -22,6 +22,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#include "common_irrlicht.h"
|
||||
|
||||
/*
|
||||
Day/night cache:
|
||||
Meshes are cached for different day-to-night transition values
|
||||
*/
|
||||
|
||||
/*#define DAYNIGHT_CACHE_COUNT 3
|
||||
// First one is day, last one is night.
|
||||
extern u32 daynight_cache_ratios[DAYNIGHT_CACHE_COUNT];*/
|
||||
|
||||
/*
|
||||
Lower level lighting stuff
|
||||
*/
|
||||
|
186
src/main.cpp
186
src/main.cpp
@ -176,14 +176,13 @@ TODO: Node cracking animation when digging
|
||||
- TODO: A way to generate new textures by combining textures
|
||||
- TODO: Mesh update to fetch cracked faces from the former
|
||||
|
||||
TODO: Add server unused sector deletion settings to settings
|
||||
|
||||
TODO: TOSERVER_LEAVE
|
||||
|
||||
Doing now:
|
||||
======================================================================
|
||||
|
||||
TODO: Add a second lighting value to the MS nibble of param of
|
||||
air to tell how bright the air node is when there is no sunlight.
|
||||
When day changes to night, these two values can be interpolated.
|
||||
- The biggest job is to add support to the lighting routines
|
||||
|
||||
======================================================================
|
||||
|
||||
*/
|
||||
@ -315,8 +314,7 @@ void set_default_settings()
|
||||
g_settings.setDefault("name", "");
|
||||
g_settings.setDefault("random_input", "false");
|
||||
g_settings.setDefault("client_delete_unused_sectors_timeout", "1200");
|
||||
g_settings.setDefault("max_block_send_distance", "8");
|
||||
g_settings.setDefault("max_block_generate_distance", "6");
|
||||
g_settings.setDefault("enable_fog", "true");
|
||||
|
||||
// Server stuff
|
||||
g_settings.setDefault("creative_mode", "false");
|
||||
@ -332,6 +330,8 @@ void set_default_settings()
|
||||
g_settings.setDefault("max_simultaneous_block_sends_server_total", "4");
|
||||
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", "4");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -860,7 +860,8 @@ void updateViewingRange(f32 frametime, Client *client)
|
||||
|
||||
// Initialize to the target value
|
||||
static float frametime_avg = 1.0/wanted_fps;
|
||||
frametime_avg = frametime_avg * 0.9 + frametime * 0.1;
|
||||
//frametime_avg = frametime_avg * 0.9 + frametime * 0.1;
|
||||
frametime_avg = frametime_avg * 0.7 + frametime * 0.3;
|
||||
|
||||
static f32 counter = 0;
|
||||
if(counter > 0){
|
||||
@ -878,6 +879,11 @@ void updateViewingRange(f32 frametime, Client *client)
|
||||
|
||||
float fraction = sqrt(frametime_avg / frametime_wanted);
|
||||
|
||||
/*float fraction = sqrt(frametime_avg / frametime_wanted) / 2.0
|
||||
+ frametime_avg / frametime_wanted / 2.0;*/
|
||||
|
||||
//float fraction = frametime_avg / frametime_wanted;
|
||||
|
||||
static bool fraction_is_good = false;
|
||||
|
||||
float fraction_good_threshold = 0.1;
|
||||
@ -1048,9 +1054,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
/*
|
||||
Parse command line
|
||||
TODO
|
||||
*/
|
||||
|
||||
// List all allowed options
|
||||
core::map<std::string, ValueSpec> allowed_options;
|
||||
allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG));
|
||||
allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG,
|
||||
@ -1058,6 +1064,10 @@ int main(int argc, char *argv[])
|
||||
allowed_options.insert("config", ValueSpec(VALUETYPE_STRING,
|
||||
"Load configuration from specified file"));
|
||||
allowed_options.insert("port", ValueSpec(VALUETYPE_STRING));
|
||||
allowed_options.insert("address", ValueSpec(VALUETYPE_STRING));
|
||||
allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG));
|
||||
allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG));
|
||||
allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG));
|
||||
|
||||
Settings cmd_args;
|
||||
|
||||
@ -1116,14 +1126,6 @@ int main(int argc, char *argv[])
|
||||
// Initialize timestamp mutex
|
||||
g_timestamp_mutex.Init();
|
||||
|
||||
/*
|
||||
Run unit tests
|
||||
*/
|
||||
if(ENABLE_TESTS)
|
||||
{
|
||||
run_tests();
|
||||
}
|
||||
|
||||
/*
|
||||
Initialization
|
||||
*/
|
||||
@ -1168,6 +1170,18 @@ int main(int argc, char *argv[])
|
||||
// Initialize random seed
|
||||
srand(time(0));
|
||||
|
||||
/*
|
||||
Run unit tests
|
||||
*/
|
||||
if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false)
|
||||
|| cmd_args.getFlag("enable-unittests") == true)
|
||||
{
|
||||
run_tests();
|
||||
}
|
||||
|
||||
/*
|
||||
Global range mutex
|
||||
*/
|
||||
g_range_mutex.Init();
|
||||
assert(g_range_mutex.IsInitialized());
|
||||
|
||||
@ -1263,14 +1277,18 @@ int main(int argc, char *argv[])
|
||||
bool hosting = false;
|
||||
char connect_name[100] = "";
|
||||
|
||||
std::cout<<"Address to connect to [empty = host a game]: ";
|
||||
if(g_settings.get("address") != "" && is_yes(g_settings.get("host_game")) == false)
|
||||
if(cmd_args.exists("address"))
|
||||
{
|
||||
snprintf(connect_name, 100, "%s", cmd_args.get("address").c_str());
|
||||
}
|
||||
else if(g_settings.get("address") != "" && is_yes(g_settings.get("host_game")) == false)
|
||||
{
|
||||
std::cout<<g_settings.get("address")<<std::endl;
|
||||
snprintf(connect_name, 100, "%s", g_settings.get("address").c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout<<"Address to connect to [empty = host a game]: ";
|
||||
std::cin.getline(connect_name, 100);
|
||||
}
|
||||
|
||||
@ -1280,9 +1298,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if(hosting)
|
||||
std::cout<<"-> hosting"<<std::endl;
|
||||
std::cout<<"> Hosting game"<<std::endl;
|
||||
else
|
||||
std::cout<<"-> "<<connect_name<<std::endl;
|
||||
std::cout<<"> Connecting to "<<connect_name<<std::endl;
|
||||
|
||||
char playername[PLAYERNAME_SIZE] = "";
|
||||
if(g_settings.get("name") != "")
|
||||
@ -1393,7 +1411,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
device->setResizable(true);
|
||||
|
||||
if(g_settings.getBool("random_input"))
|
||||
bool random_input = g_settings.getBool("random_input")
|
||||
|| cmd_args.getFlag("random-input");
|
||||
if(random_input)
|
||||
g_input = new RandomInputHandler();
|
||||
else
|
||||
g_input = new RealInputHandler(device, &receiver);
|
||||
@ -1523,14 +1543,14 @@ int main(int argc, char *argv[])
|
||||
/*
|
||||
Create skybox
|
||||
*/
|
||||
scene::ISceneNode* skybox;
|
||||
/*scene::ISceneNode* skybox;
|
||||
skybox = smgr->addSkyBoxSceneNode(
|
||||
driver->getTexture("../data/skybox2.png"),
|
||||
driver->getTexture("../data/skybox3.png"),
|
||||
driver->getTexture("../data/skybox1.png"),
|
||||
driver->getTexture("../data/skybox1.png"),
|
||||
driver->getTexture("../data/skybox1.png"),
|
||||
driver->getTexture("../data/skybox1.png"));
|
||||
driver->getTexture("../data/skybox1.png"));*/
|
||||
|
||||
/*
|
||||
Create the camera node
|
||||
@ -1553,21 +1573,6 @@ int main(int argc, char *argv[])
|
||||
// Just so big a value that everything rendered is visible
|
||||
camera->setFarValue(100000*BS);
|
||||
|
||||
/*//f32 range = BS*HEIGHTMAP_RANGE_NODES*0.9;
|
||||
f32 range = BS*HEIGHTMAP_RANGE_NODES*0.9;
|
||||
|
||||
camera->setFarValue(range);
|
||||
|
||||
driver->setFog(
|
||||
skycolor,
|
||||
video::EFT_FOG_LINEAR,
|
||||
range*0.8,
|
||||
range,
|
||||
0.01,
|
||||
false,
|
||||
false
|
||||
);*/
|
||||
|
||||
f32 camera_yaw = 0; // "right/left"
|
||||
f32 camera_pitch = 0; // "up/down"
|
||||
|
||||
@ -1888,9 +1893,11 @@ int main(int argc, char *argv[])
|
||||
Mouse and camera control
|
||||
*/
|
||||
|
||||
if(device->isWindowActive() && g_game_focused && !pauseMenu.isVisible())
|
||||
if((device->isWindowActive() && g_game_focused && !pauseMenu.isVisible())
|
||||
|| random_input)
|
||||
{
|
||||
device->getCursorControl()->setVisible(false);
|
||||
if(!random_input)
|
||||
device->getCursorControl()->setVisible(false);
|
||||
|
||||
if(first_loop_after_window_activation){
|
||||
//std::cout<<"window active, first loop"<<std::endl;
|
||||
@ -1981,7 +1988,7 @@ int main(int argc, char *argv[])
|
||||
if(selected_object->getTypeId() == MAPBLOCKOBJECT_TYPE_SIGN)
|
||||
{
|
||||
dstream<<"Sign object right-clicked"<<std::endl;
|
||||
|
||||
|
||||
unFocusGame();
|
||||
|
||||
input_guitext = guienv->addStaticText(L"",
|
||||
@ -1992,8 +1999,17 @@ int main(int argc, char *argv[])
|
||||
|
||||
input_guitext->setDrawBackground(true);
|
||||
|
||||
g_text_buffer = L"";
|
||||
g_text_buffer_accepted = false;
|
||||
if(random_input)
|
||||
{
|
||||
g_text_buffer = L"ASD LOL 8)";
|
||||
g_text_buffer_accepted = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_text_buffer = L"";
|
||||
g_text_buffer_accepted = false;
|
||||
}
|
||||
|
||||
textbuf_dest = new TextDestSign(
|
||||
selected_object->getBlock()->getPos(),
|
||||
selected_object->getId(),
|
||||
@ -2227,20 +2243,54 @@ int main(int argc, char *argv[])
|
||||
*/
|
||||
|
||||
camera->setAspectRatio((f32)screensize.X / (f32)screensize.Y);
|
||||
|
||||
// Background color is choosen based on whether the player is
|
||||
// much beyond the initial ground level
|
||||
/*video::SColor bgcolor;
|
||||
v3s16 p0 = Map::floatToInt(player_position);
|
||||
// Does this make short random delays?
|
||||
// NOTE: no need for this, sky doesn't show underground with
|
||||
// enough range
|
||||
bool is_underground = client.isNodeUnderground(p0);
|
||||
//bool is_underground = false;
|
||||
if(is_underground == false)
|
||||
bgcolor = video::SColor(255,90,140,200);
|
||||
else
|
||||
bgcolor = video::SColor(255,0,0,0);*/
|
||||
|
||||
//video::SColor bgcolor = video::SColor(255,90,140,200);
|
||||
//video::SColor bgcolor = skycolor;
|
||||
|
||||
//s32 daynight_i = client.getDayNightIndex();
|
||||
//video::SColor bgcolor = skycolor[daynight_i];
|
||||
|
||||
/*f32 range = g_viewing_range_nodes * BS;
|
||||
if(g_viewing_range_all)
|
||||
range = 100000*BS;
|
||||
u32 daynight_ratio = client.getDayNightRatio();
|
||||
video::SColor bgcolor = video::SColor(
|
||||
255,
|
||||
skycolor.getRed() * daynight_ratio / 1000,
|
||||
skycolor.getGreen() * daynight_ratio / 1000,
|
||||
skycolor.getBlue() * daynight_ratio / 1000);
|
||||
|
||||
driver->setFog(
|
||||
skycolor,
|
||||
video::EFT_FOG_LINEAR,
|
||||
range*0.6,
|
||||
range,
|
||||
0.01,
|
||||
false, // pixel fog
|
||||
false // range fog
|
||||
);*/
|
||||
/*
|
||||
Fog
|
||||
*/
|
||||
|
||||
if(g_settings.getBool("enable_fog") == true)
|
||||
{
|
||||
f32 range = g_viewing_range_nodes * BS;
|
||||
if(g_viewing_range_all)
|
||||
range = 100000*BS;
|
||||
|
||||
driver->setFog(
|
||||
bgcolor,
|
||||
video::EFT_FOG_LINEAR,
|
||||
range*0.6,
|
||||
range,
|
||||
0.01,
|
||||
false, // pixel fog
|
||||
false // range fog
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@ -2359,29 +2409,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
TimeTaker drawtimer("Drawing", device);
|
||||
|
||||
/*
|
||||
Background color is choosen based on whether the player is
|
||||
much beyond the initial ground level
|
||||
*/
|
||||
/*video::SColor bgcolor;
|
||||
v3s16 p0 = Map::floatToInt(player_position);
|
||||
// Does this make short random delays?
|
||||
// NOTE: no need for this, sky doesn't show underground with
|
||||
// enough range
|
||||
bool is_underground = client.isNodeUnderground(p0);
|
||||
//bool is_underground = false;
|
||||
if(is_underground == false)
|
||||
bgcolor = video::SColor(255,90,140,200);
|
||||
else
|
||||
bgcolor = video::SColor(255,0,0,0);*/
|
||||
|
||||
//video::SColor bgcolor = video::SColor(255,90,140,200);
|
||||
video::SColor bgcolor = skycolor;
|
||||
|
||||
{
|
||||
TimeTaker timer("beginScene", device);
|
||||
//driver->beginScene(true, true, bgcolor);
|
||||
driver->beginScene(false, true, bgcolor);
|
||||
driver->beginScene(true, true, bgcolor);
|
||||
//driver->beginScene(false, true, bgcolor);
|
||||
beginscenetime = timer.stop(true);
|
||||
}
|
||||
|
||||
@ -2471,6 +2503,8 @@ int main(int argc, char *argv[])
|
||||
device->yield();*/
|
||||
}
|
||||
|
||||
delete quick_inventory;
|
||||
|
||||
} // client is deleted at this point
|
||||
|
||||
delete g_input;
|
||||
|
142
src/map.cpp
142
src/map.cpp
@ -755,7 +755,7 @@ void Map::updateLighting(enum LightBank bank,
|
||||
// Yes, add it to light_sources... somehow.
|
||||
// It has to be added at somewhere above, in the loop.
|
||||
// TODO
|
||||
// NOTE: This actually works quite fine without it
|
||||
// NOTE: This actually works fine without doing so
|
||||
// - Find out why it works
|
||||
|
||||
{
|
||||
@ -778,6 +778,17 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
|
||||
{
|
||||
updateLighting(LIGHTBANK_DAY, a_blocks, modified_blocks);
|
||||
updateLighting(LIGHTBANK_NIGHT, a_blocks, modified_blocks);
|
||||
|
||||
/*
|
||||
Update information about whether day and night light differ
|
||||
*/
|
||||
for(core::map<v3s16, MapBlock*>::Iterator
|
||||
i = modified_blocks.getIterator();
|
||||
i.atEnd() == false; i++)
|
||||
{
|
||||
MapBlock *block = i.getNode()->getValue();
|
||||
block->updateDayNightDiff();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -901,6 +912,17 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
|
||||
*/
|
||||
spreadLight(bank, light_sources, modified_blocks);
|
||||
}
|
||||
|
||||
/*
|
||||
Update information about whether day and night light differ
|
||||
*/
|
||||
for(core::map<v3s16, MapBlock*>::Iterator
|
||||
i = modified_blocks.getIterator();
|
||||
i.atEnd() == false; i++)
|
||||
{
|
||||
MapBlock *block = i.getNode()->getValue();
|
||||
block->updateDayNightDiff();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1027,9 +1049,20 @@ void Map::removeNodeAndUpdate(v3s16 p,
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Update information about whether day and night light differ
|
||||
*/
|
||||
for(core::map<v3s16, MapBlock*>::Iterator
|
||||
i = modified_blocks.getIterator();
|
||||
i.atEnd() == false; i++)
|
||||
{
|
||||
MapBlock *block = i.getNode()->getValue();
|
||||
block->updateDayNightDiff();
|
||||
}
|
||||
}
|
||||
|
||||
void Map::expireMeshes()
|
||||
void Map::expireMeshes(bool only_daynight_diffed)
|
||||
{
|
||||
TimeTaker timer("expireMeshes()", g_device);
|
||||
|
||||
@ -1046,12 +1079,18 @@ void Map::expireMeshes()
|
||||
for(i=sectorblocks.begin(); i!=sectorblocks.end(); i++)
|
||||
{
|
||||
MapBlock *block = *i;
|
||||
|
||||
if(only_daynight_diffed && dayNightDiffed(block->getPos()) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
JMutexAutoLock lock(block->mesh_mutex);
|
||||
if(block->mesh != NULL)
|
||||
{
|
||||
//block->mesh->drop();
|
||||
//block->mesh = NULL;
|
||||
/*block->mesh->drop();
|
||||
block->mesh = NULL;*/
|
||||
block->setMeshExpired(true);
|
||||
}
|
||||
}
|
||||
@ -1059,36 +1098,70 @@ void Map::expireMeshes()
|
||||
}
|
||||
}
|
||||
|
||||
void Map::updateMeshes(v3s16 blockpos, u32 daylight_factor)
|
||||
void Map::updateMeshes(v3s16 blockpos, u32 daynight_ratio)
|
||||
{
|
||||
assert(mapType() == MAPTYPE_CLIENT);
|
||||
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(0,0,0);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
b->updateMesh(daylight_factor);
|
||||
b->updateMesh(daynight_ratio);
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(-1,0,0);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
b->updateMesh(daylight_factor);
|
||||
b->updateMesh(daynight_ratio);
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(0,-1,0);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
b->updateMesh(daylight_factor);
|
||||
b->updateMesh(daynight_ratio);
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(0,0,-1);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
b->updateMesh(daylight_factor);
|
||||
b->updateMesh(daynight_ratio);
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
}
|
||||
|
||||
bool Map::dayNightDiffed(v3s16 blockpos)
|
||||
{
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(0,0,0);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
if(b->dayNightDiffed())
|
||||
return true;
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(1,0,0);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
if(b->dayNightDiffed())
|
||||
return true;
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(0,1,0);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
if(b->dayNightDiffed())
|
||||
return true;
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
try{
|
||||
v3s16 p = blockpos + v3s16(0,0,1);
|
||||
MapBlock *b = getBlockNoCreate(p);
|
||||
if(b->dayNightDiffed())
|
||||
return true;
|
||||
}
|
||||
catch(InvalidPositionException &e){}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Updates usage timers
|
||||
*/
|
||||
@ -2216,8 +2289,8 @@ void ServerMap::save(bool only_changed)
|
||||
}//sectorlock
|
||||
|
||||
u32 deleted_count = 0;
|
||||
deleted_count = deleteUnusedSectors
|
||||
(SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT);
|
||||
deleted_count = deleteUnusedSectors(
|
||||
SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT);
|
||||
|
||||
/*
|
||||
Only print if something happened or saved whole map
|
||||
@ -2719,6 +2792,9 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||
*/
|
||||
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
|
||||
|
||||
@ -2771,12 +2847,13 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||
//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++)
|
||||
{
|
||||
{
|
||||
static int timecheck_counter = 0;
|
||||
timecheck_counter++;
|
||||
if(timecheck_counter > 50)
|
||||
{
|
||||
@ -2872,7 +2949,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||
/*
|
||||
Draw the faces of the block
|
||||
*/
|
||||
|
||||
#if 1
|
||||
bool mesh_expired = false;
|
||||
|
||||
{
|
||||
@ -2885,29 +2962,56 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||
if(block->mesh == NULL && mesh_expired == false)
|
||||
continue;
|
||||
}
|
||||
|
||||
f32 faraway = BS*50;
|
||||
//f32 faraway = viewing_range_nodes * BS;
|
||||
|
||||
/*
|
||||
This has to be done with the mesh_mutex unlocked
|
||||
*/
|
||||
if(mesh_expired && mesh_update_count < 1)
|
||||
if(mesh_expired && mesh_update_count < 6
|
||||
&& (d < faraway || mesh_update_count < 3))
|
||||
//if(mesh_expired && mesh_update_count < 4)
|
||||
{
|
||||
mesh_update_count++;
|
||||
|
||||
// Mesh has been expired: generate new mesh
|
||||
block->updateMesh(m_client->getDaylightRatio());
|
||||
}
|
||||
//block->updateMeshes(daynight_i);
|
||||
block->updateMesh(daynight_ratio);
|
||||
|
||||
mesh_expired = false;
|
||||
}
|
||||
|
||||
/*
|
||||
Don't draw an expired mesh that is far away
|
||||
*/
|
||||
/*if(mesh_expired && d >= faraway)
|
||||
//if(mesh_expired)
|
||||
{
|
||||
// Instead, delete it
|
||||
JMutexAutoLock lock(block->mesh_mutex);
|
||||
if(block->mesh)
|
||||
{
|
||||
block->mesh->drop();
|
||||
block->mesh = NULL;
|
||||
}
|
||||
// And continue to next block
|
||||
continue;
|
||||
}*/
|
||||
#endif
|
||||
{
|
||||
JMutexAutoLock lock(block->mesh_mutex);
|
||||
|
||||
if(block->mesh == NULL)
|
||||
scene::SMesh *mesh = block->mesh;
|
||||
|
||||
if(mesh == NULL)
|
||||
continue;
|
||||
|
||||
u32 c = block->mesh->getMeshBufferCount();
|
||||
u32 c = mesh->getMeshBufferCount();
|
||||
|
||||
for(u32 i=0; i<c; i++)
|
||||
{
|
||||
scene::IMeshBuffer *buf = block->mesh->getMeshBuffer(i);
|
||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
|
||||
const video::SMaterial& material = buf->getMaterial();
|
||||
video::IMaterialRenderer* rnd =
|
||||
driver->getMaterialRenderer(material.MaterialType);
|
||||
|
19
src/map.h
19
src/map.h
@ -224,6 +224,11 @@ public:
|
||||
return MAPTYPE_BASE;
|
||||
}
|
||||
|
||||
virtual void drop()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void updateCamera(v3f pos, v3f dir)
|
||||
{
|
||||
JMutexAutoLock lock(m_camera_mutex);
|
||||
@ -375,9 +380,14 @@ public:
|
||||
Updates the faces of the given block and blocks on the
|
||||
leading edge.
|
||||
*/
|
||||
void updateMeshes(v3s16 blockpos, u32 daylight_factor);
|
||||
void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
|
||||
|
||||
void expireMeshes();
|
||||
void expireMeshes(bool only_daynight_diffed);
|
||||
|
||||
/*
|
||||
Takes the blocks at the trailing edges into account
|
||||
*/
|
||||
bool dayNightDiffed(v3s16 blockpos);
|
||||
|
||||
//core::aabbox3d<s16> getDisplayedBlockArea();
|
||||
|
||||
@ -544,6 +554,11 @@ public:
|
||||
return MAPTYPE_CLIENT;
|
||||
}
|
||||
|
||||
void drop()
|
||||
{
|
||||
ISceneNode::drop();
|
||||
}
|
||||
|
||||
/*
|
||||
Forcefully get a sector from somewhere
|
||||
*/
|
||||
|
413
src/mapblock.cpp
413
src/mapblock.cpp
@ -29,6 +29,52 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
MapBlock
|
||||
*/
|
||||
|
||||
MapBlock::MapBlock(NodeContainer *parent, v3s16 pos, bool dummy):
|
||||
m_parent(parent),
|
||||
m_pos(pos),
|
||||
changed(true),
|
||||
is_underground(false),
|
||||
m_mesh_expired(false),
|
||||
m_day_night_differs(false),
|
||||
m_objects(this)
|
||||
{
|
||||
data = NULL;
|
||||
if(dummy == false)
|
||||
reallocate();
|
||||
|
||||
mesh_mutex.Init();
|
||||
|
||||
mesh = NULL;
|
||||
/*for(s32 i=0; i<DAYNIGHT_CACHE_COUNT; i++)
|
||||
{
|
||||
mesh[i] = NULL;
|
||||
}*/
|
||||
}
|
||||
|
||||
MapBlock::~MapBlock()
|
||||
{
|
||||
{
|
||||
JMutexAutoLock lock(mesh_mutex);
|
||||
|
||||
if(mesh)
|
||||
{
|
||||
mesh->drop();
|
||||
mesh = NULL;
|
||||
}
|
||||
/*for(s32 i=0; i<DAYNIGHT_CACHE_COUNT; i++)
|
||||
{
|
||||
if(mesh[i] != NULL)
|
||||
{
|
||||
mesh[i]->drop();
|
||||
mesh[i] = NULL;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
if(data)
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
bool MapBlock::isValidPositionParent(v3s16 p)
|
||||
{
|
||||
if(isValidPosition(p))
|
||||
@ -68,10 +114,33 @@ void MapBlock::setNodeParent(v3s16 p, MapNode & n)
|
||||
}
|
||||
}
|
||||
|
||||
FastFace * MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
|
||||
v3s16 dir, v3f scale, v3f posRelative_f)
|
||||
MapNode MapBlock::getNodeParentNoEx(v3s16 p)
|
||||
{
|
||||
FastFace *f = new FastFace;
|
||||
if(isValidPosition(p) == false)
|
||||
{
|
||||
try{
|
||||
return m_parent->getNode(getPosRelative() + p);
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
{
|
||||
return MapNode(CONTENT_IGNORE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(data == NULL)
|
||||
{
|
||||
return MapNode(CONTENT_IGNORE);
|
||||
}
|
||||
return data[p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X];
|
||||
}
|
||||
}
|
||||
|
||||
void MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
|
||||
v3s16 dir, v3f scale, v3f posRelative_f,
|
||||
core::array<FastFace> &dest)
|
||||
{
|
||||
FastFace face;
|
||||
|
||||
// Position is at the center of the cube.
|
||||
v3f pos = p * BS;
|
||||
@ -85,21 +154,39 @@ FastFace * MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
|
||||
vertex_pos[2] = v3f(-BS/2, BS/2,BS/2);
|
||||
vertex_pos[3] = v3f( BS/2, BS/2,BS/2);
|
||||
|
||||
if(dir == v3s16(0,0,1))
|
||||
{
|
||||
for(u16 i=0; i<4; i++)
|
||||
vertex_pos[i].rotateXZBy(0);
|
||||
}
|
||||
else if(dir == v3s16(0,0,-1))
|
||||
{
|
||||
for(u16 i=0; i<4; i++)
|
||||
vertex_pos[i].rotateXZBy(180);
|
||||
}
|
||||
else if(dir == v3s16(1,0,0))
|
||||
{
|
||||
for(u16 i=0; i<4; i++)
|
||||
vertex_pos[i].rotateXZBy(-90);
|
||||
}
|
||||
else if(dir == v3s16(-1,0,0))
|
||||
{
|
||||
for(u16 i=0; i<4; i++)
|
||||
vertex_pos[i].rotateXZBy(90);
|
||||
}
|
||||
else if(dir == v3s16(0,1,0))
|
||||
{
|
||||
for(u16 i=0; i<4; i++)
|
||||
vertex_pos[i].rotateYZBy(-90);
|
||||
}
|
||||
else if(dir == v3s16(0,-1,0))
|
||||
{
|
||||
for(u16 i=0; i<4; i++)
|
||||
vertex_pos[i].rotateYZBy(90);
|
||||
}
|
||||
|
||||
for(u16 i=0; i<4; i++)
|
||||
{
|
||||
if(dir == v3s16(0,0,1))
|
||||
vertex_pos[i].rotateXZBy(0);
|
||||
else if(dir == v3s16(0,0,-1))
|
||||
vertex_pos[i].rotateXZBy(180);
|
||||
else if(dir == v3s16(1,0,0))
|
||||
vertex_pos[i].rotateXZBy(-90);
|
||||
else if(dir == v3s16(-1,0,0))
|
||||
vertex_pos[i].rotateXZBy(90);
|
||||
else if(dir == v3s16(0,1,0))
|
||||
vertex_pos[i].rotateYZBy(-90);
|
||||
else if(dir == v3s16(0,-1,0))
|
||||
vertex_pos[i].rotateYZBy(90);
|
||||
|
||||
vertex_pos[i].X *= scale.X;
|
||||
vertex_pos[i].Y *= scale.Y;
|
||||
vertex_pos[i].Z *= scale.Z;
|
||||
@ -125,20 +212,21 @@ FastFace * MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
|
||||
|
||||
video::SColor c = video::SColor(alpha,li,li,li);
|
||||
|
||||
f->vertices[0] = video::S3DVertex(vertex_pos[0], zerovector, c,
|
||||
face.vertices[0] = video::S3DVertex(vertex_pos[0], zerovector, c,
|
||||
core::vector2d<f32>(0,1));
|
||||
f->vertices[1] = video::S3DVertex(vertex_pos[1], zerovector, c,
|
||||
face.vertices[1] = video::S3DVertex(vertex_pos[1], zerovector, c,
|
||||
core::vector2d<f32>(abs_scale,1));
|
||||
f->vertices[2] = video::S3DVertex(vertex_pos[2], zerovector, c,
|
||||
face.vertices[2] = video::S3DVertex(vertex_pos[2], zerovector, c,
|
||||
core::vector2d<f32>(abs_scale,0));
|
||||
f->vertices[3] = video::S3DVertex(vertex_pos[3], zerovector, c,
|
||||
face.vertices[3] = video::S3DVertex(vertex_pos[3], zerovector, c,
|
||||
core::vector2d<f32>(0,0));
|
||||
|
||||
f->tile = tile;
|
||||
face.tile = tile;
|
||||
//DEBUG
|
||||
//f->tile = TILE_STONE;
|
||||
|
||||
return f;
|
||||
|
||||
dest.push_back(face);
|
||||
//return f;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -146,15 +234,20 @@ FastFace * MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
|
||||
Order doesn't matter.
|
||||
|
||||
If either of the nodes doesn't exist, light is 0.
|
||||
|
||||
parameters:
|
||||
daynight_ratio: 0...1000
|
||||
n: getNodeParent(p)
|
||||
n2: getNodeParent(p + face_dir)
|
||||
face_dir: axis oriented unit vector from p to p2
|
||||
*/
|
||||
u8 MapBlock::getFaceLight(u32 daylight_factor, v3s16 p, v3s16 face_dir)
|
||||
u8 MapBlock::getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
|
||||
v3s16 face_dir)
|
||||
{
|
||||
try{
|
||||
MapNode n = getNodeParent(p);
|
||||
MapNode n2 = getNodeParent(p + face_dir);
|
||||
u8 light;
|
||||
u8 l1 = n.getLightBlend(daylight_factor);
|
||||
u8 l2 = n2.getLightBlend(daylight_factor);
|
||||
u8 l1 = n.getLightBlend(daynight_ratio);
|
||||
u8 l2 = n2.getLightBlend(daynight_ratio);
|
||||
if(l1 > l2)
|
||||
light = l1;
|
||||
else
|
||||
@ -184,21 +277,20 @@ u8 MapBlock::getFaceLight(u32 daylight_factor, v3s16 p, v3s16 face_dir)
|
||||
Gets node tile from any place relative to block.
|
||||
Returns TILE_NODE if doesn't exist or should not be drawn.
|
||||
*/
|
||||
TileSpec MapBlock::getNodeTile(v3s16 p, v3s16 face_dir)
|
||||
TileSpec MapBlock::getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir)
|
||||
{
|
||||
TileSpec spec;
|
||||
|
||||
spec.feature = TILEFEAT_NONE;
|
||||
try{
|
||||
MapNode n = getNodeParent(p);
|
||||
|
||||
spec.id = n.getTile(face_dir);
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
/*//DEBUG
|
||||
{
|
||||
spec.id = TILE_NONE;
|
||||
}
|
||||
|
||||
spec.id = TILE_STONE;
|
||||
return spec;
|
||||
}*/
|
||||
|
||||
spec.feature = TILEFEAT_NONE;
|
||||
//spec.id = TILE_STONE;
|
||||
spec.id = mn.getTile(face_dir);
|
||||
|
||||
/*
|
||||
Check temporary modifications on this node
|
||||
*/
|
||||
@ -221,7 +313,7 @@ TileSpec MapBlock::getNodeTile(v3s16 p, v3s16 face_dir)
|
||||
return spec;
|
||||
}
|
||||
|
||||
u8 MapBlock::getNodeContent(v3s16 p)
|
||||
u8 MapBlock::getNodeContent(v3s16 p, MapNode mn)
|
||||
{
|
||||
/*
|
||||
Check temporary modifications on this node
|
||||
@ -253,16 +345,8 @@ u8 MapBlock::getNodeContent(v3s16 p)
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
try{
|
||||
MapNode n = getNodeParent(p);
|
||||
|
||||
return n.d;
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
{
|
||||
return CONTENT_IGNORE;
|
||||
}
|
||||
|
||||
return mn.d;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -271,48 +355,47 @@ u8 MapBlock::getNodeContent(v3s16 p)
|
||||
face_dir: unit vector with only one of x, y or z
|
||||
*/
|
||||
void MapBlock::updateFastFaceRow(
|
||||
u32 daylight_factor,
|
||||
u32 daynight_ratio,
|
||||
v3f posRelative_f,
|
||||
v3s16 startpos,
|
||||
u16 length,
|
||||
v3s16 translate_dir,
|
||||
v3f translate_dir_f,
|
||||
v3s16 face_dir,
|
||||
core::list<FastFace*> &dest)
|
||||
v3f face_dir_f,
|
||||
core::array<FastFace> &dest)
|
||||
{
|
||||
/*
|
||||
Precalculate some variables
|
||||
*/
|
||||
v3f translate_dir_f(translate_dir.X, translate_dir.Y,
|
||||
translate_dir.Z); // floating point conversion
|
||||
v3f face_dir_f(face_dir.X, face_dir.Y,
|
||||
face_dir.Z); // floating point conversion
|
||||
v3f posRelative_f(getPosRelative().X, getPosRelative().Y,
|
||||
getPosRelative().Z); // floating point conversion
|
||||
|
||||
v3s16 p = startpos;
|
||||
/*
|
||||
Get face light at starting position
|
||||
*/
|
||||
u8 light = getFaceLight(daylight_factor, p, face_dir);
|
||||
|
||||
u16 continuous_tiles_count = 0;
|
||||
|
||||
TileSpec tile0 = getNodeTile(p, face_dir);
|
||||
TileSpec tile1 = getNodeTile(p + face_dir, -face_dir);
|
||||
MapNode n0 = getNodeParentNoEx(p);
|
||||
MapNode n1 = getNodeParentNoEx(p + face_dir);
|
||||
|
||||
u8 light = getFaceLight(daynight_ratio, n0, n1, face_dir);
|
||||
|
||||
TileSpec tile0 = getNodeTile(n0, p, face_dir);
|
||||
TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir);
|
||||
|
||||
for(u16 j=0; j<length; j++)
|
||||
{
|
||||
bool next_is_different = true;
|
||||
|
||||
v3s16 p_next;
|
||||
MapNode n0_next;
|
||||
MapNode n1_next;
|
||||
TileSpec tile0_next;
|
||||
TileSpec tile1_next;
|
||||
u8 light_next = 0;
|
||||
|
||||
if(j != length - 1){
|
||||
if(j != length - 1)
|
||||
{
|
||||
p_next = p + translate_dir;
|
||||
tile0_next = getNodeTile(p_next, face_dir);
|
||||
tile1_next = getNodeTile(p_next + face_dir, -face_dir);
|
||||
light_next = getFaceLight(daylight_factor, p_next, face_dir);
|
||||
n0_next = getNodeParentNoEx(p_next);
|
||||
n1_next = getNodeParentNoEx(p_next + face_dir);
|
||||
tile0_next = getNodeTile(n0_next, p_next, face_dir);
|
||||
tile1_next = getNodeTile(n1_next, p_next + face_dir, -face_dir);
|
||||
light_next = getFaceLight(daynight_ratio, n0_next, n1_next, face_dir);
|
||||
|
||||
if(tile0_next == tile0
|
||||
&& tile1_next == tile1
|
||||
@ -331,8 +414,8 @@ void MapBlock::updateFastFaceRow(
|
||||
*/
|
||||
//u8 mf = face_contents(tile0, tile1);
|
||||
// This is hackish
|
||||
u8 content0 = getNodeContent(p);
|
||||
u8 content1 = getNodeContent(p + face_dir);
|
||||
u8 content0 = getNodeContent(p, n0);
|
||||
u8 content1 = getNodeContent(p + face_dir, n1);
|
||||
u8 mf = face_contents(content0, content1);
|
||||
|
||||
if(mf != 0)
|
||||
@ -352,26 +435,28 @@ void MapBlock::updateFastFaceRow(
|
||||
scale.Z = continuous_tiles_count;
|
||||
}
|
||||
|
||||
FastFace *f;
|
||||
//FastFace *f;
|
||||
|
||||
// If node at sp (tile0) is more solid
|
||||
if(mf == 1)
|
||||
{
|
||||
f = makeFastFace(tile0, light,
|
||||
makeFastFace(tile0, light,
|
||||
sp, face_dir, scale,
|
||||
posRelative_f);
|
||||
posRelative_f, dest);
|
||||
}
|
||||
// If node at sp is less solid (mf == 2)
|
||||
else
|
||||
{
|
||||
f = makeFastFace(tile1, light,
|
||||
makeFastFace(tile1, light,
|
||||
sp+face_dir_f, -face_dir, scale,
|
||||
posRelative_f);
|
||||
posRelative_f, dest);
|
||||
}
|
||||
dest.push_back(f);
|
||||
//dest.push_back(f);
|
||||
}
|
||||
|
||||
continuous_tiles_count = 0;
|
||||
n0 = n0_next;
|
||||
n1 = n1_next;
|
||||
tile0 = tile0_next;
|
||||
tile1 = tile1_next;
|
||||
light = light_next;
|
||||
@ -474,89 +559,101 @@ private:
|
||||
core::array<PreMeshBuffer> m_prebuffers;
|
||||
};
|
||||
|
||||
void MapBlock::updateMesh(u32 daylight_factor)
|
||||
void MapBlock::updateMesh(u32 daynight_ratio)
|
||||
{
|
||||
/*v3s16 p = getPosRelative();
|
||||
std::cout<<"MapBlock("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
||||
<<"::updateMesh(): ";*/
|
||||
//<<"::updateMesh()"<<std::endl;
|
||||
TimeTaker timer1("updateMesh()", g_device);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
TODO: Change this to directly generate the mesh (and get rid
|
||||
of FastFaces)
|
||||
DEBUG: If mesh has been generated, don't generate it again
|
||||
*/
|
||||
{
|
||||
JMutexAutoLock meshlock(mesh_mutex);
|
||||
if(mesh != NULL)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// 4-21ms
|
||||
//TimeTaker timer1("updateMesh()", g_device);
|
||||
|
||||
core::list<FastFace*> *fastfaces_new = new core::list<FastFace*>;
|
||||
core::array<FastFace> fastfaces_new;
|
||||
|
||||
v3f posRelative_f(getPosRelative().X, getPosRelative().Y,
|
||||
getPosRelative().Z); // floating point conversion
|
||||
|
||||
/*
|
||||
We are including the faces of the trailing edges of the block.
|
||||
This means that when something changes, the caller must
|
||||
also update the meshes of the blocks at the leading edges.
|
||||
|
||||
NOTE: This is the slowest part of this method. The other parts
|
||||
take around 0ms, this takes around 15-70ms.
|
||||
NOTE: This is the slowest part of this method.
|
||||
*/
|
||||
|
||||
/*
|
||||
Go through every y,z and get top faces in rows of x+
|
||||
*/
|
||||
for(s16 y=0; y<MAP_BLOCKSIZE; y++){
|
||||
//for(s16 y=-1; y<MAP_BLOCKSIZE; y++){
|
||||
for(s16 z=0; z<MAP_BLOCKSIZE; z++){
|
||||
updateFastFaceRow(daylight_factor,
|
||||
updateFastFaceRow(daynight_ratio, posRelative_f,
|
||||
v3s16(0,y,z), MAP_BLOCKSIZE,
|
||||
v3s16(1,0,0),
|
||||
v3s16(0,1,0),
|
||||
*fastfaces_new);
|
||||
v3s16(1,0,0), //dir
|
||||
v3f (1,0,0),
|
||||
v3s16(0,1,0), //face dir
|
||||
v3f (0,1,0),
|
||||
fastfaces_new);
|
||||
}
|
||||
}
|
||||
/*
|
||||
Go through every x,y and get right faces in rows of z+
|
||||
*/
|
||||
for(s16 x=0; x<MAP_BLOCKSIZE; x++){
|
||||
//for(s16 x=-1; x<MAP_BLOCKSIZE; x++){
|
||||
for(s16 y=0; y<MAP_BLOCKSIZE; y++){
|
||||
updateFastFaceRow(daylight_factor,
|
||||
updateFastFaceRow(daynight_ratio, posRelative_f,
|
||||
v3s16(x,y,0), MAP_BLOCKSIZE,
|
||||
v3s16(0,0,1),
|
||||
v3f (0,0,1),
|
||||
v3s16(1,0,0),
|
||||
*fastfaces_new);
|
||||
v3f (1,0,0),
|
||||
fastfaces_new);
|
||||
}
|
||||
}
|
||||
/*
|
||||
Go through every y,z and get back faces in rows of x+
|
||||
*/
|
||||
for(s16 z=0; z<MAP_BLOCKSIZE; z++){
|
||||
//for(s16 z=-1; z<MAP_BLOCKSIZE; z++){
|
||||
for(s16 y=0; y<MAP_BLOCKSIZE; y++){
|
||||
updateFastFaceRow(daylight_factor,
|
||||
updateFastFaceRow(daynight_ratio, posRelative_f,
|
||||
v3s16(0,y,z), MAP_BLOCKSIZE,
|
||||
v3s16(1,0,0),
|
||||
v3f (1,0,0),
|
||||
v3s16(0,0,1),
|
||||
*fastfaces_new);
|
||||
v3f (0,0,1),
|
||||
fastfaces_new);
|
||||
}
|
||||
}
|
||||
|
||||
// End of slow part
|
||||
|
||||
/*
|
||||
Convert FastFaces to SMesh
|
||||
*/
|
||||
|
||||
scene::SMesh *mesh_new = NULL;
|
||||
|
||||
mesh_new = new scene::SMesh();
|
||||
|
||||
if(fastfaces_new->getSize() > 0)
|
||||
if(fastfaces_new.size() > 0)
|
||||
{
|
||||
MeshCollector collector;
|
||||
|
||||
core::list<FastFace*>::Iterator i = fastfaces_new->begin();
|
||||
|
||||
for(; i != fastfaces_new->end(); i++)
|
||||
for(u32 i=0; i<fastfaces_new.size(); i++)
|
||||
{
|
||||
FastFace *f = *i;
|
||||
FastFace &f = fastfaces_new[i];
|
||||
|
||||
const u16 indices[] = {0,1,2,2,3,0};
|
||||
|
||||
if(f->tile.feature == TILEFEAT_NONE)
|
||||
if(f.tile.feature == TILEFEAT_NONE)
|
||||
{
|
||||
collector.append(g_tile_materials[f->tile.id], f->vertices, 4,
|
||||
collector.append(g_tile_materials[f.tile.id], f.vertices, 4,
|
||||
indices, 6);
|
||||
}
|
||||
else
|
||||
@ -569,7 +666,7 @@ void MapBlock::updateMesh(u32 daylight_factor)
|
||||
collector.fillMesh(mesh_new);
|
||||
|
||||
// Use VBO for mesh (this just would set this for ever buffer)
|
||||
mesh_new->setHardwareMappingHint(scene::EHM_STATIC);
|
||||
//mesh_new->setHardwareMappingHint(scene::EHM_STATIC);
|
||||
|
||||
/*std::cout<<"MapBlock has "<<fastfaces_new->getSize()<<" faces "
|
||||
<<"and uses "<<mesh_new->getMeshBufferCount()
|
||||
@ -580,14 +677,14 @@ void MapBlock::updateMesh(u32 daylight_factor)
|
||||
Clear temporary FastFaces
|
||||
*/
|
||||
|
||||
core::list<FastFace*>::Iterator i;
|
||||
/*core::list<FastFace*>::Iterator i;
|
||||
i = fastfaces_new->begin();
|
||||
for(; i != fastfaces_new->end(); i++)
|
||||
{
|
||||
delete *i;
|
||||
}
|
||||
fastfaces_new->clear();
|
||||
delete fastfaces_new;
|
||||
delete fastfaces_new;*/
|
||||
|
||||
/*
|
||||
Add special graphics:
|
||||
@ -697,8 +794,10 @@ void MapBlock::updateMesh(u32 daylight_factor)
|
||||
|
||||
mesh_mutex.Lock();
|
||||
|
||||
scene::SMesh *mesh_old = mesh;
|
||||
//scene::SMesh *mesh_old = mesh[daynight_i];
|
||||
//mesh[daynight_i] = mesh_new;
|
||||
|
||||
scene::SMesh *mesh_old = mesh;
|
||||
mesh = mesh_new;
|
||||
setMeshExpired(false);
|
||||
|
||||
@ -711,8 +810,20 @@ void MapBlock::updateMesh(u32 daylight_factor)
|
||||
{
|
||||
IMeshBuffer *buf = mesh_old->getMeshBuffer(i);
|
||||
}*/
|
||||
|
||||
/*dstream<<"mesh_old->getReferenceCount()="
|
||||
<<mesh_old->getReferenceCount()<<std::endl;
|
||||
u32 c = mesh_old->getMeshBufferCount();
|
||||
for(u32 i=0; i<c; i++)
|
||||
{
|
||||
scene::IMeshBuffer *buf = mesh_old->getMeshBuffer(i);
|
||||
dstream<<"buf->getReferenceCount()="
|
||||
<<buf->getReferenceCount()<<std::endl;
|
||||
}*/
|
||||
|
||||
// Drop the mesh
|
||||
mesh_old->drop();
|
||||
|
||||
//delete mesh_old;
|
||||
}
|
||||
|
||||
@ -721,6 +832,18 @@ void MapBlock::updateMesh(u32 daylight_factor)
|
||||
//std::cout<<"added "<<fastfaces.getSize()<<" faces."<<std::endl;
|
||||
}
|
||||
|
||||
/*void MapBlock::updateMeshes(s32 first_i)
|
||||
{
|
||||
assert(first_i >= 0 && first_i <= DAYNIGHT_CACHE_COUNT);
|
||||
updateMesh(first_i);
|
||||
for(s32 i=0; i<DAYNIGHT_CACHE_COUNT; i++)
|
||||
{
|
||||
if(i == first_i)
|
||||
continue;
|
||||
updateMesh(i);
|
||||
}
|
||||
}*/
|
||||
|
||||
/*
|
||||
Propagates sunlight down through the block.
|
||||
Doesn't modify nodes that are not affected by sunlight.
|
||||
@ -874,6 +997,54 @@ void MapBlock::copyTo(VoxelManipulator &dst)
|
||||
{
|
||||
}*/
|
||||
|
||||
|
||||
void MapBlock::updateDayNightDiff()
|
||||
{
|
||||
if(data == NULL)
|
||||
{
|
||||
m_day_night_differs = false;
|
||||
return;
|
||||
}
|
||||
|
||||
bool differs = false;
|
||||
|
||||
/*
|
||||
Check if any lighting value differs
|
||||
*/
|
||||
for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
|
||||
{
|
||||
MapNode &n = data[i];
|
||||
if(n.getLight(LIGHTBANK_DAY) != n.getLight(LIGHTBANK_NIGHT))
|
||||
{
|
||||
differs = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
If some lighting values differ, check if the whole thing is
|
||||
just air. If it is, differ = false
|
||||
*/
|
||||
if(differs)
|
||||
{
|
||||
bool only_air = true;
|
||||
for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
|
||||
{
|
||||
MapNode &n = data[i];
|
||||
if(n.d != CONTENT_AIR)
|
||||
{
|
||||
only_air = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(only_air)
|
||||
differs = false;
|
||||
}
|
||||
|
||||
// Set member variable
|
||||
m_day_night_differs = differs;
|
||||
}
|
||||
|
||||
/*
|
||||
Serialization
|
||||
*/
|
||||
@ -948,7 +1119,12 @@ void MapBlock::serialize(std::ostream &os, u8 version)
|
||||
else
|
||||
{
|
||||
// First byte
|
||||
os.write((char*)&is_underground, 1);
|
||||
u8 flags = 0;
|
||||
if(is_underground)
|
||||
flags |= 1;
|
||||
if(m_day_night_differs)
|
||||
flags |= 2;
|
||||
os.write((char*)&flags, 1);
|
||||
|
||||
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||
|
||||
@ -1065,9 +1241,10 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
|
||||
{
|
||||
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||
|
||||
u8 t8;
|
||||
is.read((char*)&t8, 1);
|
||||
is_underground = t8;
|
||||
u8 flags;
|
||||
is.read((char*)&flags, 1);
|
||||
is_underground = (flags & 1) ? true : false;
|
||||
m_day_night_differs = (flags & 2) ? true : false;
|
||||
|
||||
// Uncompress data
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
|
@ -89,51 +89,12 @@ class MapBlock : public NodeContainer
|
||||
{
|
||||
public:
|
||||
|
||||
/*
|
||||
This used by Server's block creation stuff for not sending
|
||||
blocks that are waiting a lighting update.
|
||||
|
||||
If true, the block needs some work by the one who set this
|
||||
to true.
|
||||
|
||||
While true, nobody else should touch the block.
|
||||
*/
|
||||
//bool is_incomplete;
|
||||
|
||||
//scene::SMesh *mesh[DAYNIGHT_CACHE_COUNT];
|
||||
scene::SMesh *mesh;
|
||||
JMutex mesh_mutex;
|
||||
|
||||
MapBlock(NodeContainer *parent, v3s16 pos, bool dummy=false):
|
||||
m_parent(parent),
|
||||
m_pos(pos),
|
||||
changed(true),
|
||||
is_underground(false),
|
||||
m_mesh_expired(false),
|
||||
m_objects(this)
|
||||
//is_incomplete(false)
|
||||
{
|
||||
data = NULL;
|
||||
if(dummy == false)
|
||||
reallocate();
|
||||
mesh_mutex.Init();
|
||||
mesh = NULL;
|
||||
}
|
||||
|
||||
~MapBlock()
|
||||
{
|
||||
{
|
||||
JMutexAutoLock lock(mesh_mutex);
|
||||
|
||||
if(mesh != NULL)
|
||||
{
|
||||
mesh->drop();
|
||||
mesh = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(data)
|
||||
delete[] data;
|
||||
}
|
||||
MapBlock(NodeContainer *parent, v3s16 pos, bool dummy=false);
|
||||
~MapBlock();
|
||||
|
||||
virtual u16 nodeContainerId() const
|
||||
{
|
||||
@ -302,6 +263,7 @@ public:
|
||||
bool isValidPositionParent(v3s16 p);
|
||||
MapNode getNodeParent(v3s16 p);
|
||||
void setNodeParent(v3s16 p, MapNode & n);
|
||||
MapNode getNodeParentNoEx(v3s16 p);
|
||||
|
||||
void drawbox(s16 x0, s16 y0, s16 z0, s16 w, s16 h, s16 d, MapNode node)
|
||||
{
|
||||
@ -311,13 +273,23 @@ public:
|
||||
setNode(x0+x, y0+y, z0+z, node);
|
||||
}
|
||||
|
||||
static FastFace * makeFastFace(TileSpec tile, u8 light, v3f p,
|
||||
v3s16 dir, v3f scale, v3f posRelative_f);
|
||||
static void makeFastFace(TileSpec tile, u8 light, v3f p,
|
||||
v3s16 dir, v3f scale, v3f posRelative_f,
|
||||
core::array<FastFace> &dest);
|
||||
|
||||
u8 getFaceLight(u32 daylight_factor, v3s16 p, v3s16 face_dir);
|
||||
u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
|
||||
v3s16 face_dir);
|
||||
|
||||
TileSpec getNodeTile(v3s16 p, v3s16 face_dir);
|
||||
u8 getNodeContent(v3s16 p);
|
||||
u8 getFaceLight(u32 daynight_ratio, v3s16 p, v3s16 face_dir)
|
||||
{
|
||||
return getFaceLight(daynight_ratio,
|
||||
getNodeParentNoEx(p),
|
||||
getNodeParentNoEx(p + face_dir),
|
||||
face_dir);
|
||||
}
|
||||
|
||||
TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir);
|
||||
u8 getNodeContent(v3s16 p, MapNode mn);
|
||||
|
||||
/*
|
||||
startpos:
|
||||
@ -325,14 +297,20 @@ public:
|
||||
face_dir: unit vector with only one of x, y or z
|
||||
*/
|
||||
void updateFastFaceRow(
|
||||
u32 daylight_factor,
|
||||
u32 daynight_ratio,
|
||||
v3f posRelative_f,
|
||||
v3s16 startpos,
|
||||
u16 length,
|
||||
v3s16 translate_dir,
|
||||
v3f translate_dir_f,
|
||||
v3s16 face_dir,
|
||||
core::list<FastFace*> &dest);
|
||||
v3f face_dir_f,
|
||||
core::array<FastFace> &dest);
|
||||
|
||||
void updateMesh(u32 daylight_factor);
|
||||
void updateMesh(u32 daynight_ratio);
|
||||
/*void updateMesh(s32 daynight_i);
|
||||
// Updates all DAYNIGHT_CACHE_COUNT meshes
|
||||
void updateMeshes(s32 first_i=0);*/
|
||||
|
||||
bool propagateSunlight(core::map<v3s16, bool> & light_sources);
|
||||
|
||||
@ -429,6 +407,21 @@ public:
|
||||
m_temp_mods.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
Day-night lighting difference
|
||||
|
||||
These methods don't care about neighboring blocks.
|
||||
It means that to know if a block really doesn't need a mesh
|
||||
update between day and night, the neighboring blocks have
|
||||
to be taken into account.
|
||||
*/
|
||||
void updateDayNightDiff();
|
||||
|
||||
bool dayNightDiffed()
|
||||
{
|
||||
return m_day_night_differs;
|
||||
}
|
||||
|
||||
/*
|
||||
Serialization
|
||||
*/
|
||||
@ -480,6 +473,9 @@ private:
|
||||
|
||||
bool m_mesh_expired;
|
||||
|
||||
// Whether day and night lighting differs
|
||||
bool m_day_night_differs;
|
||||
|
||||
MapBlockObjectList m_objects;
|
||||
|
||||
// Temporary modifications to nodes
|
||||
|
@ -339,17 +339,7 @@ void MapBlockObjectList::update(std::istream &is, u8 version,
|
||||
" id="<<id
|
||||
<<std::endl;*/
|
||||
|
||||
if(type_id == MAPBLOCKOBJECT_TYPE_TEST)
|
||||
{
|
||||
// The constructors of objects shouldn't need
|
||||
// any more parameters than this.
|
||||
obj = new TestObject(m_block, id, pos);
|
||||
}
|
||||
else if(type_id == MAPBLOCKOBJECT_TYPE_TEST2)
|
||||
{
|
||||
obj = new Test2Object(m_block, id, pos);
|
||||
}
|
||||
else if(type_id == MAPBLOCKOBJECT_TYPE_SIGN)
|
||||
if(type_id == MAPBLOCKOBJECT_TYPE_SIGN)
|
||||
{
|
||||
obj = new SignObject(m_block, id, pos);
|
||||
}
|
||||
|
@ -220,119 +220,6 @@ protected:
|
||||
};
|
||||
#endif
|
||||
|
||||
class TestObject : public MapBlockObject
|
||||
{
|
||||
public:
|
||||
// The constructor of every MapBlockObject should be like this
|
||||
TestObject(MapBlock *block, s16 id, v3f pos):
|
||||
MapBlockObject(block, id, pos),
|
||||
m_node(NULL)
|
||||
{
|
||||
}
|
||||
virtual ~TestObject()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
Implementation interface
|
||||
*/
|
||||
virtual u16 getTypeId() const
|
||||
{
|
||||
return MAPBLOCKOBJECT_TYPE_TEST;
|
||||
}
|
||||
virtual void serialize(std::ostream &os, u8 version)
|
||||
{
|
||||
serializeBase(os, version);
|
||||
|
||||
// Write subpos_c * 100
|
||||
u8 buf[2];
|
||||
writeU16(buf, m_subpos_c * 100);
|
||||
os.write((char*)buf, 2);
|
||||
}
|
||||
virtual void update(std::istream &is, u8 version)
|
||||
{
|
||||
// Read subpos_c * 100
|
||||
u8 buf[2];
|
||||
is.read((char*)buf, 2);
|
||||
m_subpos_c = (f32)readU16(buf) / 100;
|
||||
|
||||
updateNodePos();
|
||||
}
|
||||
virtual bool serverStep(float dtime)
|
||||
{
|
||||
m_subpos_c += dtime * 3.0;
|
||||
|
||||
updateNodePos();
|
||||
|
||||
return false;
|
||||
}
|
||||
virtual void addToScene(scene::ISceneManager *smgr)
|
||||
{
|
||||
if(m_node != NULL)
|
||||
return;
|
||||
|
||||
//dstream<<"Adding to scene"<<std::endl;
|
||||
|
||||
video::IVideoDriver* driver = smgr->getVideoDriver();
|
||||
|
||||
scene::SMesh *mesh = new scene::SMesh();
|
||||
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
||||
video::SColor c(255,255,255,255);
|
||||
video::S3DVertex vertices[4] =
|
||||
{
|
||||
video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
|
||||
video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
|
||||
video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
|
||||
video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
|
||||
};
|
||||
u16 indices[] = {0,1,2,2,3,0};
|
||||
buf->append(vertices, 4, indices, 6);
|
||||
// Set material
|
||||
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
|
||||
buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
|
||||
buf->getMaterial().setTexture
|
||||
(0, driver->getTexture("../data/player.png"));
|
||||
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
// Add to mesh
|
||||
mesh->addMeshBuffer(buf);
|
||||
buf->drop();
|
||||
m_node = smgr->addMeshSceneNode(mesh, NULL);
|
||||
mesh->drop();
|
||||
m_node->setPosition(getAbsolutePos());
|
||||
}
|
||||
virtual void removeFromScene()
|
||||
{
|
||||
//dstream<<"Removing from scene"<<std::endl;
|
||||
if(m_node != NULL)
|
||||
{
|
||||
m_node->remove();
|
||||
m_node = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Special methods
|
||||
*/
|
||||
|
||||
void updateNodePos()
|
||||
{
|
||||
m_subpos = BS*2.0 * v3f(sin(m_subpos_c), sin(m_subpos_c+1.0), sin(-m_subpos_c));
|
||||
|
||||
if(m_node != NULL)
|
||||
{
|
||||
m_node->setPosition(getAbsolutePos() + m_subpos);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
scene::IMeshSceneNode *m_node;
|
||||
std::string m_text;
|
||||
|
||||
v3f m_subpos;
|
||||
f32 m_subpos_c;
|
||||
};
|
||||
|
||||
class MovingObject : public MapBlockObject
|
||||
{
|
||||
public:
|
||||
@ -398,134 +285,6 @@ protected:
|
||||
bool m_touching_ground;
|
||||
};
|
||||
|
||||
class Test2Object : public MovingObject
|
||||
{
|
||||
public:
|
||||
// The constructor of every MapBlockObject should be like this
|
||||
Test2Object(MapBlock *block, s16 id, v3f pos):
|
||||
MovingObject(block, id, pos),
|
||||
m_node(NULL)
|
||||
{
|
||||
m_collision_box = new core::aabbox3d<f32>
|
||||
(-BS*0.3,0,-BS*0.3, BS*0.3,BS*1.7,BS*0.3);
|
||||
}
|
||||
virtual ~Test2Object()
|
||||
{
|
||||
delete m_collision_box;
|
||||
}
|
||||
|
||||
/*
|
||||
Implementation interface
|
||||
*/
|
||||
virtual u16 getTypeId() const
|
||||
{
|
||||
return MAPBLOCKOBJECT_TYPE_TEST2;
|
||||
}
|
||||
virtual void serialize(std::ostream &os, u8 version)
|
||||
{
|
||||
MovingObject::serialize(os, version);
|
||||
}
|
||||
virtual void update(std::istream &is, u8 version)
|
||||
{
|
||||
MovingObject::update(is, version);
|
||||
|
||||
updateNodePos();
|
||||
}
|
||||
|
||||
virtual bool serverStep(float dtime)
|
||||
{
|
||||
m_speed.X = 2*BS;
|
||||
m_speed.Z = 0;
|
||||
|
||||
if(m_touching_ground)
|
||||
{
|
||||
static float count = 0;
|
||||
count -= dtime;
|
||||
if(count < 0.0)
|
||||
{
|
||||
count += 1.0;
|
||||
m_speed.Y = 6.5*BS;
|
||||
}
|
||||
}
|
||||
|
||||
move(dtime, v3f(0, -9.81*BS, 0));
|
||||
|
||||
updateNodePos();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void clientStep(float dtime)
|
||||
{
|
||||
m_pos += m_speed * dtime;
|
||||
|
||||
updateNodePos();
|
||||
}
|
||||
|
||||
virtual void addToScene(scene::ISceneManager *smgr)
|
||||
{
|
||||
if(m_node != NULL)
|
||||
return;
|
||||
|
||||
//dstream<<"Adding to scene"<<std::endl;
|
||||
|
||||
video::IVideoDriver* driver = smgr->getVideoDriver();
|
||||
|
||||
scene::SMesh *mesh = new scene::SMesh();
|
||||
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
||||
video::SColor c(255,255,255,255);
|
||||
video::S3DVertex vertices[4] =
|
||||
{
|
||||
video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
|
||||
video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
|
||||
video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
|
||||
video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
|
||||
};
|
||||
u16 indices[] = {0,1,2,2,3,0};
|
||||
buf->append(vertices, 4, indices, 6);
|
||||
// Set material
|
||||
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
|
||||
buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
|
||||
buf->getMaterial().setTexture
|
||||
(0, driver->getTexture("../data/player.png"));
|
||||
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
// Add to mesh
|
||||
mesh->addMeshBuffer(buf);
|
||||
buf->drop();
|
||||
m_node = smgr->addMeshSceneNode(mesh, NULL);
|
||||
mesh->drop();
|
||||
m_node->setPosition(getAbsolutePos());
|
||||
}
|
||||
virtual void removeFromScene()
|
||||
{
|
||||
//dstream<<"Removing from scene"<<std::endl;
|
||||
if(m_node != NULL)
|
||||
{
|
||||
m_node->remove();
|
||||
m_node = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Special methods
|
||||
*/
|
||||
|
||||
void updateNodePos()
|
||||
{
|
||||
//m_subpos = BS*2.0 * v3f(sin(m_subpos_c), sin(m_subpos_c+1.0), sin(-m_subpos_c));
|
||||
|
||||
if(m_node != NULL)
|
||||
{
|
||||
//m_node->setPosition(getAbsolutePos() + m_subpos);
|
||||
m_node->setPosition(getAbsolutePos());
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
scene::IMeshSceneNode *m_node;
|
||||
};
|
||||
|
||||
class RatObject : public MovingObject
|
||||
{
|
||||
public:
|
||||
|
@ -43,7 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
8: (dev) server-initiated block transfers and all kinds of stuff
|
||||
9: (dev) block objects
|
||||
10: (dev) water pressure
|
||||
11: (dev) zlib'd blocks
|
||||
11: (dev) zlib'd blocks, block flags
|
||||
*/
|
||||
// This represents an uninitialized or invalid format
|
||||
#define SER_FMT_VER_INVALID 255
|
||||
|
@ -285,6 +285,12 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
|
||||
// Increment timers
|
||||
{
|
||||
JMutexAutoLock lock(m_blocks_sent_mutex);
|
||||
m_nearest_unsent_reset_timer += dtime;
|
||||
}
|
||||
|
||||
// Won't send anything if already sending
|
||||
{
|
||||
JMutexAutoLock lock(m_blocks_sending_mutex);
|
||||
@ -320,12 +326,13 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||
m_last_center = center;
|
||||
}
|
||||
|
||||
static float reset_counter = 0;
|
||||
reset_counter += dtime;
|
||||
if(reset_counter > 5.0)
|
||||
/*dstream<<"m_nearest_unsent_reset_timer="
|
||||
<<m_nearest_unsent_reset_timer<<std::endl;*/
|
||||
if(m_nearest_unsent_reset_timer > 5.0)
|
||||
{
|
||||
reset_counter = 0;
|
||||
m_nearest_unsent_reset_timer = 0;
|
||||
m_nearest_unsent_d = 0;
|
||||
//dstream<<"Resetting m_nearest_unsent_d"<<std::endl;
|
||||
}
|
||||
|
||||
last_nearest_unsent_d = m_nearest_unsent_d;
|
||||
@ -353,6 +360,21 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||
= LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS;
|
||||
}
|
||||
}
|
||||
|
||||
u32 num_blocks_selected;
|
||||
{
|
||||
JMutexAutoLock lock(m_blocks_sending_mutex);
|
||||
num_blocks_selected = m_blocks_sending.size();
|
||||
}
|
||||
|
||||
/*
|
||||
next time d will be continued from the d from which the nearest
|
||||
unsent block was found this time.
|
||||
|
||||
This is because not necessarily any of the blocks found this
|
||||
time are actually sent.
|
||||
*/
|
||||
s32 new_nearest_unsent_d = -1;
|
||||
|
||||
// Serialization version used
|
||||
//u8 ser_version = serialization_version;
|
||||
@ -380,12 +402,8 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||
if(m_nearest_unsent_d != last_nearest_unsent_d)
|
||||
{
|
||||
d = m_nearest_unsent_d;
|
||||
last_nearest_unsent_d = m_nearest_unsent_d;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nearest_unsent_d = d;
|
||||
}
|
||||
last_nearest_unsent_d = m_nearest_unsent_d;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -421,13 +439,13 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||
JMutexAutoLock lock(m_blocks_sending_mutex);
|
||||
|
||||
// Limit is dynamically lowered when building
|
||||
if(m_blocks_sending.size()
|
||||
if(num_blocks_selected
|
||||
>= maximum_simultaneous_block_sends_now)
|
||||
{
|
||||
/*dstream<<"Not sending more blocks. Queue full. "
|
||||
<<m_blocks_sending.size()
|
||||
<<std::endl;*/
|
||||
return;
|
||||
goto queue_full;
|
||||
}
|
||||
|
||||
if(m_blocks_sending.find(p) != NULL)
|
||||
@ -460,7 +478,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||
if(m_blocks_sent.find(p) != NULL)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Check if map has this block
|
||||
*/
|
||||
@ -498,6 +516,15 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
Record the lowest d from which a a block has been
|
||||
found being not sent and possibly to exist
|
||||
*/
|
||||
if(new_nearest_unsent_d == -1 || d < new_nearest_unsent_d)
|
||||
{
|
||||
new_nearest_unsent_d = d;
|
||||
}
|
||||
|
||||
/*
|
||||
Add inexistent block to emerge queue.
|
||||
*/
|
||||
@ -531,10 +558,17 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||
PrioritySortedBlockTransfer q((float)d, p, peer_id);
|
||||
|
||||
dest.push_back(q);
|
||||
|
||||
num_blocks_selected += 1;
|
||||
}
|
||||
}
|
||||
queue_full:
|
||||
|
||||
// Don't add anything here. The loop breaks by returning.
|
||||
if(new_nearest_unsent_d != -1)
|
||||
{
|
||||
JMutexAutoLock lock(m_blocks_sent_mutex);
|
||||
m_nearest_unsent_d = new_nearest_unsent_d;
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteClient::SendObjectData(
|
||||
@ -894,6 +928,12 @@ Server::Server(
|
||||
m_thread(this),
|
||||
m_emergethread(this)
|
||||
{
|
||||
m_flowwater_timer = 0.0;
|
||||
m_print_info_timer = 0.0;
|
||||
m_objectdata_timer = 0.0;
|
||||
m_emergethread_trigger_timer = 0.0;
|
||||
m_savemap_timer = 0.0;
|
||||
|
||||
m_env_mutex.Init();
|
||||
m_con_mutex.Init();
|
||||
m_step_dtime_mutex.Init();
|
||||
@ -983,7 +1023,7 @@ void Server::AsyncRunStep()
|
||||
|
||||
{
|
||||
JMutexAutoLock lock1(m_step_dtime_mutex);
|
||||
m_step_dtime = 0.0;
|
||||
m_step_dtime -= dtime;
|
||||
}
|
||||
|
||||
//dstream<<"Server steps "<<dtime<<std::endl;
|
||||
@ -1018,7 +1058,7 @@ void Server::AsyncRunStep()
|
||||
else
|
||||
interval = 0.25;
|
||||
|
||||
static float counter = 0.0;
|
||||
float &counter = m_flowwater_timer;
|
||||
counter += dtime;
|
||||
if(counter >= 0.25 && m_flow_active_nodes.size() > 0)
|
||||
{
|
||||
@ -1082,7 +1122,7 @@ void Server::AsyncRunStep()
|
||||
|
||||
// Periodically print some info
|
||||
{
|
||||
static float counter = 0.0;
|
||||
float &counter = m_print_info_timer;
|
||||
counter += dtime;
|
||||
if(counter >= 30.0)
|
||||
{
|
||||
@ -1208,7 +1248,7 @@ void Server::AsyncRunStep()
|
||||
|
||||
// Send object positions
|
||||
{
|
||||
static float counter = 0.0;
|
||||
float &counter = m_objectdata_timer;
|
||||
counter += dtime;
|
||||
if(counter >= g_settings.getFloat("objectdata_interval"))
|
||||
{
|
||||
@ -1223,7 +1263,7 @@ void Server::AsyncRunStep()
|
||||
// Trigger emergethread (it gets somehow gets to a
|
||||
// non-triggered but bysy state sometimes)
|
||||
{
|
||||
static float counter = 0.0;
|
||||
float &counter = m_emergethread_trigger_timer;
|
||||
counter += dtime;
|
||||
if(counter >= 2.0)
|
||||
{
|
||||
@ -1235,7 +1275,7 @@ void Server::AsyncRunStep()
|
||||
|
||||
// Save map
|
||||
{
|
||||
static float counter = 0.0;
|
||||
float &counter = m_savemap_timer;
|
||||
counter += dtime;
|
||||
if(counter >= SERVER_MAP_SAVE_INTERVAL)
|
||||
{
|
||||
@ -1589,14 +1629,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||
if(action == 0)
|
||||
{
|
||||
|
||||
u8 material;
|
||||
u8 content;
|
||||
|
||||
try
|
||||
{
|
||||
// Get material at position
|
||||
material = m_env.getMap().getNode(p_under).d;
|
||||
// Get content at position
|
||||
content = m_env.getMap().getNode(p_under).d;
|
||||
// If it's not diggable, do nothing
|
||||
if(content_diggable(material) == false)
|
||||
if(content_diggable(content) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -1615,7 +1655,16 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||
JMutexAutoLock(client->m_dig_mutex);
|
||||
client->m_dig_tool_item = 0;
|
||||
client->m_dig_position = p_under;
|
||||
client->m_dig_time_remaining = 1.0;
|
||||
float dig_time = 0.5;
|
||||
if(content == CONTENT_STONE)
|
||||
{
|
||||
dig_time = 1.5;
|
||||
}
|
||||
else if(content == CONTENT_TORCH)
|
||||
{
|
||||
dig_time = 0.0;
|
||||
}
|
||||
client->m_dig_time_remaining = dig_time;
|
||||
|
||||
// Reset build time counter
|
||||
getClient(peer->id)->m_time_from_building.set(0.0);
|
||||
|
47
src/server.h
47
src/server.h
@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "environment.h"
|
||||
#include "common_irrlicht.h"
|
||||
#include <string>
|
||||
#include "utility.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
@ -146,44 +147,6 @@ private:
|
||||
JMutex m_mutex;
|
||||
};
|
||||
|
||||
class SimpleThread : public JThread
|
||||
{
|
||||
bool run;
|
||||
JMutex run_mutex;
|
||||
|
||||
public:
|
||||
|
||||
SimpleThread():
|
||||
JThread(),
|
||||
run(true)
|
||||
{
|
||||
run_mutex.Init();
|
||||
}
|
||||
|
||||
virtual ~SimpleThread()
|
||||
{}
|
||||
|
||||
virtual void * Thread() = 0;
|
||||
|
||||
bool getRun()
|
||||
{
|
||||
JMutexAutoLock lock(run_mutex);
|
||||
return run;
|
||||
}
|
||||
void setRun(bool a_run)
|
||||
{
|
||||
JMutexAutoLock lock(run_mutex);
|
||||
run = a_run;
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
setRun(false);
|
||||
while(IsRunning())
|
||||
sleep_ms(100);
|
||||
}
|
||||
};
|
||||
|
||||
class Server;
|
||||
|
||||
class ServerThread : public SimpleThread
|
||||
@ -281,6 +244,7 @@ public:
|
||||
serialization_version = SER_FMT_VER_INVALID;
|
||||
pending_serialization_version = SER_FMT_VER_INVALID;
|
||||
m_nearest_unsent_d = 0;
|
||||
m_nearest_unsent_reset_timer = 0.0;
|
||||
|
||||
m_blocks_sent_mutex.Init();
|
||||
m_blocks_sending_mutex.Init();
|
||||
@ -384,6 +348,7 @@ private:
|
||||
core::map<v3s16, bool> m_blocks_sent;
|
||||
s16 m_nearest_unsent_d;
|
||||
v3s16 m_last_center;
|
||||
float m_nearest_unsent_reset_timer;
|
||||
JMutex m_blocks_sent_mutex;
|
||||
/*
|
||||
Blocks that are currently on the line.
|
||||
@ -467,6 +432,12 @@ private:
|
||||
void UpdateBlockWaterPressure(MapBlock *block,
|
||||
core::map<v3s16, MapBlock*> &modified_blocks);
|
||||
|
||||
float m_flowwater_timer;
|
||||
float m_print_info_timer;
|
||||
float m_objectdata_timer;
|
||||
float m_emergethread_trigger_timer;
|
||||
float m_savemap_timer;
|
||||
|
||||
// NOTE: If connection and environment are both to be locked,
|
||||
// environment shall be locked first.
|
||||
JMutex m_env_mutex;
|
||||
|
@ -56,7 +56,7 @@ void tile_materials_preload(TextureCache &cache)
|
||||
g_tile_materials[i].setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||
g_tile_materials[i].setFlag(video::EMF_ANTI_ALIASING, video::EAAM_OFF);
|
||||
//if(i != TILE_WATER)
|
||||
//g_tile_materials[i].setFlag(video::EMF_FOG_ENABLE, true);
|
||||
g_tile_materials[i].setFlag(video::EMF_FOG_ENABLE, true);
|
||||
|
||||
//g_tile_materials[i].setFlag(video::EMF_TEXTURE_WRAP, video::ETC_REPEAT);
|
||||
//g_tile_materials[i].setFlag(video::EMF_ANISOTROPIC_FILTER, false);
|
||||
|
@ -28,9 +28,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <jthread.h>
|
||||
#include <jmutex.h>
|
||||
#include <jmutexautolock.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#define sleep_ms(x) Sleep(x)
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#define sleep_ms(x) usleep(x*1000)
|
||||
#endif
|
||||
|
||||
#include "common_irrlicht.h"
|
||||
#include "debug.h"
|
||||
#include "strfnd.h"
|
||||
@ -1100,5 +1109,43 @@ private:
|
||||
JMutex m_mutex;
|
||||
};
|
||||
|
||||
class SimpleThread : public JThread
|
||||
{
|
||||
bool run;
|
||||
JMutex run_mutex;
|
||||
|
||||
public:
|
||||
|
||||
SimpleThread():
|
||||
JThread(),
|
||||
run(true)
|
||||
{
|
||||
run_mutex.Init();
|
||||
}
|
||||
|
||||
virtual ~SimpleThread()
|
||||
{}
|
||||
|
||||
virtual void * Thread() = 0;
|
||||
|
||||
bool getRun()
|
||||
{
|
||||
JMutexAutoLock lock(run_mutex);
|
||||
return run;
|
||||
}
|
||||
void setRun(bool a_run)
|
||||
{
|
||||
JMutexAutoLock lock(run_mutex);
|
||||
run = a_run;
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
setRun(false);
|
||||
while(IsRunning())
|
||||
sleep_ms(100);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -741,11 +741,6 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
|
||||
|
||||
m_data[m_area.index(removed_pos)].setLightBanks(light);
|
||||
|
||||
/*// NOTE: HACK: This has to be set to LIGHT_MAX so that
|
||||
// unspreadLight will clear all light that came from this node.
|
||||
// Otherwise there will be weird bugs
|
||||
m_data[m_area.index(removed_pos)].setLight(LIGHT_MAX);*/
|
||||
|
||||
// Mark removed_pos checked
|
||||
m_flags[m_area.index(removed_pos)] |= VOXELFLAG_CHECKED;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user