starting to separate "material" to "content" and "tile"
parent
db49f37692
commit
47a593b519
|
@ -53,3 +53,6 @@
|
||||||
#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_generate_distance = 5
|
||||||
|
|
||||||
|
|
215
src/main.cpp
215
src/main.cpp
|
@ -179,200 +179,19 @@ SUGG: MovingObject::move and Player::move are basically the same.
|
||||||
TODO: Transfer sign texts as metadata of block and not as data of
|
TODO: Transfer sign texts as metadata of block and not as data of
|
||||||
object
|
object
|
||||||
|
|
||||||
|
SUGG: Implement a "Fast check queue" (a queue with a map for checking
|
||||||
|
if something is already in it)
|
||||||
|
- TODO: Use it in active block queue in water flowing
|
||||||
|
|
||||||
|
TODO: Proper looking torches.
|
||||||
|
- Signs could be done in the same way?
|
||||||
|
|
||||||
Doing now:
|
Doing now:
|
||||||
======================================================================
|
======================================================================
|
||||||
|
|
||||||
Water dynamics pseudo-code (block = MapNode):
|
TODO: A system for showing some nodes in some other way than cubes
|
||||||
SUGG: Create separate flag table in VoxelManipulator to allow fast
|
- Needed for torches
|
||||||
clearing of "modified" flags
|
- Also for signs, stairs, etc
|
||||||
|
|
||||||
neighborCausedPressure(pos):
|
|
||||||
pressure = 0
|
|
||||||
dirs = {down, left, right, back, front, up}
|
|
||||||
for d in dirs:
|
|
||||||
pos2 = pos + d
|
|
||||||
p = block_at(pos2).pressure
|
|
||||||
if d.Y == 1 and p > min:
|
|
||||||
p -= 1
|
|
||||||
if d.Y == -1 and p < max:
|
|
||||||
p += 1
|
|
||||||
if p > pressure:
|
|
||||||
pressure = p
|
|
||||||
return pressure
|
|
||||||
|
|
||||||
# This should somehow update all changed pressure values
|
|
||||||
# in an unknown body of water
|
|
||||||
updateWaterPressure(pos):
|
|
||||||
TODO
|
|
||||||
|
|
||||||
FIXME: This goes in an indefinite loop when there is an underwater
|
|
||||||
chamber like this:
|
|
||||||
|
|
||||||
#111######
|
|
||||||
#222##22##
|
|
||||||
#33333333x<- block removed from here
|
|
||||||
##########
|
|
||||||
|
|
||||||
#111######
|
|
||||||
#222##22##
|
|
||||||
#3333333x1
|
|
||||||
##########
|
|
||||||
|
|
||||||
#111######
|
|
||||||
#222##22##
|
|
||||||
#333333x11
|
|
||||||
##########
|
|
||||||
|
|
||||||
#111######
|
|
||||||
#222##2x##
|
|
||||||
#333333333
|
|
||||||
##########
|
|
||||||
|
|
||||||
#111######
|
|
||||||
#222##x2##
|
|
||||||
#333333333
|
|
||||||
##########
|
|
||||||
|
|
||||||
Now, consider moving to the last block not allowed.
|
|
||||||
|
|
||||||
Consider it a 3D case with a depth of 2. We're now at this situation.
|
|
||||||
Note the additional blocking ## in the second depth plane.
|
|
||||||
|
|
||||||
z=1 z=2
|
|
||||||
#111###### #111######
|
|
||||||
#222##x2## #222##22##
|
|
||||||
#333333333 #33333##33
|
|
||||||
########## ##########
|
|
||||||
|
|
||||||
#111###### #111######
|
|
||||||
#222##22## #222##x2##
|
|
||||||
#333333333 #33333##33
|
|
||||||
########## ##########
|
|
||||||
|
|
||||||
#111###### #111######
|
|
||||||
#222##22## #222##2x##
|
|
||||||
#333333333 #33333##33
|
|
||||||
########## ##########
|
|
||||||
|
|
||||||
Now there is nowhere to go, without going to an already visited block,
|
|
||||||
but the pressure calculated in here from neighboring blocks is >= 2,
|
|
||||||
so it is not the final ending.
|
|
||||||
|
|
||||||
We will back up to a state where there is somewhere to go to.
|
|
||||||
It is this state:
|
|
||||||
|
|
||||||
#111###### #111######
|
|
||||||
#222##22## #222##22##
|
|
||||||
#333333x33 #33333##33
|
|
||||||
########## ##########
|
|
||||||
|
|
||||||
Then just go on, avoiding already visited blocks:
|
|
||||||
|
|
||||||
#111###### #111######
|
|
||||||
#222##22## #222##22##
|
|
||||||
#33333x333 #33333##33
|
|
||||||
########## ##########
|
|
||||||
|
|
||||||
#111###### #111######
|
|
||||||
#222##22## #222##22##
|
|
||||||
#3333x3333 #33333##33
|
|
||||||
########## ##########
|
|
||||||
|
|
||||||
#111###### #111######
|
|
||||||
#222##22## #222##22##
|
|
||||||
#333x33333 #33333##33
|
|
||||||
########## ##########
|
|
||||||
|
|
||||||
#111###### #111######
|
|
||||||
#222##22## #222##22##
|
|
||||||
#33x333333 #33333##33
|
|
||||||
########## ##########
|
|
||||||
|
|
||||||
#111###### #111######
|
|
||||||
#22x##22## #222##22##
|
|
||||||
#333333333 #33333##33
|
|
||||||
########## ##########
|
|
||||||
|
|
||||||
#11x###### #111######
|
|
||||||
#222##22## #222##22##
|
|
||||||
#333333333 #33333##33
|
|
||||||
########## ##########
|
|
||||||
|
|
||||||
"Blob". the air bubble finally got out of the water.
|
|
||||||
Then return recursively to a state where there is air next to water,
|
|
||||||
clear the visit flags and feed the neighbor of the water recursively
|
|
||||||
to the algorithm.
|
|
||||||
|
|
||||||
#11 ###### #111######
|
|
||||||
#222##22## #222##22##
|
|
||||||
#333333333x #33333##33
|
|
||||||
########## ##########
|
|
||||||
|
|
||||||
#11 ###### #111######
|
|
||||||
#222##22## #222##22##
|
|
||||||
#33333333x3 #33333##33
|
|
||||||
########## ##########
|
|
||||||
|
|
||||||
...and so on.
|
|
||||||
|
|
||||||
|
|
||||||
# removed_pos: a position that has been changed from something to air
|
|
||||||
flowWater(removed_pos):
|
|
||||||
dirs = {top, left, right, back, front, bottom}
|
|
||||||
selected_dir = None
|
|
||||||
for d in dirs:
|
|
||||||
b2 = removed_pos + d
|
|
||||||
|
|
||||||
# Ignore positions that don't have water
|
|
||||||
if block_at(b2) != water:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Ignore positions that have already been checked
|
|
||||||
if block_at(b2).checked:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# If block is at top, select it always.
|
|
||||||
if d.Y == 1:
|
|
||||||
selected_dir = d
|
|
||||||
break
|
|
||||||
|
|
||||||
# If block is at bottom, select it if it has enough pressure.
|
|
||||||
# >= 3 needed for stability (and sanity)
|
|
||||||
if d.Y == -1:
|
|
||||||
if block_at(b2).pressure >= 3:
|
|
||||||
selected_dir = d
|
|
||||||
break
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Else block is at some side. select it if it has enough pressure.
|
|
||||||
if block_at(b2).pressure >= 2:
|
|
||||||
selected_dir = d
|
|
||||||
break
|
|
||||||
|
|
||||||
# If there is nothing to do anymore, return.
|
|
||||||
if selected_dir == None
|
|
||||||
return
|
|
||||||
|
|
||||||
b2 = removed_pos + selected_dir
|
|
||||||
|
|
||||||
# Move block
|
|
||||||
set_block(removed_pos, block_at(b2))
|
|
||||||
set_block(b2, air_block)
|
|
||||||
|
|
||||||
# Update pressure
|
|
||||||
updateWaterPressure(removed_pos)
|
|
||||||
|
|
||||||
# Flow water to the newly created empty position
|
|
||||||
flowWater(b2)
|
|
||||||
|
|
||||||
# Check empty positions around and try flowing water to them
|
|
||||||
for d in dirs:
|
|
||||||
b3 = removed_pos + d
|
|
||||||
# Ignore positions that are not air
|
|
||||||
if block_at(b3) is not air:
|
|
||||||
continue
|
|
||||||
flowWater(b3)
|
|
||||||
|
|
||||||
|
|
||||||
======================================================================
|
======================================================================
|
||||||
|
|
||||||
|
@ -448,7 +267,8 @@ const char *g_material_filenames[MATERIALS_COUNT] =
|
||||||
"../data/leaves.png",
|
"../data/leaves.png",
|
||||||
"../data/grass_footsteps.png",
|
"../data/grass_footsteps.png",
|
||||||
"../data/mese.png",
|
"../data/mese.png",
|
||||||
"../data/mud.png"
|
"../data/mud.png",
|
||||||
|
"../data/water.png", // ocean
|
||||||
};
|
};
|
||||||
|
|
||||||
video::SMaterial g_materials[MATERIALS_COUNT];
|
video::SMaterial g_materials[MATERIALS_COUNT];
|
||||||
|
@ -499,6 +319,8 @@ void set_default_settings()
|
||||||
g_settings.set("name", "");
|
g_settings.set("name", "");
|
||||||
g_settings.set("random_input", "false");
|
g_settings.set("random_input", "false");
|
||||||
g_settings.set("client_delete_unused_sectors_timeout", "1200");
|
g_settings.set("client_delete_unused_sectors_timeout", "1200");
|
||||||
|
g_settings.set("max_block_send_distance", "8");
|
||||||
|
g_settings.set("max_block_generate_distance", "5");
|
||||||
|
|
||||||
// Server stuff
|
// Server stuff
|
||||||
g_settings.set("creative_mode", "false");
|
g_settings.set("creative_mode", "false");
|
||||||
|
@ -1489,13 +1311,12 @@ int main(int argc, char *argv[])
|
||||||
g_materials[i].setFlag(video::EMF_BILINEAR_FILTER, false);
|
g_materials[i].setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||||
//g_materials[i].setFlag(video::EMF_ANISOTROPIC_FILTER, false);
|
//g_materials[i].setFlag(video::EMF_ANISOTROPIC_FILTER, false);
|
||||||
//g_materials[i].setFlag(video::EMF_FOG_ENABLE, true);
|
//g_materials[i].setFlag(video::EMF_FOG_ENABLE, true);
|
||||||
if(i == MATERIAL_WATER)
|
|
||||||
{
|
|
||||||
g_materials[i].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
|
|
||||||
//g_materials[i].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_materials[MATERIAL_WATER].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
|
||||||
|
//g_materials[MATERIAL_WATER].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
|
||||||
|
g_materials[MATERIAL_OCEAN].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
|
||||||
|
|
||||||
/*g_mesh_materials[0].setTexture(0, driver->getTexture("../data/water.png"));
|
/*g_mesh_materials[0].setTexture(0, driver->getTexture("../data/water.png"));
|
||||||
g_mesh_materials[1].setTexture(0, driver->getTexture("../data/grass.png"));
|
g_mesh_materials[1].setTexture(0, driver->getTexture("../data/grass.png"));
|
||||||
g_mesh_materials[2].setTexture(0, driver->getTexture("../data/stone.png"));
|
g_mesh_materials[2].setTexture(0, driver->getTexture("../data/stone.png"));
|
||||||
|
|
81
src/map.cpp
81
src/map.cpp
|
@ -1819,7 +1819,8 @@ MapBlock * ServerMap::emergeBlock(
|
||||||
// If under water level, it's water
|
// If under water level, it's water
|
||||||
if(real_y < WATER_LEVEL)
|
if(real_y < WATER_LEVEL)
|
||||||
{
|
{
|
||||||
n.d = MATERIAL_WATER;
|
//n.d = MATERIAL_WATER;
|
||||||
|
n.d = MATERIAL_OCEAN;
|
||||||
n.setLight(diminish_light(LIGHT_SUN, WATER_LEVEL-real_y+1));
|
n.setLight(diminish_light(LIGHT_SUN, WATER_LEVEL-real_y+1));
|
||||||
}
|
}
|
||||||
// else air
|
// else air
|
||||||
|
@ -2731,34 +2732,6 @@ void ClientMap::renderMap(video::IVideoDriver* driver,
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
|
|
||||||
bool is_transparent_pass = pass == scene::ESNRP_TRANSPARENT;
|
bool is_transparent_pass = pass == scene::ESNRP_TRANSPARENT;
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
Draw master heightmap mesh
|
|
||||||
*/
|
|
||||||
|
|
||||||
{
|
|
||||||
JMutexAutoLock lock(mesh_mutex);
|
|
||||||
if(mesh != NULL)
|
|
||||||
{
|
|
||||||
u32 c = mesh->getMeshBufferCount();
|
|
||||||
|
|
||||||
for(u32 i=0; i<c; i++)
|
|
||||||
{
|
|
||||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
|
|
||||||
const video::SMaterial& material = buf->getMaterial();
|
|
||||||
video::IMaterialRenderer* rnd =
|
|
||||||
driver->getMaterialRenderer(material.MaterialType);
|
|
||||||
bool transparent = (rnd && rnd->isTransparent());
|
|
||||||
// Render transparent on transparent pass and likewise.
|
|
||||||
if(transparent == is_transparent_pass)
|
|
||||||
{
|
|
||||||
driver->setMaterial(buf->getMaterial());
|
|
||||||
driver->drawMeshBuffer(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get time for measuring timeout.
|
Get time for measuring timeout.
|
||||||
|
@ -3162,7 +3135,8 @@ MapVoxelManipulator::~MapVoxelManipulator()
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapVoxelManipulator::emerge(VoxelArea a)
|
#if 1
|
||||||
|
void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id)
|
||||||
{
|
{
|
||||||
TimeTaker timer1("emerge", g_device, &emerge_time);
|
TimeTaker timer1("emerge", g_device, &emerge_time);
|
||||||
|
|
||||||
|
@ -3190,8 +3164,11 @@ void MapVoxelManipulator::emerge(VoxelArea a)
|
||||||
{
|
{
|
||||||
TimeTaker timer1("emerge load", g_device, &emerge_load_time);
|
TimeTaker timer1("emerge load", g_device, &emerge_load_time);
|
||||||
|
|
||||||
dstream<<"Loading block ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
/*dstream<<"Loading block (caller_id="<<caller_id<<")"
|
||||||
<<std::endl;
|
<<" ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
||||||
|
<<" wanted area: ";
|
||||||
|
a.print(dstream);
|
||||||
|
dstream<<std::endl;*/
|
||||||
|
|
||||||
MapBlock *block = m_map->getBlockNoCreate(p);
|
MapBlock *block = m_map->getBlockNoCreate(p);
|
||||||
if(block->isDummy())
|
if(block->isDummy())
|
||||||
|
@ -3221,6 +3198,43 @@ void MapVoxelManipulator::emerge(VoxelArea a)
|
||||||
|
|
||||||
//dstream<<"emerge done"<<std::endl;
|
//dstream<<"emerge done"<<std::endl;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void MapVoxelManipulator::emerge(VoxelArea a)
|
||||||
|
{
|
||||||
|
TimeTaker timer1("emerge", g_device, &emerge_time);
|
||||||
|
|
||||||
|
v3s16 size = a.getExtent();
|
||||||
|
|
||||||
|
VoxelArea padded = a;
|
||||||
|
padded.pad(m_area.getExtent() / 4);
|
||||||
|
addArea(padded);
|
||||||
|
|
||||||
|
for(s16 z=0; z<size.Z; z++)
|
||||||
|
for(s16 y=0; y<size.Y; y++)
|
||||||
|
for(s16 x=0; x<size.X; x++)
|
||||||
|
{
|
||||||
|
v3s16 p(x,y,z);
|
||||||
|
s32 i = m_area.index(a.MinEdge + p);
|
||||||
|
// Don't touch nodes that have already been loaded
|
||||||
|
if(!(m_flags[i] & VOXELFLAG_NOT_LOADED))
|
||||||
|
continue;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TimeTaker timer1("emerge load", g_device, &emerge_load_time);
|
||||||
|
MapNode n = m_map->getNode(a.MinEdge + p);
|
||||||
|
m_data[i] = n;
|
||||||
|
m_flags[i] = 0;
|
||||||
|
}
|
||||||
|
catch(InvalidPositionException &e)
|
||||||
|
{
|
||||||
|
m_flags[i] = VOXELFLAG_INEXISTENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: Add an option to only update eg. water and air nodes.
|
TODO: Add an option to only update eg. water and air nodes.
|
||||||
|
@ -3230,6 +3244,9 @@ void MapVoxelManipulator::emerge(VoxelArea a)
|
||||||
void MapVoxelManipulator::blitBack
|
void MapVoxelManipulator::blitBack
|
||||||
(core::map<v3s16, MapBlock*> & modified_blocks)
|
(core::map<v3s16, MapBlock*> & modified_blocks)
|
||||||
{
|
{
|
||||||
|
if(m_area.getExtent() == v3s16(0,0,0))
|
||||||
|
return;
|
||||||
|
|
||||||
TimeTaker timer1("blitBack", g_device);
|
TimeTaker timer1("blitBack", g_device);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
11
src/map.h
11
src/map.h
|
@ -603,15 +603,18 @@ public:
|
||||||
m_loaded_blocks.clear();
|
m_loaded_blocks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void emerge(VoxelArea a);
|
virtual void emerge(VoxelArea a, s32 caller_id=-1);
|
||||||
|
|
||||||
void blitBack(core::map<v3s16, MapBlock*> & modified_blocks);
|
void blitBack(core::map<v3s16, MapBlock*> & modified_blocks);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Map *m_map;
|
Map *m_map;
|
||||||
// bool is dummy value
|
/*
|
||||||
// SUGG: How 'bout an another VoxelManipulator for storing the
|
NOTE: This might be used or not
|
||||||
// information about which block is loaded?
|
bool is dummy value
|
||||||
|
SUGG: How 'bout an another VoxelManipulator for storing the
|
||||||
|
information about which block is loaded?
|
||||||
|
*/
|
||||||
core::map<v3s16, bool> m_loaded_blocks;
|
core::map<v3s16, bool> m_loaded_blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ FastFace * MapBlock::makeFastFace(u8 material, u8 light, v3f p,
|
||||||
|
|
||||||
u8 alpha = 255;
|
u8 alpha = 255;
|
||||||
|
|
||||||
if(material == MATERIAL_WATER)
|
if(material == MATERIAL_WATER || material == MATERIAL_OCEAN)
|
||||||
{
|
{
|
||||||
alpha = 128;
|
alpha = 128;
|
||||||
}
|
}
|
||||||
|
@ -173,13 +173,14 @@ u8 MapBlock::getFaceLight(v3s16 p, v3s16 face_dir)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Gets node material from any place relative to block.
|
Gets node material from any place relative to block.
|
||||||
Returns MATERIAL_AIR if doesn't exist.
|
Returns MATERIAL_IGNORE if doesn't exist or should not be drawn.
|
||||||
*/
|
*/
|
||||||
u8 MapBlock::getNodeMaterial(v3s16 p)
|
u8 MapBlock::getNodeMaterial(v3s16 p)
|
||||||
{
|
{
|
||||||
try{
|
try{
|
||||||
MapNode n = getNodeParent(p);
|
MapNode n = getNodeParent(p);
|
||||||
return n.d;
|
|
||||||
|
return content_cube_material(n.d);
|
||||||
}
|
}
|
||||||
catch(InvalidPositionException &e)
|
catch(InvalidPositionException &e)
|
||||||
{
|
{
|
||||||
|
@ -470,46 +471,6 @@ void MapBlock::updateMesh()
|
||||||
|
|
||||||
collector.fillMesh(mesh_new);
|
collector.fillMesh(mesh_new);
|
||||||
|
|
||||||
#if 0
|
|
||||||
scene::IMeshBuffer *buf = NULL;
|
|
||||||
|
|
||||||
core::list<FastFace*>::Iterator i = fastfaces_new->begin();
|
|
||||||
|
|
||||||
// MATERIAL_AIR shouldn't be used by any face
|
|
||||||
u8 material_in_use = MATERIAL_AIR;
|
|
||||||
|
|
||||||
for(; i != fastfaces_new->end(); i++)
|
|
||||||
{
|
|
||||||
FastFace *f = *i;
|
|
||||||
|
|
||||||
if(f->material != material_in_use || buf == NULL)
|
|
||||||
{
|
|
||||||
// Try to get a meshbuffer associated with the material
|
|
||||||
buf = mesh_new->getMeshBuffer(g_materials[f->material]);
|
|
||||||
// If not found, create one
|
|
||||||
if(buf == NULL)
|
|
||||||
{
|
|
||||||
// This is a "Standard MeshBuffer",
|
|
||||||
// it's a typedeffed CMeshBuffer<video::S3DVertex>
|
|
||||||
buf = new scene::SMeshBuffer();
|
|
||||||
// Set material
|
|
||||||
((scene::SMeshBuffer*)buf)->Material = g_materials[f->material];
|
|
||||||
// Use VBO
|
|
||||||
//buf->setHardwareMappingHint(scene::EHM_STATIC);
|
|
||||||
// Add to mesh
|
|
||||||
mesh_new->addMeshBuffer(buf);
|
|
||||||
// Mesh grabbed it
|
|
||||||
buf->drop();
|
|
||||||
}
|
|
||||||
material_in_use = f->material;
|
|
||||||
}
|
|
||||||
|
|
||||||
u16 new_indices[] = {0,1,2,2,3,0};
|
|
||||||
|
|
||||||
//buf->append(f->vertices, 4, indices, 6);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
|
@ -517,8 +478,11 @@ void MapBlock::updateMesh()
|
||||||
<<"and uses "<<mesh_new->getMeshBufferCount()
|
<<"and uses "<<mesh_new->getMeshBufferCount()
|
||||||
<<" materials (meshbuffers)"<<std::endl;*/
|
<<" materials (meshbuffers)"<<std::endl;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Clear temporary FastFaces
|
||||||
|
*/
|
||||||
|
|
||||||
// TODO: Get rid of the FastFace stage
|
|
||||||
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++)
|
||||||
|
@ -528,6 +492,18 @@ void MapBlock::updateMesh()
|
||||||
fastfaces_new->clear();
|
fastfaces_new->clear();
|
||||||
delete fastfaces_new;
|
delete fastfaces_new;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add special graphics:
|
||||||
|
- torches
|
||||||
|
*/
|
||||||
|
|
||||||
|
for(s16 z=0; z<MAP_BLOCKSIZE; z++)
|
||||||
|
for(s16 y=0; y<MAP_BLOCKSIZE; y++)
|
||||||
|
for(s16 x=0; x<MAP_BLOCKSIZE; x++)
|
||||||
|
{
|
||||||
|
v3s16 p(x,y,z);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Replace the mesh
|
Replace the mesh
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -56,6 +56,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
GRAVEL
|
GRAVEL
|
||||||
- Dynamics of gravel: if there is a drop of more than two
|
- Dynamics of gravel: if there is a drop of more than two
|
||||||
blocks on any side, it will drop in there. Is this doable?
|
blocks on any side, it will drop in there. Is this doable?
|
||||||
|
|
||||||
|
TODO: These should be named to "content" or something like that
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum Material
|
enum Material
|
||||||
|
@ -77,6 +79,8 @@ enum Material
|
||||||
MATERIAL_MESE,
|
MATERIAL_MESE,
|
||||||
|
|
||||||
MATERIAL_MUD,
|
MATERIAL_MUD,
|
||||||
|
|
||||||
|
MATERIAL_OCEAN,
|
||||||
|
|
||||||
// This is set to the number of the actual values in this enum
|
// This is set to the number of the actual values in this enum
|
||||||
USEFUL_MATERIAL_COUNT
|
USEFUL_MATERIAL_COUNT
|
||||||
|
@ -88,7 +92,7 @@ enum Material
|
||||||
*/
|
*/
|
||||||
inline bool light_propagates_material(u8 m)
|
inline bool light_propagates_material(u8 m)
|
||||||
{
|
{
|
||||||
return (m == MATERIAL_AIR || m == MATERIAL_LIGHT || m == MATERIAL_WATER);
|
return (m == MATERIAL_AIR || m == MATERIAL_LIGHT || m == MATERIAL_WATER || m == MATERIAL_OCEAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -110,7 +114,7 @@ inline u8 material_solidness(u8 m)
|
||||||
{
|
{
|
||||||
if(m == MATERIAL_AIR)
|
if(m == MATERIAL_AIR)
|
||||||
return 0;
|
return 0;
|
||||||
if(m == MATERIAL_WATER)
|
if(m == MATERIAL_WATER || m == MATERIAL_OCEAN)
|
||||||
return 1;
|
return 1;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
@ -118,29 +122,54 @@ inline u8 material_solidness(u8 m)
|
||||||
// Objects collide with walkable materials
|
// Objects collide with walkable materials
|
||||||
inline bool material_walkable(u8 m)
|
inline bool material_walkable(u8 m)
|
||||||
{
|
{
|
||||||
return (m != MATERIAL_AIR && m != MATERIAL_WATER);
|
return (m != MATERIAL_AIR && m != MATERIAL_WATER && m != MATERIAL_OCEAN && m != MATERIAL_LIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A liquid resists fast movement
|
// A liquid resists fast movement
|
||||||
inline bool material_liquid(u8 m)
|
inline bool material_liquid(u8 m)
|
||||||
{
|
{
|
||||||
return (m == MATERIAL_WATER);
|
return (m == MATERIAL_WATER || m == MATERIAL_OCEAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pointable materials can be pointed to in the map
|
// Pointable materials can be pointed to in the map
|
||||||
inline bool material_pointable(u8 m)
|
inline bool material_pointable(u8 m)
|
||||||
{
|
{
|
||||||
return (m != MATERIAL_AIR && m != MATERIAL_WATER);
|
return (m != MATERIAL_AIR && m != MATERIAL_WATER && m != MATERIAL_OCEAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool material_diggable(u8 m)
|
inline bool material_diggable(u8 m)
|
||||||
{
|
{
|
||||||
return (m != MATERIAL_AIR && m != MATERIAL_WATER);
|
return (m != MATERIAL_AIR && m != MATERIAL_WATER && m != MATERIAL_OCEAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool material_buildable_to(u8 m)
|
inline bool material_buildable_to(u8 m)
|
||||||
{
|
{
|
||||||
return (m == MATERIAL_AIR || m == MATERIAL_WATER);
|
return (m == MATERIAL_AIR || m == MATERIAL_WATER || m == MATERIAL_OCEAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
As of now, input is a "material" and the output is a "material"
|
||||||
|
*/
|
||||||
|
inline u8 content_cube_material(u8 c)
|
||||||
|
{
|
||||||
|
if(c == MATERIAL_IGNORE || c == MATERIAL_LIGHT)
|
||||||
|
return MATERIAL_AIR;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns true for materials that form the base ground that
|
||||||
|
follows the main heightmap
|
||||||
|
*/
|
||||||
|
inline bool is_ground_material(u8 m)
|
||||||
|
{
|
||||||
|
return(
|
||||||
|
m == MATERIAL_STONE ||
|
||||||
|
m == MATERIAL_GRASS ||
|
||||||
|
m == MATERIAL_GRASS_FOOTSTEPS ||
|
||||||
|
m == MATERIAL_MESE ||
|
||||||
|
m == MATERIAL_MUD
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -168,21 +197,6 @@ inline u8 face_materials(u8 m1, u8 m2)
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Returns true for materials that form the base ground that
|
|
||||||
follows the main heightmap
|
|
||||||
*/
|
|
||||||
inline bool is_ground_material(u8 m)
|
|
||||||
{
|
|
||||||
return(
|
|
||||||
m == MATERIAL_STONE ||
|
|
||||||
m == MATERIAL_GRASS ||
|
|
||||||
m == MATERIAL_GRASS_FOOTSTEPS ||
|
|
||||||
m == MATERIAL_MESE ||
|
|
||||||
m == MATERIAL_MUD
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MapNode
|
struct MapNode
|
||||||
{
|
{
|
||||||
//TODO: block type to differ from material
|
//TODO: block type to differ from material
|
||||||
|
@ -214,7 +228,9 @@ struct MapNode
|
||||||
|
|
||||||
bool operator==(const MapNode &other)
|
bool operator==(const MapNode &other)
|
||||||
{
|
{
|
||||||
return (d == other.d && param == other.param);
|
return (d == other.d
|
||||||
|
&& param == other.param
|
||||||
|
&& pressure == other.pressure);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool light_propagates()
|
bool light_propagates()
|
||||||
|
|
|
@ -196,6 +196,28 @@ void * EmergeThread::Thread()
|
||||||
{
|
{
|
||||||
MapBlock *block = i.getNode()->getValue();
|
MapBlock *block = i.getNode()->getValue();
|
||||||
modified_blocks.insert(block->getPos(), block);
|
modified_blocks.insert(block->getPos(), block);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update water pressure.
|
||||||
|
This also adds suitable nodes to active_nodes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MapVoxelManipulator v(&map);
|
||||||
|
|
||||||
|
VoxelArea area(block->getPosRelative(),
|
||||||
|
block->getPosRelative() + v3s16(1,1,1)*(MAP_BLOCKSIZE-1));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
v.updateAreaWaterPressure(area, m_server->m_flow_active_nodes);
|
||||||
|
}
|
||||||
|
catch(ProcessingLimitException &e)
|
||||||
|
{
|
||||||
|
dstream<<"Processing limit reached (1)"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
v.blitBack(modified_blocks);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*dstream<<"lighting "<<lighting_invalidated_blocks.size()
|
/*dstream<<"lighting "<<lighting_invalidated_blocks.size()
|
||||||
|
@ -244,12 +266,6 @@ void * EmergeThread::Thread()
|
||||||
// Remove block from sent history
|
// Remove block from sent history
|
||||||
client->SetBlocksNotSent(modified_blocks);
|
client->SetBlocksNotSent(modified_blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if(q->peer_ids.find(client->peer_id) != NULL)
|
|
||||||
{
|
|
||||||
// Decrement emerge queue count of client
|
|
||||||
client->BlockEmerged();
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -348,14 +364,8 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||||
|
|
||||||
//bool has_incomplete_blocks = false;
|
//bool has_incomplete_blocks = false;
|
||||||
|
|
||||||
/*
|
s16 d_max = g_settings.getS16("max_block_send_distance");
|
||||||
TODO: Get this from somewhere
|
s16 d_max_gen = g_settings.getS16("max_block_generate_distance");
|
||||||
*/
|
|
||||||
//s16 d_max = 7;
|
|
||||||
s16 d_max = 8;
|
|
||||||
|
|
||||||
//TODO: Get this from somewhere (probably a bigger value)
|
|
||||||
s16 d_max_gen = 5;
|
|
||||||
|
|
||||||
//dstream<<"Starting from "<<d_start<<std::endl;
|
//dstream<<"Starting from "<<d_start<<std::endl;
|
||||||
|
|
||||||
|
@ -998,7 +1008,7 @@ void Server::AsyncRunStep()
|
||||||
{
|
{
|
||||||
static float counter = 0.0;
|
static float counter = 0.0;
|
||||||
counter += dtime;
|
counter += dtime;
|
||||||
if(counter >= 1.0)
|
if(counter >= 0.25 && m_flow_active_nodes.size() > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
counter = 0.0;
|
counter = 0.0;
|
||||||
|
@ -1011,16 +1021,7 @@ void Server::AsyncRunStep()
|
||||||
|
|
||||||
MapVoxelManipulator v(&m_env.getMap());
|
MapVoxelManipulator v(&m_env.getMap());
|
||||||
|
|
||||||
/*try{
|
v.flowWater(m_flow_active_nodes, 0, false, 50);
|
||||||
v.flowWater(m_flow_active_nodes, 0, false, 20);
|
|
||||||
//v.flowWater(p_under, 0, true, 100);
|
|
||||||
}
|
|
||||||
catch(ProcessingLimitException &e)
|
|
||||||
{
|
|
||||||
dstream<<"Processing limit reached"<<std::endl;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
v.flowWater(m_flow_active_nodes, 0, false, 20);
|
|
||||||
|
|
||||||
v.blitBack(modified_blocks);
|
v.blitBack(modified_blocks);
|
||||||
|
|
||||||
|
@ -1059,7 +1060,7 @@ void Server::AsyncRunStep()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // interval counter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Periodically print some info
|
// Periodically print some info
|
||||||
|
@ -1547,7 +1548,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
}
|
}
|
||||||
catch(ProcessingLimitException &e)
|
catch(ProcessingLimitException &e)
|
||||||
{
|
{
|
||||||
dstream<<"Processing limit reached"<<std::endl;
|
dstream<<"Processing limit reached (1)"<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
v.blitBack(modified_blocks);
|
v.blitBack(modified_blocks);
|
||||||
|
@ -1624,6 +1625,28 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
*/
|
*/
|
||||||
core::map<v3s16, MapBlock*> modified_blocks;
|
core::map<v3s16, MapBlock*> modified_blocks;
|
||||||
m_env.getMap().addNodeAndUpdate(p_over, n, modified_blocks);
|
m_env.getMap().addNodeAndUpdate(p_over, n, modified_blocks);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update water
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Update water pressure around modification
|
||||||
|
// This also adds it to m_flow_active_nodes if appropriate
|
||||||
|
|
||||||
|
MapVoxelManipulator v(&m_env.getMap());
|
||||||
|
|
||||||
|
VoxelArea area(p_over-v3s16(1,1,1), p_over+v3s16(1,1,1));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
v.updateAreaWaterPressure(area, m_flow_active_nodes);
|
||||||
|
}
|
||||||
|
catch(ProcessingLimitException &e)
|
||||||
|
{
|
||||||
|
dstream<<"Processing limit reached (1)"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
v.blitBack(modified_blocks);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Handle block object items
|
Handle block object items
|
||||||
|
@ -2019,6 +2042,10 @@ void Server::peerAdded(con::Peer *peer)
|
||||||
assert(USEFUL_MATERIAL_COUNT <= PLAYER_INVENTORY_SIZE);
|
assert(USEFUL_MATERIAL_COUNT <= PLAYER_INVENTORY_SIZE);
|
||||||
for(u16 i=0; i<USEFUL_MATERIAL_COUNT; i++)
|
for(u16 i=0; i<USEFUL_MATERIAL_COUNT; i++)
|
||||||
{
|
{
|
||||||
|
// Skip some materials
|
||||||
|
if(i == MATERIAL_OCEAN)
|
||||||
|
continue;
|
||||||
|
|
||||||
InventoryItem *item = new MaterialItem(i, 1);
|
InventoryItem *item = new MaterialItem(i, 1);
|
||||||
player->inventory.addItem(item);
|
player->inventory.addItem(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -264,11 +264,13 @@ struct TestVoxelManipulator
|
||||||
s16 highest_y = -32768;
|
s16 highest_y = -32768;
|
||||||
assert(v.getWaterPressure(v3s16(7, 1, 1), highest_y, 0) == -1);
|
assert(v.getWaterPressure(v3s16(7, 1, 1), highest_y, 0) == -1);
|
||||||
assert(highest_y == 3);
|
assert(highest_y == 3);
|
||||||
|
/*assert(v.getWaterPressure(v3s16(7, 1, 1), highest_y, 0) == 3);
|
||||||
|
//assert(highest_y == 3);*/
|
||||||
|
|
||||||
active_nodes.clear();
|
active_nodes.clear();
|
||||||
active_nodes[v3s16(9,1,0)] = 1;
|
active_nodes[v3s16(9,1,0)] = 1;
|
||||||
//v.flowWater(active_nodes, 0, false);
|
//v.flowWater(active_nodes, 0, false);
|
||||||
v.flowWater(active_nodes, 0, true);
|
v.flowWater(active_nodes, 0, true, 1000);
|
||||||
|
|
||||||
dstream<<"Final result of flowWater:"<<std::endl;
|
dstream<<"Final result of flowWater:"<<std::endl;
|
||||||
v.print(dstream, VOXELPRINT_WATERPRESSURE);
|
v.print(dstream, VOXELPRINT_WATERPRESSURE);
|
||||||
|
|
199
src/voxel.cpp
199
src/voxel.cpp
|
@ -335,23 +335,26 @@ int VoxelManipulator::getWaterPressure(v3s16 p, s16 &highest_y, int recur_count)
|
||||||
if(p.Y > highest_y)
|
if(p.Y > highest_y)
|
||||||
highest_y = p.Y;
|
highest_y = p.Y;
|
||||||
|
|
||||||
recur_count++;
|
/*if(recur_count > 1000)
|
||||||
if(recur_count > 30)
|
|
||||||
throw ProcessingLimitException
|
throw ProcessingLimitException
|
||||||
("getWaterPressure recur_count limit reached");
|
("getWaterPressure recur_count limit reached");*/
|
||||||
|
|
||||||
|
if(recur_count > 10000)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
recur_count++;
|
||||||
|
|
||||||
v3s16 dirs[6] = {
|
v3s16 dirs[6] = {
|
||||||
v3s16(0,1,0), // top
|
v3s16(0,1,0), // top
|
||||||
v3s16(-1,0,0), // left
|
|
||||||
v3s16(1,0,0), // right
|
|
||||||
v3s16(0,0,-1), // front
|
|
||||||
v3s16(0,0,1), // back
|
v3s16(0,0,1), // back
|
||||||
|
v3s16(0,0,-1), // front
|
||||||
|
v3s16(1,0,0), // right
|
||||||
|
v3s16(-1,0,0), // left
|
||||||
v3s16(0,-1,0), // bottom
|
v3s16(0,-1,0), // bottom
|
||||||
};
|
};
|
||||||
|
|
||||||
// Load neighboring nodes
|
// Load neighboring nodes
|
||||||
// TODO: A bigger area would be better
|
emerge(VoxelArea(p - v3s16(1,1,1), p + v3s16(1,1,1)), 1);
|
||||||
emerge(VoxelArea(p - v3s16(1,1,1), p + v3s16(1,1,1)));
|
|
||||||
|
|
||||||
s32 i;
|
s32 i;
|
||||||
for(i=0; i<6; i++)
|
for(i=0; i<6; i++)
|
||||||
|
@ -367,14 +370,14 @@ int VoxelManipulator::getWaterPressure(v3s16 p, s16 &highest_y, int recur_count)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int pr;
|
int pr;
|
||||||
|
|
||||||
// If at surface
|
// If at ocean surface
|
||||||
/*if(n.pressure == 1)
|
if(n.pressure == 1 && n.d == MATERIAL_OCEAN)
|
||||||
{
|
{
|
||||||
pr = 1;
|
pr = 1;
|
||||||
}
|
}
|
||||||
// Otherwise recurse more
|
// Otherwise recurse more
|
||||||
else*/
|
else
|
||||||
{
|
{
|
||||||
pr = getWaterPressure(p2, highest_y, recur_count);
|
pr = getWaterPressure(p2, highest_y, recur_count);
|
||||||
if(pr == -1)
|
if(pr == -1)
|
||||||
|
@ -410,10 +413,21 @@ void VoxelManipulator::spreadWaterPressure(v3s16 p, int pr,
|
||||||
core::map<v3s16, u8> &active_nodes,
|
core::map<v3s16, u8> &active_nodes,
|
||||||
int recur_count)
|
int recur_count)
|
||||||
{
|
{
|
||||||
|
//if(recur_count > 10000)
|
||||||
|
/*throw ProcessingLimitException
|
||||||
|
("spreadWaterPressure recur_count limit reached");*/
|
||||||
|
if(recur_count > 10)
|
||||||
|
return;
|
||||||
recur_count++;
|
recur_count++;
|
||||||
if(recur_count > 10000)
|
|
||||||
throw ProcessingLimitException
|
/*dstream<<"spreadWaterPressure: p=("
|
||||||
("spreadWaterPressure recur_count limit reached");
|
<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
||||||
|
<<", oldpr="<<(int)m_data[m_area.index(p)].pressure
|
||||||
|
<<", pr="<<pr
|
||||||
|
<<", recur_count="<<recur_count
|
||||||
|
<<", request_area=";
|
||||||
|
request_area.print(dstream);
|
||||||
|
dstream<<std::endl;*/
|
||||||
|
|
||||||
m_flags[m_area.index(p)] |= VOXELFLAG_CHECKED3;
|
m_flags[m_area.index(p)] |= VOXELFLAG_CHECKED3;
|
||||||
m_data[m_area.index(p)].pressure = pr;
|
m_data[m_area.index(p)].pressure = pr;
|
||||||
|
@ -428,7 +442,7 @@ void VoxelManipulator::spreadWaterPressure(v3s16 p, int pr,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Load neighboring nodes
|
// Load neighboring nodes
|
||||||
emerge(VoxelArea(p - v3s16(1,1,1), p + v3s16(1,1,1)));
|
emerge(VoxelArea(p - v3s16(1,1,1), p + v3s16(1,1,1)), 2);
|
||||||
|
|
||||||
s32 i;
|
s32 i;
|
||||||
for(i=0; i<6; i++)
|
for(i=0; i<6; i++)
|
||||||
|
@ -455,6 +469,7 @@ void VoxelManipulator::spreadWaterPressure(v3s16 p, int pr,
|
||||||
// If block is at top
|
// If block is at top
|
||||||
if(i == 0)
|
if(i == 0)
|
||||||
{
|
{
|
||||||
|
//if(pr >= PRESERVE_WATER_VOLUME ? 3 : 2)
|
||||||
if(pr >= 3)
|
if(pr >= 3)
|
||||||
pressure_causes_flow = true;
|
pressure_causes_flow = true;
|
||||||
}
|
}
|
||||||
|
@ -466,6 +481,7 @@ void VoxelManipulator::spreadWaterPressure(v3s16 p, int pr,
|
||||||
// If block is at side
|
// If block is at side
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//if(pr >= PRESERVE_WATER_VOLUME ? 2 : 1)
|
||||||
if(pr >= 2)
|
if(pr >= 2)
|
||||||
pressure_causes_flow = true;
|
pressure_causes_flow = true;
|
||||||
}
|
}
|
||||||
|
@ -497,7 +513,10 @@ void VoxelManipulator::spreadWaterPressure(v3s16 p, int pr,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore if correct pressure is already set and is not on
|
// Ignore if correct pressure is already set and is not on
|
||||||
// request_area
|
// request_area.
|
||||||
|
// Thus, request_area can be used for updating as much
|
||||||
|
// pressure info in some area as possible to possibly
|
||||||
|
// make some calls to getWaterPressure unnecessary.
|
||||||
if(n.pressure == pr2 && request_area.contains(p2) == false)
|
if(n.pressure == pr2 && request_area.contains(p2) == false)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -512,7 +531,7 @@ void VoxelManipulator::updateAreaWaterPressure(VoxelArea a,
|
||||||
TimeTaker timer("updateAreaWaterPressure", g_device,
|
TimeTaker timer("updateAreaWaterPressure", g_device,
|
||||||
&updateareawaterpressure_time);
|
&updateareawaterpressure_time);
|
||||||
|
|
||||||
emerge(a);
|
emerge(a, 3);
|
||||||
|
|
||||||
bool checked2_clear = false;
|
bool checked2_clear = false;
|
||||||
|
|
||||||
|
@ -596,20 +615,21 @@ void VoxelManipulator::updateAreaWaterPressure(VoxelArea a,
|
||||||
bool VoxelManipulator::flowWater(v3s16 removed_pos,
|
bool VoxelManipulator::flowWater(v3s16 removed_pos,
|
||||||
core::map<v3s16, u8> &active_nodes,
|
core::map<v3s16, u8> &active_nodes,
|
||||||
int recursion_depth, bool debugprint,
|
int recursion_depth, bool debugprint,
|
||||||
int *counter, int counterlimit)
|
u32 stoptime)
|
||||||
{
|
{
|
||||||
v3s16 dirs[6] = {
|
v3s16 dirs[6] = {
|
||||||
v3s16(0,1,0), // top
|
v3s16(0,1,0), // top
|
||||||
v3s16(-1,0,0), // left
|
|
||||||
v3s16(1,0,0), // right
|
|
||||||
v3s16(0,0,-1), // front
|
v3s16(0,0,-1), // front
|
||||||
v3s16(0,0,1), // back
|
v3s16(0,0,1), // back
|
||||||
|
v3s16(-1,0,0), // left
|
||||||
|
v3s16(1,0,0), // right
|
||||||
v3s16(0,-1,0), // bottom
|
v3s16(0,-1,0), // bottom
|
||||||
};
|
};
|
||||||
|
|
||||||
recursion_depth++;
|
recursion_depth++;
|
||||||
|
|
||||||
v3s16 p;
|
v3s16 p;
|
||||||
|
bool from_ocean = false;
|
||||||
|
|
||||||
// Randomize horizontal order
|
// Randomize horizontal order
|
||||||
static s32 cs = 0;
|
static s32 cs = 0;
|
||||||
|
@ -625,7 +645,7 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
|
||||||
TimeTaker timer1("flowWater pre", g_device, &flowwater_pre_time);
|
TimeTaker timer1("flowWater pre", g_device, &flowwater_pre_time);
|
||||||
|
|
||||||
// Load neighboring nodes
|
// Load neighboring nodes
|
||||||
emerge(VoxelArea(removed_pos - v3s16(1,1,1), removed_pos + v3s16(1,1,1)));
|
emerge(VoxelArea(removed_pos - v3s16(1,1,1), removed_pos + v3s16(1,1,1)), 4);
|
||||||
|
|
||||||
// Ignore incorrect removed_pos
|
// Ignore incorrect removed_pos
|
||||||
{
|
{
|
||||||
|
@ -660,11 +680,13 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
|
||||||
// If block is at bottom, select it if it has enough pressure
|
// If block is at bottom, select it if it has enough pressure
|
||||||
if(i == 5)
|
if(i == 5)
|
||||||
{
|
{
|
||||||
|
//if(n.pressure >= PRESERVE_WATER_VOLUME ? 3 : 2)
|
||||||
if(n.pressure >= 3)
|
if(n.pressure >= 3)
|
||||||
break;
|
break;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Else block is at some side. Select it if it has enough pressure
|
// Else block is at some side. Select it if it has enough pressure
|
||||||
|
//if(n.pressure >= PRESERVE_WATER_VOLUME ? 2 : 1)
|
||||||
if(n.pressure >= 2)
|
if(n.pressure >= 2)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -675,22 +697,47 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
|
||||||
if(i==6)
|
if(i==6)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Switch nodes at p and removed_pos
|
/*
|
||||||
|
Move water and bubble
|
||||||
|
*/
|
||||||
|
|
||||||
u8 m = m_data[m_area.index(p)].d;
|
u8 m = m_data[m_area.index(p)].d;
|
||||||
u8 f = m_flags[m_area.index(p)];
|
u8 f = m_flags[m_area.index(p)];
|
||||||
m_data[m_area.index(p)].d = m_data[m_area.index(removed_pos)].d;
|
|
||||||
m_flags[m_area.index(p)] = m_flags[m_area.index(removed_pos)];
|
if(m == MATERIAL_OCEAN)
|
||||||
|
from_ocean = true;
|
||||||
|
|
||||||
|
// Move air bubble if not taking water from ocean
|
||||||
|
if(from_ocean == false)
|
||||||
|
{
|
||||||
|
m_data[m_area.index(p)].d = m_data[m_area.index(removed_pos)].d;
|
||||||
|
m_flags[m_area.index(p)] = m_flags[m_area.index(removed_pos)];
|
||||||
|
}
|
||||||
|
|
||||||
m_data[m_area.index(removed_pos)].d = m;
|
m_data[m_area.index(removed_pos)].d = m;
|
||||||
m_flags[m_area.index(removed_pos)] = f;
|
m_flags[m_area.index(removed_pos)] = f;
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
||||||
// If block was dropped from surface, increase pressure
|
// If block was dropped from surface, increase pressure
|
||||||
if(i == 0 && m_data[m_area.index(removed_pos)].pressure == 1)
|
if(i == 0 && m_data[m_area.index(removed_pos)].pressure == 1)
|
||||||
{
|
{
|
||||||
m_data[m_area.index(removed_pos)].pressure = 2;
|
m_data[m_area.index(removed_pos)].pressure = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
NOTE: This does not work as-is
|
||||||
|
if(m == MATERIAL_OCEAN)
|
||||||
|
{
|
||||||
|
// If block was raised to surface, increase pressure of
|
||||||
|
// source node
|
||||||
|
if(i == 5 && m_data[m_area.index(p)].pressure == 1)
|
||||||
|
{
|
||||||
|
m_data[m_area.index(p)].pressure = 2;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
/*if(debugprint)
|
/*if(debugprint)
|
||||||
{
|
{
|
||||||
dstream<<"VoxelManipulator::flowWater(): Moved bubble:"<<std::endl;
|
dstream<<"VoxelManipulator::flowWater(): Moved bubble:"<<std::endl;
|
||||||
|
@ -720,12 +767,30 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
|
||||||
}
|
}
|
||||||
|
|
||||||
}//timer1
|
}//timer1
|
||||||
|
|
||||||
// Flow water to the newly created empty position
|
//if(PRESERVE_WATER_VOLUME)
|
||||||
flowWater(p, active_nodes, recursion_depth,
|
if(from_ocean == false)
|
||||||
debugprint, counter, counterlimit);
|
{
|
||||||
|
// Flow water to the newly created empty position
|
||||||
|
/*flowWater(p, active_nodes, recursion_depth,
|
||||||
|
debugprint, counter, counterlimit);*/
|
||||||
|
flowWater(p, active_nodes, recursion_depth,
|
||||||
|
debugprint, stoptime);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stoptime != 0 && g_device != NULL)
|
||||||
|
{
|
||||||
|
u32 timenow = g_device->getTimer()->getRealTime();
|
||||||
|
if(timenow >= stoptime ||
|
||||||
|
(stoptime < 0x80000000 && timenow > 0x80000000))
|
||||||
|
{
|
||||||
|
dstream<<"flowWater: stoptime reached"<<std::endl;
|
||||||
|
throw ProcessingLimitException("flowWater stoptime reached");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
find_again:
|
find_again:
|
||||||
|
|
||||||
// Try flowing water to empty positions around removed_pos.
|
// Try flowing water to empty positions around removed_pos.
|
||||||
// They are checked in reverse order compared to the previous loop.
|
// They are checked in reverse order compared to the previous loop.
|
||||||
for(s32 i=5; i>=0; i--)
|
for(s32 i=5; i>=0; i--)
|
||||||
|
@ -745,7 +810,9 @@ find_again:
|
||||||
// Flow water to node
|
// Flow water to node
|
||||||
bool moved =
|
bool moved =
|
||||||
flowWater(p, active_nodes, recursion_depth,
|
flowWater(p, active_nodes, recursion_depth,
|
||||||
debugprint, counter, counterlimit);
|
debugprint, stoptime);
|
||||||
|
/*flowWater(p, active_nodes, recursion_depth,
|
||||||
|
debugprint, counter, counterlimit);*/
|
||||||
|
|
||||||
if(moved)
|
if(moved)
|
||||||
{
|
{
|
||||||
|
@ -754,27 +821,13 @@ find_again:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(counter != NULL)
|
|
||||||
{
|
|
||||||
(*counter)++;
|
|
||||||
if((*counter) % 10 == 0)
|
|
||||||
dstream<<"flowWater(): moved "<<(*counter)<<" nodes"
|
|
||||||
<<std::endl;
|
|
||||||
|
|
||||||
if(counterlimit != -1 && (*counter) > counterlimit)
|
|
||||||
{
|
|
||||||
dstream<<"Counter limit reached; returning"<<std::endl;
|
|
||||||
throw ProcessingLimitException("flowWater counterlimit reached");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelManipulator::flowWater(
|
void VoxelManipulator::flowWater(
|
||||||
core::map<v3s16, u8> &active_nodes,
|
core::map<v3s16, u8> &active_nodes,
|
||||||
int recursion_depth, bool debugprint,
|
int recursion_depth, bool debugprint,
|
||||||
int counterlimit)
|
u32 timelimit)
|
||||||
{
|
{
|
||||||
addarea_time = 0;
|
addarea_time = 0;
|
||||||
emerge_time = 0;
|
emerge_time = 0;
|
||||||
|
@ -783,25 +836,53 @@ void VoxelManipulator::flowWater(
|
||||||
updateareawaterpressure_time = 0;
|
updateareawaterpressure_time = 0;
|
||||||
flowwater_pre_time = 0;
|
flowwater_pre_time = 0;
|
||||||
|
|
||||||
|
if(active_nodes.size() == 0)
|
||||||
|
{
|
||||||
|
dstream<<"flowWater: no active nodes"<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TimeTaker timer1("flowWater (active_nodes)", g_device);
|
TimeTaker timer1("flowWater (active_nodes)", g_device);
|
||||||
|
|
||||||
dstream<<"active_nodes.size() = "<<active_nodes.size()<<std::endl;
|
dstream<<"active_nodes.size() = "<<active_nodes.size()<<std::endl;
|
||||||
|
|
||||||
int counter = 0;
|
//int counter = 0;
|
||||||
|
|
||||||
|
u32 stoptime = 0;
|
||||||
|
if(g_device != NULL)
|
||||||
|
{
|
||||||
|
stoptime = g_device->getTimer()->getRealTime() + timelimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count of handled active nodes
|
||||||
|
u32 handled_count = 0;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
Take random one at first
|
||||||
|
|
||||||
|
This is randomized only at the first time so that all
|
||||||
|
subsequent nodes will be taken at roughly the same position
|
||||||
|
*/
|
||||||
|
s32 k = 0;
|
||||||
|
if(active_nodes.size() != 0)
|
||||||
|
k = (s32)rand() % (s32)active_nodes.size();
|
||||||
|
|
||||||
// Flow water to active nodes
|
// Flow water to active nodes
|
||||||
for(;;)
|
for(;;)
|
||||||
|
//for(s32 h=0; h<1; h++)
|
||||||
{
|
{
|
||||||
// Clear check flags
|
|
||||||
clearFlag(VOXELFLAG_CHECKED);
|
|
||||||
|
|
||||||
if(active_nodes.size() == 0)
|
if(active_nodes.size() == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
dstream<<"Selecting a new active_node"<<std::endl;
|
handled_count++;
|
||||||
|
|
||||||
|
// Clear check flags
|
||||||
|
clearFlag(VOXELFLAG_CHECKED);
|
||||||
|
|
||||||
|
//dstream<<"Selecting a new active_node"<<std::endl;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Take first one
|
// Take first one
|
||||||
|
@ -810,9 +891,7 @@ void VoxelManipulator::flowWater(
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// Take random one
|
|
||||||
s32 k = (s32)rand() % (s32)active_nodes.size();
|
|
||||||
//s32 k = 0;
|
|
||||||
core::map<v3s16, u8>::Iterator
|
core::map<v3s16, u8>::Iterator
|
||||||
i = active_nodes.getIterator().getNode();
|
i = active_nodes.getIterator().getNode();
|
||||||
for(s32 j=0; j<k; j++)
|
for(s32 j=0; j<k; j++)
|
||||||
|
@ -820,12 +899,17 @@ void VoxelManipulator::flowWater(
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
core::map<v3s16, u8>::Node *n = i.getNode();
|
core::map<v3s16, u8>::Node *n = i.getNode();
|
||||||
|
|
||||||
|
// Decrement index if less than 0.
|
||||||
|
// This keeps us in existing indices always.
|
||||||
|
if(k > 0)
|
||||||
|
k--;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
v3s16 p = n->getKey();
|
v3s16 p = n->getKey();
|
||||||
active_nodes.remove(p);
|
active_nodes.remove(p);
|
||||||
flowWater(p, active_nodes, recursion_depth,
|
flowWater(p, active_nodes, recursion_depth,
|
||||||
debugprint, &counter, counterlimit);
|
debugprint, stoptime);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -836,11 +920,14 @@ void VoxelManipulator::flowWater(
|
||||||
|
|
||||||
v3s16 e = m_area.getExtent();
|
v3s16 e = m_area.getExtent();
|
||||||
s32 v = m_area.getVolume();
|
s32 v = m_area.getVolume();
|
||||||
dstream<<"flowWater (active): moved "<<counter<<" nodes, "
|
//dstream<<"flowWater (active): moved "<<counter<<" nodes, "
|
||||||
|
dstream<<"flowWater (active): "
|
||||||
<<"area ended up as "
|
<<"area ended up as "
|
||||||
<<e.X<<"x"<<e.Y<<"x"<<e.Z<<" = "<<v
|
<<e.X<<"x"<<e.Y<<"x"<<e.Z<<" = "<<v
|
||||||
|
<<", handled a_node count: "<<handled_count
|
||||||
|
<<", active_nodes.size() = "<<active_nodes.size()
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
|
|
||||||
dstream<<"addarea_time: "<<addarea_time
|
dstream<<"addarea_time: "<<addarea_time
|
||||||
<<", emerge_time: "<<emerge_time
|
<<", emerge_time: "<<emerge_time
|
||||||
<<", emerge_load_time: "<<emerge_load_time
|
<<", emerge_load_time: "<<emerge_load_time
|
||||||
|
|
|
@ -428,8 +428,8 @@ public:
|
||||||
bool flowWater(v3s16 removed_pos,
|
bool flowWater(v3s16 removed_pos,
|
||||||
core::map<v3s16, u8> &active_nodes,
|
core::map<v3s16, u8> &active_nodes,
|
||||||
int recursion_depth=0,
|
int recursion_depth=0,
|
||||||
bool debugprint=false, int *counter=NULL,
|
bool debugprint=false,
|
||||||
int counterlimit=-1
|
u32 stoptime=0
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -446,7 +446,7 @@ public:
|
||||||
void flowWater(core::map<v3s16, u8> &active_nodes,
|
void flowWater(core::map<v3s16, u8> &active_nodes,
|
||||||
int recursion_depth=0,
|
int recursion_depth=0,
|
||||||
bool debugprint=false,
|
bool debugprint=false,
|
||||||
int counterlimit=-1
|
u32 timelimit=50
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -460,7 +460,7 @@ public:
|
||||||
|
|
||||||
If not found from source, add with VOXELFLAG_INEXISTENT
|
If not found from source, add with VOXELFLAG_INEXISTENT
|
||||||
*/
|
*/
|
||||||
virtual void emerge(VoxelArea a)
|
virtual void emerge(VoxelArea a, s32 caller_id=-1)
|
||||||
{
|
{
|
||||||
//dstream<<"emerge p=("<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;
|
//dstream<<"emerge p=("<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;
|
||||||
addArea(a);
|
addArea(a);
|
||||||
|
|
Loading…
Reference in New Issue