day/night working client side
This commit is contained in:
parent
240499dc2c
commit
0ca9423b8b
|
@ -23,6 +23,8 @@
|
||||||
#random_input = false
|
#random_input = false
|
||||||
#client_delete_unused_sectors_timeout = 1200
|
#client_delete_unused_sectors_timeout = 1200
|
||||||
|
|
||||||
|
#enable_fog = true
|
||||||
|
|
||||||
# Server side stuff
|
# Server side stuff
|
||||||
|
|
||||||
# - The possible generators are:
|
# - The possible generators are:
|
||||||
|
@ -51,8 +53,8 @@
|
||||||
#max_simultaneous_block_sends_per_client = 1
|
#max_simultaneous_block_sends_per_client = 1
|
||||||
#max_simultaneous_block_sends_server_total = 4
|
#max_simultaneous_block_sends_server_total = 4
|
||||||
|
|
||||||
#max_block_send_distance = 8
|
#max_block_send_distance = 5
|
||||||
#max_block_generate_distance = 6
|
#max_block_generate_distance = 4
|
||||||
|
|
||||||
#disable_water_climb = true
|
#disable_water_climb = true
|
||||||
# Note that this gets applied at map generation time
|
# 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->asyncStep();
|
||||||
|
|
||||||
|
//m_client->updateSomeExpiredMeshes();
|
||||||
|
|
||||||
bool was = m_client->AsyncProcessData();
|
bool was = m_client->AsyncProcessData();
|
||||||
|
|
||||||
if(was == false)
|
if(was == false)
|
||||||
|
@ -84,7 +86,15 @@ Client::Client(IrrlichtDevice *device,
|
||||||
m_inventory_updated(false),
|
m_inventory_updated(false),
|
||||||
m_time(0),
|
m_time(0),
|
||||||
m_time_counter(0.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_fetchblock_mutex.Init();
|
||||||
m_incoming_queue_mutex.Init();
|
m_incoming_queue_mutex.Init();
|
||||||
m_env_mutex.Init();
|
m_env_mutex.Init();
|
||||||
|
@ -154,14 +164,41 @@ void Client::step(float dtime)
|
||||||
m_time += seconds;
|
m_time += seconds;
|
||||||
if(seconds > 0)
|
if(seconds > 0)
|
||||||
{
|
{
|
||||||
dstream<<"m_time="<<m_time<<std::endl;
|
//dstream<<"m_time="<<m_time<<std::endl;
|
||||||
JMutexAutoLock envlock(m_env_mutex);
|
/*JMutexAutoLock envlock(m_env_mutex);
|
||||||
u32 dr = 500+500*sin((float)((m_time/10)%7)/7.*2.*PI);
|
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;
|
dstream<<"dr="<<dr<<std::endl;
|
||||||
m_env.setDaylightRatio(dr);
|
m_env.setDayNightRatio(dr);
|
||||||
m_env.expireMeshes();
|
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
|
Packet counter
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
static float counter = -0.001;
|
float &counter = m_packetcounter_timer;
|
||||||
counter -= dtime;
|
counter -= dtime;
|
||||||
if(counter <= 0.0)
|
if(counter <= 0.0)
|
||||||
{
|
{
|
||||||
|
@ -206,12 +243,13 @@ void Client::step(float dtime)
|
||||||
clear caches
|
clear caches
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static float counter = -0.001;
|
float &counter = m_delete_unused_sectors_timer;
|
||||||
counter -= dtime;
|
counter -= dtime;
|
||||||
if(counter <= 0.0)
|
if(counter <= 0.0)
|
||||||
{
|
{
|
||||||
// 3 minute interval
|
// 3 minute interval
|
||||||
counter = 180.0;
|
//counter = 180.0;
|
||||||
|
counter = 60.0;
|
||||||
|
|
||||||
JMutexAutoLock lock(m_env_mutex);
|
JMutexAutoLock lock(m_env_mutex);
|
||||||
|
|
||||||
|
@ -290,7 +328,7 @@ void Client::step(float dtime)
|
||||||
|
|
||||||
if(connected == false)
|
if(connected == false)
|
||||||
{
|
{
|
||||||
static float counter = -0.001;
|
float &counter = m_connection_reinit_timer;
|
||||||
counter -= dtime;
|
counter -= dtime;
|
||||||
if(counter <= 0.0)
|
if(counter <= 0.0)
|
||||||
{
|
{
|
||||||
|
@ -354,12 +392,7 @@ void Client::step(float dtime)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Fetch some nearby blocks
|
float &counter = m_avg_rtt_timer;
|
||||||
//fetchBlocks();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
static float counter = 0.0;
|
|
||||||
counter += dtime;
|
counter += dtime;
|
||||||
if(counter >= 10)
|
if(counter >= 10)
|
||||||
{
|
{
|
||||||
|
@ -371,8 +404,7 @@ void Client::step(float dtime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Update at reasonable intervals (0.2s)
|
float &counter = m_playerpos_send_timer;
|
||||||
static float counter = 0.0;
|
|
||||||
counter += dtime;
|
counter += dtime;
|
||||||
if(counter >= 0.2)
|
if(counter >= 0.2)
|
||||||
{
|
{
|
||||||
|
@ -1121,7 +1153,7 @@ bool Client::AsyncProcessPacket(LazyMeshUpdater &mesh_updater)
|
||||||
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
|
<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
|
||||||
|
|
||||||
/*dstream<<DTIME<<"Client: Thread: BLOCKDATA for ("
|
/*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::string datastring((char*)&data[8], datasize-8);
|
||||||
std::istringstream istr(datastring, std::ios_base::binary);
|
std::istringstream istr(datastring, std::ios_base::binary);
|
||||||
|
@ -1780,9 +1812,71 @@ void Client::printDebugInfo(std::ostream &os)
|
||||||
<<std::endl;
|
<<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);
|
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 Client;
|
||||||
|
|
||||||
class ClientUpdateThread : public JThread
|
class ClientUpdateThread : public SimpleThread
|
||||||
{
|
{
|
||||||
bool run;
|
|
||||||
JMutex run_mutex;
|
|
||||||
|
|
||||||
Client *m_client;
|
Client *m_client;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ClientUpdateThread(Client *client) : JThread(), run(true), m_client(client)
|
ClientUpdateThread(Client *client):
|
||||||
|
SimpleThread(),
|
||||||
|
m_client(client)
|
||||||
{
|
{
|
||||||
run_mutex.Init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void * Thread();
|
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
|
struct IncomingPacket
|
||||||
|
@ -98,6 +82,7 @@ struct IncomingPacket
|
||||||
if(*m_refcount == 0){
|
if(*m_refcount == 0){
|
||||||
if(m_data != NULL)
|
if(m_data != NULL)
|
||||||
delete[] m_data;
|
delete[] m_data;
|
||||||
|
delete m_refcount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,7 +222,10 @@ public:
|
||||||
// Prints a line or two of info
|
// Prints a line or two of info
|
||||||
void printDebugInfo(std::ostream &os);
|
void printDebugInfo(std::ostream &os);
|
||||||
|
|
||||||
float getDaylightRatio();
|
//s32 getDayNightIndex();
|
||||||
|
u32 getDayNightRatio();
|
||||||
|
|
||||||
|
//void updateSomeExpiredMeshes();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -252,6 +240,12 @@ private:
|
||||||
// This sends the player's current name etc to the server
|
// This sends the player's current name etc to the server
|
||||||
void sendPlayerInfo();
|
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;
|
ClientUpdateThread m_thread;
|
||||||
|
|
||||||
// NOTE: If connection and environment are both to be locked,
|
// NOTE: If connection and environment are both to be locked,
|
||||||
|
@ -290,6 +284,10 @@ private:
|
||||||
// Access these only in main thread.
|
// Access these only in main thread.
|
||||||
u32 m_time;
|
u32 m_time;
|
||||||
float m_time_counter;
|
float m_time_counter;
|
||||||
|
|
||||||
|
// 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
|
||||||
|
//s32 m_daynight_i;
|
||||||
|
//u32 m_daynight_ratio;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -445,6 +445,7 @@ Peer::Peer(u16 a_id, Address a_address)
|
||||||
address = a_address;
|
address = a_address;
|
||||||
timeout_counter = 0.0;
|
timeout_counter = 0.0;
|
||||||
//resend_timeout = RESEND_TIMEOUT_MINIMUM;
|
//resend_timeout = RESEND_TIMEOUT_MINIMUM;
|
||||||
|
ping_timer = 0.0;
|
||||||
resend_timeout = 0.5;
|
resend_timeout = 0.5;
|
||||||
avg_rtt = -1.0;
|
avg_rtt = -1.0;
|
||||||
has_sent_with_id = false;
|
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 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 SERVER_MAP_SAVE_INTERVAL (60)
|
||||||
/*#define SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT (10)
|
/*#define SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT (10)
|
||||||
#define SERVER_MAP_SAVE_INTERVAL (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.5)
|
||||||
//#define FOV_ANGLE (PI/2.25)
|
|
||||||
|
|
||||||
// The absolute working limit is (2^15 - viewing_range).
|
// The absolute working limit is (2^15 - viewing_range).
|
||||||
#define MAP_GENERATION_LIMIT (31000)
|
#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 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
|
#define LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS 0
|
||||||
|
// Override for the previous one when distance of block
|
||||||
// Override for the previous one when distance is low
|
// is very low
|
||||||
#define BLOCK_SEND_DISABLE_LIMITS_MAX_D 1
|
#define BLOCK_SEND_DISABLE_LIMITS_MAX_D 1
|
||||||
|
|
||||||
//#define MAX_SIMULTANEOUS_BLOCK_SENDS_SERVER_TOTAL 4
|
|
||||||
|
|
||||||
// Viewing range stuff
|
// Viewing range stuff
|
||||||
|
|
||||||
//#define HEIGHTMAP_RANGE_NODES 300
|
|
||||||
|
|
||||||
//#define FREETIME_RATIO 0.2
|
//#define FREETIME_RATIO 0.2
|
||||||
#define FREETIME_RATIO 0.15
|
#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
|
#define SIGN_TEXT_MAX_LENGTH 50
|
||||||
|
|
||||||
// The distance of how far objects will be sent to client
|
// Whether to catch all std::exceptions.
|
||||||
//#define ACTIVE_OBJECT_D_BLOCKS 2
|
|
||||||
|
|
||||||
// Wether to catch all std::exceptions.
|
|
||||||
// Assert will be called on such an event.
|
// Assert will be called on such an event.
|
||||||
#define CATCH_UNHANDLED_EXCEPTIONS 1
|
#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 MAX_OBJECTDATA_SIZE 450
|
||||||
|
|
||||||
//#define WATER_LEVEL (-5)
|
|
||||||
#define WATER_LEVEL (0)
|
#define WATER_LEVEL (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,7 +24,7 @@ Environment::Environment(Map *map, std::ostream &dout):
|
||||||
m_dout(dout)
|
m_dout(dout)
|
||||||
{
|
{
|
||||||
m_map = map;
|
m_map = map;
|
||||||
m_daylight_ratio = 0.2;
|
m_daynight_ratio = 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
Environment::~Environment()
|
Environment::~Environment()
|
||||||
|
@ -36,7 +36,9 @@ Environment::~Environment()
|
||||||
delete (*i);
|
delete (*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete m_map;
|
// The map is removed by the SceneManager
|
||||||
|
m_map->drop();
|
||||||
|
//delete m_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::step(float dtime)
|
void Environment::step(float dtime)
|
||||||
|
@ -153,7 +155,7 @@ void Environment::step(float dtime)
|
||||||
{
|
{
|
||||||
v3s16 p_blocks = getNodeBlockPos(bottompos);
|
v3s16 p_blocks = getNodeBlockPos(bottompos);
|
||||||
MapBlock *b = m_map->getBlockNoCreate(p_blocks);
|
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)
|
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 printPlayers(std::ostream &o);
|
||||||
|
|
||||||
void updateMeshes(v3s16 blockpos);
|
void updateMeshes(v3s16 blockpos);
|
||||||
void expireMeshes();
|
void expireMeshes(bool only_daynight_diffed);
|
||||||
void setDaylightRatio(u32 r);
|
void setDayNightRatio(u32 r);
|
||||||
u32 getDaylightRatio();
|
u32 getDayNightRatio();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Map *m_map;
|
Map *m_map;
|
||||||
core::list<Player*> m_players;
|
core::list<Player*> m_players;
|
||||||
// Debug output goes here
|
// Debug output goes here
|
||||||
std::ostream &m_dout;
|
std::ostream &m_dout;
|
||||||
u32 m_daylight_ratio;
|
u32 m_daynight_ratio;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,6 +19,67 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
#include "light.h"
|
#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
|
// LIGHT_MAX is 14, 0-14 is 15 values
|
||||||
/*u8 light_decode_table[LIGHT_MAX+1] =
|
/*u8 light_decode_table[LIGHT_MAX+1] =
|
||||||
{
|
{
|
||||||
|
@ -38,24 +99,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
191,
|
191,
|
||||||
255,
|
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
|
#if 0
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -22,6 +22,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
#include "common_irrlicht.h"
|
#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
|
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: A way to generate new textures by combining textures
|
||||||
- TODO: Mesh update to fetch cracked faces from the former
|
- TODO: Mesh update to fetch cracked faces from the former
|
||||||
|
|
||||||
|
TODO: Add server unused sector deletion settings to settings
|
||||||
|
|
||||||
|
TODO: TOSERVER_LEAVE
|
||||||
|
|
||||||
Doing now:
|
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("name", "");
|
||||||
g_settings.setDefault("random_input", "false");
|
g_settings.setDefault("random_input", "false");
|
||||||
g_settings.setDefault("client_delete_unused_sectors_timeout", "1200");
|
g_settings.setDefault("client_delete_unused_sectors_timeout", "1200");
|
||||||
g_settings.setDefault("max_block_send_distance", "8");
|
g_settings.setDefault("enable_fog", "true");
|
||||||
g_settings.setDefault("max_block_generate_distance", "6");
|
|
||||||
|
|
||||||
// Server stuff
|
// Server stuff
|
||||||
g_settings.setDefault("creative_mode", "false");
|
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("max_simultaneous_block_sends_server_total", "4");
|
||||||
g_settings.setDefault("disable_water_climb", "true");
|
g_settings.setDefault("disable_water_climb", "true");
|
||||||
g_settings.setDefault("endless_water", "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
|
// Initialize to the target value
|
||||||
static float frametime_avg = 1.0/wanted_fps;
|
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;
|
static f32 counter = 0;
|
||||||
if(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);
|
||||||
|
|
||||||
|
/*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;
|
static bool fraction_is_good = false;
|
||||||
|
|
||||||
float fraction_good_threshold = 0.1;
|
float fraction_good_threshold = 0.1;
|
||||||
|
@ -1048,9 +1054,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Parse command line
|
Parse command line
|
||||||
TODO
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// List all allowed options
|
||||||
core::map<std::string, ValueSpec> allowed_options;
|
core::map<std::string, ValueSpec> allowed_options;
|
||||||
allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG));
|
allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG));
|
||||||
allowed_options.insert("server", 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,
|
allowed_options.insert("config", ValueSpec(VALUETYPE_STRING,
|
||||||
"Load configuration from specified file"));
|
"Load configuration from specified file"));
|
||||||
allowed_options.insert("port", ValueSpec(VALUETYPE_STRING));
|
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;
|
Settings cmd_args;
|
||||||
|
|
||||||
|
@ -1116,14 +1126,6 @@ int main(int argc, char *argv[])
|
||||||
// Initialize timestamp mutex
|
// Initialize timestamp mutex
|
||||||
g_timestamp_mutex.Init();
|
g_timestamp_mutex.Init();
|
||||||
|
|
||||||
/*
|
|
||||||
Run unit tests
|
|
||||||
*/
|
|
||||||
if(ENABLE_TESTS)
|
|
||||||
{
|
|
||||||
run_tests();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Initialization
|
Initialization
|
||||||
*/
|
*/
|
||||||
|
@ -1168,6 +1170,18 @@ int main(int argc, char *argv[])
|
||||||
// Initialize random seed
|
// Initialize random seed
|
||||||
srand(time(0));
|
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();
|
g_range_mutex.Init();
|
||||||
assert(g_range_mutex.IsInitialized());
|
assert(g_range_mutex.IsInitialized());
|
||||||
|
|
||||||
|
@ -1263,14 +1277,18 @@ int main(int argc, char *argv[])
|
||||||
bool hosting = false;
|
bool hosting = false;
|
||||||
char connect_name[100] = "";
|
char connect_name[100] = "";
|
||||||
|
|
||||||
std::cout<<"Address to connect to [empty = host a game]: ";
|
if(cmd_args.exists("address"))
|
||||||
if(g_settings.get("address") != "" && is_yes(g_settings.get("host_game")) == false)
|
{
|
||||||
|
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;
|
std::cout<<g_settings.get("address")<<std::endl;
|
||||||
snprintf(connect_name, 100, "%s", g_settings.get("address").c_str());
|
snprintf(connect_name, 100, "%s", g_settings.get("address").c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
std::cout<<"Address to connect to [empty = host a game]: ";
|
||||||
std::cin.getline(connect_name, 100);
|
std::cin.getline(connect_name, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1280,9 +1298,9 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hosting)
|
if(hosting)
|
||||||
std::cout<<"-> hosting"<<std::endl;
|
std::cout<<"> Hosting game"<<std::endl;
|
||||||
else
|
else
|
||||||
std::cout<<"-> "<<connect_name<<std::endl;
|
std::cout<<"> Connecting to "<<connect_name<<std::endl;
|
||||||
|
|
||||||
char playername[PLAYERNAME_SIZE] = "";
|
char playername[PLAYERNAME_SIZE] = "";
|
||||||
if(g_settings.get("name") != "")
|
if(g_settings.get("name") != "")
|
||||||
|
@ -1393,7 +1411,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
device->setResizable(true);
|
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();
|
g_input = new RandomInputHandler();
|
||||||
else
|
else
|
||||||
g_input = new RealInputHandler(device, &receiver);
|
g_input = new RealInputHandler(device, &receiver);
|
||||||
|
@ -1523,14 +1543,14 @@ int main(int argc, char *argv[])
|
||||||
/*
|
/*
|
||||||
Create skybox
|
Create skybox
|
||||||
*/
|
*/
|
||||||
scene::ISceneNode* skybox;
|
/*scene::ISceneNode* skybox;
|
||||||
skybox = smgr->addSkyBoxSceneNode(
|
skybox = smgr->addSkyBoxSceneNode(
|
||||||
driver->getTexture("../data/skybox2.png"),
|
driver->getTexture("../data/skybox2.png"),
|
||||||
driver->getTexture("../data/skybox3.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"),
|
driver->getTexture("../data/skybox1.png"),
|
||||||
driver->getTexture("../data/skybox1.png"));
|
driver->getTexture("../data/skybox1.png"));*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create the camera node
|
Create the camera node
|
||||||
|
@ -1553,21 +1573,6 @@ int main(int argc, char *argv[])
|
||||||
// Just so big a value that everything rendered is visible
|
// Just so big a value that everything rendered is visible
|
||||||
camera->setFarValue(100000*BS);
|
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_yaw = 0; // "right/left"
|
||||||
f32 camera_pitch = 0; // "up/down"
|
f32 camera_pitch = 0; // "up/down"
|
||||||
|
|
||||||
|
@ -1888,9 +1893,11 @@ int main(int argc, char *argv[])
|
||||||
Mouse and camera control
|
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){
|
if(first_loop_after_window_activation){
|
||||||
//std::cout<<"window active, first loop"<<std::endl;
|
//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)
|
if(selected_object->getTypeId() == MAPBLOCKOBJECT_TYPE_SIGN)
|
||||||
{
|
{
|
||||||
dstream<<"Sign object right-clicked"<<std::endl;
|
dstream<<"Sign object right-clicked"<<std::endl;
|
||||||
|
|
||||||
unFocusGame();
|
unFocusGame();
|
||||||
|
|
||||||
input_guitext = guienv->addStaticText(L"",
|
input_guitext = guienv->addStaticText(L"",
|
||||||
|
@ -1992,8 +1999,17 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
input_guitext->setDrawBackground(true);
|
input_guitext->setDrawBackground(true);
|
||||||
|
|
||||||
g_text_buffer = L"";
|
if(random_input)
|
||||||
g_text_buffer_accepted = false;
|
{
|
||||||
|
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(
|
textbuf_dest = new TextDestSign(
|
||||||
selected_object->getBlock()->getPos(),
|
selected_object->getBlock()->getPos(),
|
||||||
selected_object->getId(),
|
selected_object->getId(),
|
||||||
|
@ -2227,20 +2243,54 @@ int main(int argc, char *argv[])
|
||||||
*/
|
*/
|
||||||
|
|
||||||
camera->setAspectRatio((f32)screensize.X / (f32)screensize.Y);
|
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;
|
u32 daynight_ratio = client.getDayNightRatio();
|
||||||
if(g_viewing_range_all)
|
video::SColor bgcolor = video::SColor(
|
||||||
range = 100000*BS;
|
255,
|
||||||
|
skycolor.getRed() * daynight_ratio / 1000,
|
||||||
|
skycolor.getGreen() * daynight_ratio / 1000,
|
||||||
|
skycolor.getBlue() * daynight_ratio / 1000);
|
||||||
|
|
||||||
driver->setFog(
|
/*
|
||||||
skycolor,
|
Fog
|
||||||
video::EFT_FOG_LINEAR,
|
*/
|
||||||
range*0.6,
|
|
||||||
range,
|
if(g_settings.getBool("enable_fog") == true)
|
||||||
0.01,
|
{
|
||||||
false, // pixel fog
|
f32 range = g_viewing_range_nodes * BS;
|
||||||
false // range fog
|
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);
|
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);
|
TimeTaker timer("beginScene", device);
|
||||||
//driver->beginScene(true, true, bgcolor);
|
driver->beginScene(true, true, bgcolor);
|
||||||
driver->beginScene(false, true, bgcolor);
|
//driver->beginScene(false, true, bgcolor);
|
||||||
beginscenetime = timer.stop(true);
|
beginscenetime = timer.stop(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2471,6 +2503,8 @@ int main(int argc, char *argv[])
|
||||||
device->yield();*/
|
device->yield();*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete quick_inventory;
|
||||||
|
|
||||||
} // client is deleted at this point
|
} // client is deleted at this point
|
||||||
|
|
||||||
delete g_input;
|
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.
|
// Yes, add it to light_sources... somehow.
|
||||||
// It has to be added at somewhere above, in the loop.
|
// It has to be added at somewhere above, in the loop.
|
||||||
// TODO
|
// TODO
|
||||||
// NOTE: This actually works quite fine without it
|
// NOTE: This actually works fine without doing so
|
||||||
// - Find out why it works
|
// - 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_DAY, a_blocks, modified_blocks);
|
||||||
updateLighting(LIGHTBANK_NIGHT, 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);
|
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);
|
TimeTaker timer("expireMeshes()", g_device);
|
||||||
|
|
||||||
|
@ -1046,12 +1079,18 @@ void Map::expireMeshes()
|
||||||
for(i=sectorblocks.begin(); i!=sectorblocks.end(); i++)
|
for(i=sectorblocks.begin(); i!=sectorblocks.end(); i++)
|
||||||
{
|
{
|
||||||
MapBlock *block = *i;
|
MapBlock *block = *i;
|
||||||
|
|
||||||
|
if(only_daynight_diffed && dayNightDiffed(block->getPos()) == false)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
JMutexAutoLock lock(block->mesh_mutex);
|
JMutexAutoLock lock(block->mesh_mutex);
|
||||||
if(block->mesh != NULL)
|
if(block->mesh != NULL)
|
||||||
{
|
{
|
||||||
//block->mesh->drop();
|
/*block->mesh->drop();
|
||||||
//block->mesh = NULL;
|
block->mesh = NULL;*/
|
||||||
block->setMeshExpired(true);
|
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);
|
assert(mapType() == MAPTYPE_CLIENT);
|
||||||
|
|
||||||
try{
|
try{
|
||||||
v3s16 p = blockpos + v3s16(0,0,0);
|
v3s16 p = blockpos + v3s16(0,0,0);
|
||||||
MapBlock *b = getBlockNoCreate(p);
|
MapBlock *b = getBlockNoCreate(p);
|
||||||
b->updateMesh(daylight_factor);
|
b->updateMesh(daynight_ratio);
|
||||||
}
|
}
|
||||||
catch(InvalidPositionException &e){}
|
catch(InvalidPositionException &e){}
|
||||||
try{
|
try{
|
||||||
v3s16 p = blockpos + v3s16(-1,0,0);
|
v3s16 p = blockpos + v3s16(-1,0,0);
|
||||||
MapBlock *b = getBlockNoCreate(p);
|
MapBlock *b = getBlockNoCreate(p);
|
||||||
b->updateMesh(daylight_factor);
|
b->updateMesh(daynight_ratio);
|
||||||
}
|
}
|
||||||
catch(InvalidPositionException &e){}
|
catch(InvalidPositionException &e){}
|
||||||
try{
|
try{
|
||||||
v3s16 p = blockpos + v3s16(0,-1,0);
|
v3s16 p = blockpos + v3s16(0,-1,0);
|
||||||
MapBlock *b = getBlockNoCreate(p);
|
MapBlock *b = getBlockNoCreate(p);
|
||||||
b->updateMesh(daylight_factor);
|
b->updateMesh(daynight_ratio);
|
||||||
}
|
}
|
||||||
catch(InvalidPositionException &e){}
|
catch(InvalidPositionException &e){}
|
||||||
try{
|
try{
|
||||||
v3s16 p = blockpos + v3s16(0,0,-1);
|
v3s16 p = blockpos + v3s16(0,0,-1);
|
||||||
MapBlock *b = getBlockNoCreate(p);
|
MapBlock *b = getBlockNoCreate(p);
|
||||||
b->updateMesh(daylight_factor);
|
b->updateMesh(daynight_ratio);
|
||||||
}
|
}
|
||||||
catch(InvalidPositionException &e){}
|
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
|
Updates usage timers
|
||||||
*/
|
*/
|
||||||
|
@ -2216,8 +2289,8 @@ void ServerMap::save(bool only_changed)
|
||||||
}//sectorlock
|
}//sectorlock
|
||||||
|
|
||||||
u32 deleted_count = 0;
|
u32 deleted_count = 0;
|
||||||
deleted_count = deleteUnusedSectors
|
deleted_count = deleteUnusedSectors(
|
||||||
(SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT);
|
SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Only print if something happened or saved whole map
|
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);
|
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
|
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
|
//NOTE: The sectors map should be locked but we're not doing it
|
||||||
// because it'd cause too much delays
|
// because it'd cause too much delays
|
||||||
|
|
||||||
|
int timecheck_counter = 0;
|
||||||
|
|
||||||
core::map<v2s16, MapSector*>::Iterator si;
|
core::map<v2s16, MapSector*>::Iterator si;
|
||||||
si = m_sectors.getIterator();
|
si = m_sectors.getIterator();
|
||||||
for(; si.atEnd() == false; si++)
|
for(; si.atEnd() == false; si++)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
static int timecheck_counter = 0;
|
|
||||||
timecheck_counter++;
|
timecheck_counter++;
|
||||||
if(timecheck_counter > 50)
|
if(timecheck_counter > 50)
|
||||||
{
|
{
|
||||||
|
@ -2872,7 +2949,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||||
/*
|
/*
|
||||||
Draw the faces of the block
|
Draw the faces of the block
|
||||||
*/
|
*/
|
||||||
|
#if 1
|
||||||
bool mesh_expired = false;
|
bool mesh_expired = false;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -2885,29 +2962,56 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||||
if(block->mesh == NULL && mesh_expired == false)
|
if(block->mesh == NULL && mesh_expired == false)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f32 faraway = BS*50;
|
||||||
|
//f32 faraway = viewing_range_nodes * BS;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This has to be done with the mesh_mutex unlocked
|
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_update_count++;
|
||||||
|
|
||||||
// Mesh has been expired: generate new mesh
|
// 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);
|
JMutexAutoLock lock(block->mesh_mutex);
|
||||||
|
|
||||||
if(block->mesh == NULL)
|
scene::SMesh *mesh = block->mesh;
|
||||||
|
|
||||||
|
if(mesh == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
u32 c = block->mesh->getMeshBufferCount();
|
u32 c = mesh->getMeshBufferCount();
|
||||||
|
|
||||||
for(u32 i=0; i<c; i++)
|
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();
|
const video::SMaterial& material = buf->getMaterial();
|
||||||
video::IMaterialRenderer* rnd =
|
video::IMaterialRenderer* rnd =
|
||||||
driver->getMaterialRenderer(material.MaterialType);
|
driver->getMaterialRenderer(material.MaterialType);
|
||||||
|
|
19
src/map.h
19
src/map.h
|
@ -224,6 +224,11 @@ public:
|
||||||
return MAPTYPE_BASE;
|
return MAPTYPE_BASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void drop()
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
void updateCamera(v3f pos, v3f dir)
|
void updateCamera(v3f pos, v3f dir)
|
||||||
{
|
{
|
||||||
JMutexAutoLock lock(m_camera_mutex);
|
JMutexAutoLock lock(m_camera_mutex);
|
||||||
|
@ -375,9 +380,14 @@ public:
|
||||||
Updates the faces of the given block and blocks on the
|
Updates the faces of the given block and blocks on the
|
||||||
leading edge.
|
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();
|
//core::aabbox3d<s16> getDisplayedBlockArea();
|
||||||
|
|
||||||
|
@ -544,6 +554,11 @@ public:
|
||||||
return MAPTYPE_CLIENT;
|
return MAPTYPE_CLIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drop()
|
||||||
|
{
|
||||||
|
ISceneNode::drop();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Forcefully get a sector from somewhere
|
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::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)
|
bool MapBlock::isValidPositionParent(v3s16 p)
|
||||||
{
|
{
|
||||||
if(isValidPosition(p))
|
if(isValidPosition(p))
|
||||||
|
@ -68,10 +114,33 @@ void MapBlock::setNodeParent(v3s16 p, MapNode & n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FastFace * MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
|
MapNode MapBlock::getNodeParentNoEx(v3s16 p)
|
||||||
v3s16 dir, v3f scale, v3f posRelative_f)
|
|
||||||
{
|
{
|
||||||
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.
|
// Position is at the center of the cube.
|
||||||
v3f pos = p * BS;
|
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[2] = v3f(-BS/2, BS/2,BS/2);
|
||||||
vertex_pos[3] = 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++)
|
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].X *= scale.X;
|
||||||
vertex_pos[i].Y *= scale.Y;
|
vertex_pos[i].Y *= scale.Y;
|
||||||
vertex_pos[i].Z *= scale.Z;
|
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);
|
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));
|
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));
|
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));
|
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));
|
core::vector2d<f32>(0,0));
|
||||||
|
|
||||||
f->tile = tile;
|
face.tile = tile;
|
||||||
//DEBUG
|
//DEBUG
|
||||||
//f->tile = TILE_STONE;
|
//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.
|
Order doesn't matter.
|
||||||
|
|
||||||
If either of the nodes doesn't exist, light is 0.
|
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{
|
try{
|
||||||
MapNode n = getNodeParent(p);
|
|
||||||
MapNode n2 = getNodeParent(p + face_dir);
|
|
||||||
u8 light;
|
u8 light;
|
||||||
u8 l1 = n.getLightBlend(daylight_factor);
|
u8 l1 = n.getLightBlend(daynight_ratio);
|
||||||
u8 l2 = n2.getLightBlend(daylight_factor);
|
u8 l2 = n2.getLightBlend(daynight_ratio);
|
||||||
if(l1 > l2)
|
if(l1 > l2)
|
||||||
light = l1;
|
light = l1;
|
||||||
else
|
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.
|
Gets node tile from any place relative to block.
|
||||||
Returns TILE_NODE if doesn't exist or should not be drawn.
|
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;
|
TileSpec spec;
|
||||||
|
|
||||||
spec.feature = TILEFEAT_NONE;
|
/*//DEBUG
|
||||||
try{
|
|
||||||
MapNode n = getNodeParent(p);
|
|
||||||
|
|
||||||
spec.id = n.getTile(face_dir);
|
|
||||||
}
|
|
||||||
catch(InvalidPositionException &e)
|
|
||||||
{
|
{
|
||||||
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
|
Check temporary modifications on this node
|
||||||
*/
|
*/
|
||||||
|
@ -221,7 +313,7 @@ TileSpec MapBlock::getNodeTile(v3s16 p, v3s16 face_dir)
|
||||||
return spec;
|
return spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 MapBlock::getNodeContent(v3s16 p)
|
u8 MapBlock::getNodeContent(v3s16 p, MapNode mn)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Check temporary modifications on this node
|
Check temporary modifications on this node
|
||||||
|
@ -253,16 +345,8 @@ u8 MapBlock::getNodeContent(v3s16 p)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try{
|
return mn.d;
|
||||||
MapNode n = getNodeParent(p);
|
|
||||||
|
|
||||||
return n.d;
|
|
||||||
}
|
|
||||||
catch(InvalidPositionException &e)
|
|
||||||
{
|
|
||||||
return CONTENT_IGNORE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -271,48 +355,47 @@ u8 MapBlock::getNodeContent(v3s16 p)
|
||||||
face_dir: unit vector with only one of x, y or z
|
face_dir: unit vector with only one of x, y or z
|
||||||
*/
|
*/
|
||||||
void MapBlock::updateFastFaceRow(
|
void MapBlock::updateFastFaceRow(
|
||||||
u32 daylight_factor,
|
u32 daynight_ratio,
|
||||||
|
v3f posRelative_f,
|
||||||
v3s16 startpos,
|
v3s16 startpos,
|
||||||
u16 length,
|
u16 length,
|
||||||
v3s16 translate_dir,
|
v3s16 translate_dir,
|
||||||
|
v3f translate_dir_f,
|
||||||
v3s16 face_dir,
|
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;
|
v3s16 p = startpos;
|
||||||
/*
|
|
||||||
Get face light at starting position
|
|
||||||
*/
|
|
||||||
u8 light = getFaceLight(daylight_factor, p, face_dir);
|
|
||||||
|
|
||||||
u16 continuous_tiles_count = 0;
|
u16 continuous_tiles_count = 0;
|
||||||
|
|
||||||
TileSpec tile0 = getNodeTile(p, face_dir);
|
MapNode n0 = getNodeParentNoEx(p);
|
||||||
TileSpec tile1 = getNodeTile(p + face_dir, -face_dir);
|
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++)
|
for(u16 j=0; j<length; j++)
|
||||||
{
|
{
|
||||||
bool next_is_different = true;
|
bool next_is_different = true;
|
||||||
|
|
||||||
v3s16 p_next;
|
v3s16 p_next;
|
||||||
|
MapNode n0_next;
|
||||||
|
MapNode n1_next;
|
||||||
TileSpec tile0_next;
|
TileSpec tile0_next;
|
||||||
TileSpec tile1_next;
|
TileSpec tile1_next;
|
||||||
u8 light_next = 0;
|
u8 light_next = 0;
|
||||||
|
|
||||||
if(j != length - 1){
|
if(j != length - 1)
|
||||||
|
{
|
||||||
p_next = p + translate_dir;
|
p_next = p + translate_dir;
|
||||||
tile0_next = getNodeTile(p_next, face_dir);
|
n0_next = getNodeParentNoEx(p_next);
|
||||||
tile1_next = getNodeTile(p_next + face_dir, -face_dir);
|
n1_next = getNodeParentNoEx(p_next + face_dir);
|
||||||
light_next = getFaceLight(daylight_factor, 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
|
if(tile0_next == tile0
|
||||||
&& tile1_next == tile1
|
&& tile1_next == tile1
|
||||||
|
@ -331,8 +414,8 @@ void MapBlock::updateFastFaceRow(
|
||||||
*/
|
*/
|
||||||
//u8 mf = face_contents(tile0, tile1);
|
//u8 mf = face_contents(tile0, tile1);
|
||||||
// This is hackish
|
// This is hackish
|
||||||
u8 content0 = getNodeContent(p);
|
u8 content0 = getNodeContent(p, n0);
|
||||||
u8 content1 = getNodeContent(p + face_dir);
|
u8 content1 = getNodeContent(p + face_dir, n1);
|
||||||
u8 mf = face_contents(content0, content1);
|
u8 mf = face_contents(content0, content1);
|
||||||
|
|
||||||
if(mf != 0)
|
if(mf != 0)
|
||||||
|
@ -352,26 +435,28 @@ void MapBlock::updateFastFaceRow(
|
||||||
scale.Z = continuous_tiles_count;
|
scale.Z = continuous_tiles_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
FastFace *f;
|
//FastFace *f;
|
||||||
|
|
||||||
// If node at sp (tile0) is more solid
|
// If node at sp (tile0) is more solid
|
||||||
if(mf == 1)
|
if(mf == 1)
|
||||||
{
|
{
|
||||||
f = makeFastFace(tile0, light,
|
makeFastFace(tile0, light,
|
||||||
sp, face_dir, scale,
|
sp, face_dir, scale,
|
||||||
posRelative_f);
|
posRelative_f, dest);
|
||||||
}
|
}
|
||||||
// If node at sp is less solid (mf == 2)
|
// If node at sp is less solid (mf == 2)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
f = makeFastFace(tile1, light,
|
makeFastFace(tile1, light,
|
||||||
sp+face_dir_f, -face_dir, scale,
|
sp+face_dir_f, -face_dir, scale,
|
||||||
posRelative_f);
|
posRelative_f, dest);
|
||||||
}
|
}
|
||||||
dest.push_back(f);
|
//dest.push_back(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
continuous_tiles_count = 0;
|
continuous_tiles_count = 0;
|
||||||
|
n0 = n0_next;
|
||||||
|
n1 = n1_next;
|
||||||
tile0 = tile0_next;
|
tile0 = tile0_next;
|
||||||
tile1 = tile1_next;
|
tile1 = tile1_next;
|
||||||
light = light_next;
|
light = light_next;
|
||||||
|
@ -474,89 +559,101 @@ private:
|
||||||
core::array<PreMeshBuffer> m_prebuffers;
|
core::array<PreMeshBuffer> m_prebuffers;
|
||||||
};
|
};
|
||||||
|
|
||||||
void MapBlock::updateMesh(u32 daylight_factor)
|
void MapBlock::updateMesh(u32 daynight_ratio)
|
||||||
{
|
{
|
||||||
/*v3s16 p = getPosRelative();
|
#if 0
|
||||||
std::cout<<"MapBlock("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
|
||||||
<<"::updateMesh(): ";*/
|
|
||||||
//<<"::updateMesh()"<<std::endl;
|
|
||||||
TimeTaker timer1("updateMesh()", g_device);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: Change this to directly generate the mesh (and get rid
|
DEBUG: If mesh has been generated, don't generate it again
|
||||||
of FastFaces)
|
|
||||||
*/
|
*/
|
||||||
|
{
|
||||||
|
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.
|
We are including the faces of the trailing edges of the block.
|
||||||
This means that when something changes, the caller must
|
This means that when something changes, the caller must
|
||||||
also update the meshes of the blocks at the leading edges.
|
also update the meshes of the blocks at the leading edges.
|
||||||
|
|
||||||
NOTE: This is the slowest part of this method. The other parts
|
NOTE: This is the slowest part of this method.
|
||||||
take around 0ms, this takes around 15-70ms.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Go through every y,z and get top faces in rows of x+
|
Go through every y,z and get top faces in rows of x+
|
||||||
*/
|
*/
|
||||||
for(s16 y=0; y<MAP_BLOCKSIZE; y++){
|
for(s16 y=0; y<MAP_BLOCKSIZE; y++){
|
||||||
//for(s16 y=-1; y<MAP_BLOCKSIZE; y++){
|
|
||||||
for(s16 z=0; z<MAP_BLOCKSIZE; z++){
|
for(s16 z=0; z<MAP_BLOCKSIZE; z++){
|
||||||
updateFastFaceRow(daylight_factor,
|
updateFastFaceRow(daynight_ratio, posRelative_f,
|
||||||
v3s16(0,y,z), MAP_BLOCKSIZE,
|
v3s16(0,y,z), MAP_BLOCKSIZE,
|
||||||
v3s16(1,0,0),
|
v3s16(1,0,0), //dir
|
||||||
v3s16(0,1,0),
|
v3f (1,0,0),
|
||||||
*fastfaces_new);
|
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+
|
Go through every x,y and get right faces in rows of z+
|
||||||
*/
|
*/
|
||||||
for(s16 x=0; x<MAP_BLOCKSIZE; x++){
|
for(s16 x=0; x<MAP_BLOCKSIZE; x++){
|
||||||
//for(s16 x=-1; x<MAP_BLOCKSIZE; x++){
|
|
||||||
for(s16 y=0; y<MAP_BLOCKSIZE; y++){
|
for(s16 y=0; y<MAP_BLOCKSIZE; y++){
|
||||||
updateFastFaceRow(daylight_factor,
|
updateFastFaceRow(daynight_ratio, posRelative_f,
|
||||||
v3s16(x,y,0), MAP_BLOCKSIZE,
|
v3s16(x,y,0), MAP_BLOCKSIZE,
|
||||||
v3s16(0,0,1),
|
v3s16(0,0,1),
|
||||||
|
v3f (0,0,1),
|
||||||
v3s16(1,0,0),
|
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+
|
Go through every y,z and get back faces in rows of x+
|
||||||
*/
|
*/
|
||||||
for(s16 z=0; z<MAP_BLOCKSIZE; z++){
|
for(s16 z=0; z<MAP_BLOCKSIZE; z++){
|
||||||
//for(s16 z=-1; z<MAP_BLOCKSIZE; z++){
|
|
||||||
for(s16 y=0; y<MAP_BLOCKSIZE; y++){
|
for(s16 y=0; y<MAP_BLOCKSIZE; y++){
|
||||||
updateFastFaceRow(daylight_factor,
|
updateFastFaceRow(daynight_ratio, posRelative_f,
|
||||||
v3s16(0,y,z), MAP_BLOCKSIZE,
|
v3s16(0,y,z), MAP_BLOCKSIZE,
|
||||||
v3s16(1,0,0),
|
v3s16(1,0,0),
|
||||||
|
v3f (1,0,0),
|
||||||
v3s16(0,0,1),
|
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;
|
scene::SMesh *mesh_new = NULL;
|
||||||
|
|
||||||
mesh_new = new scene::SMesh();
|
mesh_new = new scene::SMesh();
|
||||||
|
|
||||||
if(fastfaces_new->getSize() > 0)
|
if(fastfaces_new.size() > 0)
|
||||||
{
|
{
|
||||||
MeshCollector collector;
|
MeshCollector collector;
|
||||||
|
|
||||||
core::list<FastFace*>::Iterator i = fastfaces_new->begin();
|
for(u32 i=0; i<fastfaces_new.size(); i++)
|
||||||
|
|
||||||
for(; i != fastfaces_new->end(); i++)
|
|
||||||
{
|
{
|
||||||
FastFace *f = *i;
|
FastFace &f = fastfaces_new[i];
|
||||||
|
|
||||||
const u16 indices[] = {0,1,2,2,3,0};
|
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);
|
indices, 6);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -569,7 +666,7 @@ void MapBlock::updateMesh(u32 daylight_factor)
|
||||||
collector.fillMesh(mesh_new);
|
collector.fillMesh(mesh_new);
|
||||||
|
|
||||||
// Use VBO for mesh (this just would set this for ever buffer)
|
// 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 "
|
/*std::cout<<"MapBlock has "<<fastfaces_new->getSize()<<" faces "
|
||||||
<<"and uses "<<mesh_new->getMeshBufferCount()
|
<<"and uses "<<mesh_new->getMeshBufferCount()
|
||||||
|
@ -580,14 +677,14 @@ void MapBlock::updateMesh(u32 daylight_factor)
|
||||||
Clear temporary FastFaces
|
Clear temporary FastFaces
|
||||||
*/
|
*/
|
||||||
|
|
||||||
core::list<FastFace*>::Iterator i;
|
/*core::list<FastFace*>::Iterator i;
|
||||||
i = fastfaces_new->begin();
|
i = fastfaces_new->begin();
|
||||||
for(; i != fastfaces_new->end(); i++)
|
for(; i != fastfaces_new->end(); i++)
|
||||||
{
|
{
|
||||||
delete *i;
|
delete *i;
|
||||||
}
|
}
|
||||||
fastfaces_new->clear();
|
fastfaces_new->clear();
|
||||||
delete fastfaces_new;
|
delete fastfaces_new;*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Add special graphics:
|
Add special graphics:
|
||||||
|
@ -697,8 +794,10 @@ void MapBlock::updateMesh(u32 daylight_factor)
|
||||||
|
|
||||||
mesh_mutex.Lock();
|
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;
|
mesh = mesh_new;
|
||||||
setMeshExpired(false);
|
setMeshExpired(false);
|
||||||
|
|
||||||
|
@ -711,8 +810,20 @@ void MapBlock::updateMesh(u32 daylight_factor)
|
||||||
{
|
{
|
||||||
IMeshBuffer *buf = mesh_old->getMeshBuffer(i);
|
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
|
// Drop the mesh
|
||||||
mesh_old->drop();
|
mesh_old->drop();
|
||||||
|
|
||||||
//delete mesh_old;
|
//delete mesh_old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,6 +832,18 @@ void MapBlock::updateMesh(u32 daylight_factor)
|
||||||
//std::cout<<"added "<<fastfaces.getSize()<<" faces."<<std::endl;
|
//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.
|
Propagates sunlight down through the block.
|
||||||
Doesn't modify nodes that are not affected by sunlight.
|
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
|
Serialization
|
||||||
*/
|
*/
|
||||||
|
@ -948,7 +1119,12 @@ void MapBlock::serialize(std::ostream &os, u8 version)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// First byte
|
// 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;
|
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;
|
u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||||
|
|
||||||
u8 t8;
|
u8 flags;
|
||||||
is.read((char*)&t8, 1);
|
is.read((char*)&flags, 1);
|
||||||
is_underground = t8;
|
is_underground = (flags & 1) ? true : false;
|
||||||
|
m_day_night_differs = (flags & 2) ? true : false;
|
||||||
|
|
||||||
// Uncompress data
|
// Uncompress data
|
||||||
std::ostringstream os(std::ios_base::binary);
|
std::ostringstream os(std::ios_base::binary);
|
||||||
|
|
|
@ -89,51 +89,12 @@ class MapBlock : public NodeContainer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*
|
//scene::SMesh *mesh[DAYNIGHT_CACHE_COUNT];
|
||||||
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;
|
scene::SMesh *mesh;
|
||||||
JMutex mesh_mutex;
|
JMutex mesh_mutex;
|
||||||
|
|
||||||
MapBlock(NodeContainer *parent, v3s16 pos, bool dummy=false):
|
MapBlock(NodeContainer *parent, v3s16 pos, bool dummy=false);
|
||||||
m_parent(parent),
|
~MapBlock();
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual u16 nodeContainerId() const
|
virtual u16 nodeContainerId() const
|
||||||
{
|
{
|
||||||
|
@ -302,6 +263,7 @@ public:
|
||||||
bool isValidPositionParent(v3s16 p);
|
bool isValidPositionParent(v3s16 p);
|
||||||
MapNode getNodeParent(v3s16 p);
|
MapNode getNodeParent(v3s16 p);
|
||||||
void setNodeParent(v3s16 p, MapNode & n);
|
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)
|
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);
|
setNode(x0+x, y0+y, z0+z, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static FastFace * makeFastFace(TileSpec tile, u8 light, v3f p,
|
static void makeFastFace(TileSpec tile, u8 light, v3f p,
|
||||||
v3s16 dir, v3f scale, v3f posRelative_f);
|
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 getFaceLight(u32 daynight_ratio, v3s16 p, v3s16 face_dir)
|
||||||
u8 getNodeContent(v3s16 p);
|
{
|
||||||
|
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:
|
startpos:
|
||||||
|
@ -325,14 +297,20 @@ public:
|
||||||
face_dir: unit vector with only one of x, y or z
|
face_dir: unit vector with only one of x, y or z
|
||||||
*/
|
*/
|
||||||
void updateFastFaceRow(
|
void updateFastFaceRow(
|
||||||
u32 daylight_factor,
|
u32 daynight_ratio,
|
||||||
|
v3f posRelative_f,
|
||||||
v3s16 startpos,
|
v3s16 startpos,
|
||||||
u16 length,
|
u16 length,
|
||||||
v3s16 translate_dir,
|
v3s16 translate_dir,
|
||||||
|
v3f translate_dir_f,
|
||||||
v3s16 face_dir,
|
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);
|
bool propagateSunlight(core::map<v3s16, bool> & light_sources);
|
||||||
|
|
||||||
|
@ -429,6 +407,21 @@ public:
|
||||||
m_temp_mods.clear();
|
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
|
Serialization
|
||||||
*/
|
*/
|
||||||
|
@ -480,6 +473,9 @@ private:
|
||||||
|
|
||||||
bool m_mesh_expired;
|
bool m_mesh_expired;
|
||||||
|
|
||||||
|
// Whether day and night lighting differs
|
||||||
|
bool m_day_night_differs;
|
||||||
|
|
||||||
MapBlockObjectList m_objects;
|
MapBlockObjectList m_objects;
|
||||||
|
|
||||||
// Temporary modifications to nodes
|
// Temporary modifications to nodes
|
||||||
|
|
|
@ -339,17 +339,7 @@ void MapBlockObjectList::update(std::istream &is, u8 version,
|
||||||
" id="<<id
|
" id="<<id
|
||||||
<<std::endl;*/
|
<<std::endl;*/
|
||||||
|
|
||||||
if(type_id == MAPBLOCKOBJECT_TYPE_TEST)
|
if(type_id == MAPBLOCKOBJECT_TYPE_SIGN)
|
||||||
{
|
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
obj = new SignObject(m_block, id, pos);
|
obj = new SignObject(m_block, id, pos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,119 +220,6 @@ protected:
|
||||||
};
|
};
|
||||||
#endif
|
#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
|
class MovingObject : public MapBlockObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -398,134 +285,6 @@ protected:
|
||||||
bool m_touching_ground;
|
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
|
class RatObject : public MovingObject
|
||||||
{
|
{
|
||||||
public:
|
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
|
8: (dev) server-initiated block transfers and all kinds of stuff
|
||||||
9: (dev) block objects
|
9: (dev) block objects
|
||||||
10: (dev) water pressure
|
10: (dev) water pressure
|
||||||
11: (dev) zlib'd blocks
|
11: (dev) zlib'd blocks, block flags
|
||||||
*/
|
*/
|
||||||
// This represents an uninitialized or invalid format
|
// This represents an uninitialized or invalid format
|
||||||
#define SER_FMT_VER_INVALID 255
|
#define SER_FMT_VER_INVALID 255
|
||||||
|
|
|
@ -285,6 +285,12 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
||||||
|
// Increment timers
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_blocks_sent_mutex);
|
||||||
|
m_nearest_unsent_reset_timer += dtime;
|
||||||
|
}
|
||||||
|
|
||||||
// Won't send anything if already sending
|
// Won't send anything if already sending
|
||||||
{
|
{
|
||||||
JMutexAutoLock lock(m_blocks_sending_mutex);
|
JMutexAutoLock lock(m_blocks_sending_mutex);
|
||||||
|
@ -320,12 +326,13 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||||
m_last_center = center;
|
m_last_center = center;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float reset_counter = 0;
|
/*dstream<<"m_nearest_unsent_reset_timer="
|
||||||
reset_counter += dtime;
|
<<m_nearest_unsent_reset_timer<<std::endl;*/
|
||||||
if(reset_counter > 5.0)
|
if(m_nearest_unsent_reset_timer > 5.0)
|
||||||
{
|
{
|
||||||
reset_counter = 0;
|
m_nearest_unsent_reset_timer = 0;
|
||||||
m_nearest_unsent_d = 0;
|
m_nearest_unsent_d = 0;
|
||||||
|
//dstream<<"Resetting m_nearest_unsent_d"<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_nearest_unsent_d = m_nearest_unsent_d;
|
last_nearest_unsent_d = m_nearest_unsent_d;
|
||||||
|
@ -353,6 +360,21 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||||
= LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS;
|
= 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
|
// Serialization version used
|
||||||
//u8 ser_version = serialization_version;
|
//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)
|
if(m_nearest_unsent_d != last_nearest_unsent_d)
|
||||||
{
|
{
|
||||||
d = m_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);
|
JMutexAutoLock lock(m_blocks_sending_mutex);
|
||||||
|
|
||||||
// Limit is dynamically lowered when building
|
// Limit is dynamically lowered when building
|
||||||
if(m_blocks_sending.size()
|
if(num_blocks_selected
|
||||||
>= maximum_simultaneous_block_sends_now)
|
>= maximum_simultaneous_block_sends_now)
|
||||||
{
|
{
|
||||||
/*dstream<<"Not sending more blocks. Queue full. "
|
/*dstream<<"Not sending more blocks. Queue full. "
|
||||||
<<m_blocks_sending.size()
|
<<m_blocks_sending.size()
|
||||||
<<std::endl;*/
|
<<std::endl;*/
|
||||||
return;
|
goto queue_full;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_blocks_sending.find(p) != NULL)
|
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)
|
if(m_blocks_sent.find(p) != NULL)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check if map has this block
|
Check if map has this block
|
||||||
*/
|
*/
|
||||||
|
@ -498,6 +516,15 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||||
continue;
|
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.
|
Add inexistent block to emerge queue.
|
||||||
*/
|
*/
|
||||||
|
@ -531,10 +558,17 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||||
PrioritySortedBlockTransfer q((float)d, p, peer_id);
|
PrioritySortedBlockTransfer q((float)d, p, peer_id);
|
||||||
|
|
||||||
dest.push_back(q);
|
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(
|
void RemoteClient::SendObjectData(
|
||||||
|
@ -894,6 +928,12 @@ Server::Server(
|
||||||
m_thread(this),
|
m_thread(this),
|
||||||
m_emergethread(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_env_mutex.Init();
|
||||||
m_con_mutex.Init();
|
m_con_mutex.Init();
|
||||||
m_step_dtime_mutex.Init();
|
m_step_dtime_mutex.Init();
|
||||||
|
@ -983,7 +1023,7 @@ void Server::AsyncRunStep()
|
||||||
|
|
||||||
{
|
{
|
||||||
JMutexAutoLock lock1(m_step_dtime_mutex);
|
JMutexAutoLock lock1(m_step_dtime_mutex);
|
||||||
m_step_dtime = 0.0;
|
m_step_dtime -= dtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
//dstream<<"Server steps "<<dtime<<std::endl;
|
//dstream<<"Server steps "<<dtime<<std::endl;
|
||||||
|
@ -1018,7 +1058,7 @@ void Server::AsyncRunStep()
|
||||||
else
|
else
|
||||||
interval = 0.25;
|
interval = 0.25;
|
||||||
|
|
||||||
static float counter = 0.0;
|
float &counter = m_flowwater_timer;
|
||||||
counter += dtime;
|
counter += dtime;
|
||||||
if(counter >= 0.25 && m_flow_active_nodes.size() > 0)
|
if(counter >= 0.25 && m_flow_active_nodes.size() > 0)
|
||||||
{
|
{
|
||||||
|
@ -1082,7 +1122,7 @@ void Server::AsyncRunStep()
|
||||||
|
|
||||||
// Periodically print some info
|
// Periodically print some info
|
||||||
{
|
{
|
||||||
static float counter = 0.0;
|
float &counter = m_print_info_timer;
|
||||||
counter += dtime;
|
counter += dtime;
|
||||||
if(counter >= 30.0)
|
if(counter >= 30.0)
|
||||||
{
|
{
|
||||||
|
@ -1208,7 +1248,7 @@ void Server::AsyncRunStep()
|
||||||
|
|
||||||
// Send object positions
|
// Send object positions
|
||||||
{
|
{
|
||||||
static float counter = 0.0;
|
float &counter = m_objectdata_timer;
|
||||||
counter += dtime;
|
counter += dtime;
|
||||||
if(counter >= g_settings.getFloat("objectdata_interval"))
|
if(counter >= g_settings.getFloat("objectdata_interval"))
|
||||||
{
|
{
|
||||||
|
@ -1223,7 +1263,7 @@ void Server::AsyncRunStep()
|
||||||
// Trigger emergethread (it gets somehow gets to a
|
// Trigger emergethread (it gets somehow gets to a
|
||||||
// non-triggered but bysy state sometimes)
|
// non-triggered but bysy state sometimes)
|
||||||
{
|
{
|
||||||
static float counter = 0.0;
|
float &counter = m_emergethread_trigger_timer;
|
||||||
counter += dtime;
|
counter += dtime;
|
||||||
if(counter >= 2.0)
|
if(counter >= 2.0)
|
||||||
{
|
{
|
||||||
|
@ -1235,7 +1275,7 @@ void Server::AsyncRunStep()
|
||||||
|
|
||||||
// Save map
|
// Save map
|
||||||
{
|
{
|
||||||
static float counter = 0.0;
|
float &counter = m_savemap_timer;
|
||||||
counter += dtime;
|
counter += dtime;
|
||||||
if(counter >= SERVER_MAP_SAVE_INTERVAL)
|
if(counter >= SERVER_MAP_SAVE_INTERVAL)
|
||||||
{
|
{
|
||||||
|
@ -1589,14 +1629,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
if(action == 0)
|
if(action == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
u8 material;
|
u8 content;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Get material at position
|
// Get content at position
|
||||||
material = m_env.getMap().getNode(p_under).d;
|
content = m_env.getMap().getNode(p_under).d;
|
||||||
// If it's not diggable, do nothing
|
// If it's not diggable, do nothing
|
||||||
if(content_diggable(material) == false)
|
if(content_diggable(content) == false)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1615,7 +1655,16 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
JMutexAutoLock(client->m_dig_mutex);
|
JMutexAutoLock(client->m_dig_mutex);
|
||||||
client->m_dig_tool_item = 0;
|
client->m_dig_tool_item = 0;
|
||||||
client->m_dig_position = p_under;
|
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
|
// Reset build time counter
|
||||||
getClient(peer->id)->m_time_from_building.set(0.0);
|
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 "environment.h"
|
||||||
#include "common_irrlicht.h"
|
#include "common_irrlicht.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "utility.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -146,44 +147,6 @@ private:
|
||||||
JMutex m_mutex;
|
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 Server;
|
||||||
|
|
||||||
class ServerThread : public SimpleThread
|
class ServerThread : public SimpleThread
|
||||||
|
@ -281,6 +244,7 @@ public:
|
||||||
serialization_version = SER_FMT_VER_INVALID;
|
serialization_version = SER_FMT_VER_INVALID;
|
||||||
pending_serialization_version = SER_FMT_VER_INVALID;
|
pending_serialization_version = SER_FMT_VER_INVALID;
|
||||||
m_nearest_unsent_d = 0;
|
m_nearest_unsent_d = 0;
|
||||||
|
m_nearest_unsent_reset_timer = 0.0;
|
||||||
|
|
||||||
m_blocks_sent_mutex.Init();
|
m_blocks_sent_mutex.Init();
|
||||||
m_blocks_sending_mutex.Init();
|
m_blocks_sending_mutex.Init();
|
||||||
|
@ -384,6 +348,7 @@ private:
|
||||||
core::map<v3s16, bool> m_blocks_sent;
|
core::map<v3s16, bool> m_blocks_sent;
|
||||||
s16 m_nearest_unsent_d;
|
s16 m_nearest_unsent_d;
|
||||||
v3s16 m_last_center;
|
v3s16 m_last_center;
|
||||||
|
float m_nearest_unsent_reset_timer;
|
||||||
JMutex m_blocks_sent_mutex;
|
JMutex m_blocks_sent_mutex;
|
||||||
/*
|
/*
|
||||||
Blocks that are currently on the line.
|
Blocks that are currently on the line.
|
||||||
|
@ -467,6 +432,12 @@ private:
|
||||||
void UpdateBlockWaterPressure(MapBlock *block,
|
void UpdateBlockWaterPressure(MapBlock *block,
|
||||||
core::map<v3s16, MapBlock*> &modified_blocks);
|
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,
|
// NOTE: If connection and environment are both to be locked,
|
||||||
// environment shall be locked first.
|
// environment shall be locked first.
|
||||||
JMutex m_env_mutex;
|
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_BILINEAR_FILTER, false);
|
||||||
g_tile_materials[i].setFlag(video::EMF_ANTI_ALIASING, video::EAAM_OFF);
|
g_tile_materials[i].setFlag(video::EMF_ANTI_ALIASING, video::EAAM_OFF);
|
||||||
//if(i != TILE_WATER)
|
//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_TEXTURE_WRAP, video::ETC_REPEAT);
|
||||||
//g_tile_materials[i].setFlag(video::EMF_ANISOTROPIC_FILTER, false);
|
//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 <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <jthread.h>
|
||||||
#include <jmutex.h>
|
#include <jmutex.h>
|
||||||
#include <jmutexautolock.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 "common_irrlicht.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "strfnd.h"
|
#include "strfnd.h"
|
||||||
|
@ -1100,5 +1109,43 @@ private:
|
||||||
JMutex m_mutex;
|
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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -741,11 +741,6 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
|
||||||
|
|
||||||
m_data[m_area.index(removed_pos)].setLightBanks(light);
|
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
|
// Mark removed_pos checked
|
||||||
m_flags[m_area.index(removed_pos)] |= VOXELFLAG_CHECKED;
|
m_flags[m_area.index(removed_pos)] |= VOXELFLAG_CHECKED;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue