Modified block mesh generation to have clearer input and output. Instead of being a messy object oriented cludge, it now is a messy cludge with separate parameters.

This commit is contained in:
Perttu Ahola 2011-04-03 19:50:54 +03:00
parent 01c2b003e1
commit e0f7bd4d57
9 changed files with 240 additions and 83 deletions

@ -1238,6 +1238,35 @@ bool Client::AsyncProcessPacket()
block->deSerialize(istr, ser_version); block->deSerialize(istr, ser_version);
sector->insertBlock(block); sector->insertBlock(block);
//block->setChangedFlag(); //block->setChangedFlag();
//DEBUG
/*NodeMod mod;
mod.type = NODEMOD_CHANGECONTENT;
mod.param = CONTENT_MESE;
block->setTempMod(v3s16(8,10,8), mod);
block->setTempMod(v3s16(8,9,8), mod);
block->setTempMod(v3s16(8,8,8), mod);
block->setTempMod(v3s16(8,7,8), mod);
block->setTempMod(v3s16(8,6,8), mod);*/
/*
Add some coulds
Well, this is a dumb way to do it, they should just
be drawn as separate objects.
*/
/*if(p.Y == 3)
{
NodeMod mod;
mod.type = NODEMOD_CHANGECONTENT;
mod.param = CONTENT_CLOUD;
v3s16 p2;
p2.Y = 8;
for(p2.X=3; p2.X<=13; p2.X++)
for(p2.Z=3; p2.Z<=13; p2.Z++)
{
block->setTempMod(p2, mod);
}
}*/
} }
} //envlock } //envlock

@ -891,7 +891,8 @@ void ClientEnvironment::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_daynight_ratio); //b->updateMesh(m_daynight_ratio);
b->setMeshExpired(true);
} }
} }
} }

@ -5482,8 +5482,8 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
mesh_update_count++; mesh_update_count++;
// Mesh has been expired: generate new mesh // Mesh has been expired: generate new mesh
//block->updateMeshes(daynight_i);
block->updateMesh(daynight_ratio); block->updateMesh(daynight_ratio);
//m_client->addUpdateMeshTask(block);
mesh_expired = false; mesh_expired = false;
} }
@ -5691,6 +5691,7 @@ void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio)
v3s16 p = blockpos + v3s16(0,0,0); v3s16 p = blockpos + v3s16(0,0,0);
MapBlock *b = getBlockNoCreate(p); MapBlock *b = getBlockNoCreate(p);
b->updateMesh(daynight_ratio); b->updateMesh(daynight_ratio);
//b->setMeshExpired(true);
} }
catch(InvalidPositionException &e){} catch(InvalidPositionException &e){}
// Leading edge // Leading edge
@ -5698,18 +5699,21 @@ void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio)
v3s16 p = blockpos + v3s16(-1,0,0); v3s16 p = blockpos + v3s16(-1,0,0);
MapBlock *b = getBlockNoCreate(p); MapBlock *b = getBlockNoCreate(p);
b->updateMesh(daynight_ratio); b->updateMesh(daynight_ratio);
//b->setMeshExpired(true);
} }
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(daynight_ratio); b->updateMesh(daynight_ratio);
//b->setMeshExpired(true);
} }
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(daynight_ratio); b->updateMesh(daynight_ratio);
//b->setMeshExpired(true);
} }
catch(InvalidPositionException &e){} catch(InvalidPositionException &e){}
} }

@ -146,7 +146,7 @@ MapNode MapBlock::getNodeParentNoEx(v3s16 p)
returns encoded light value. returns encoded light value.
*/ */
u8 MapBlock::getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2, u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
v3s16 face_dir) v3s16 face_dir)
{ {
try{ try{
@ -182,7 +182,7 @@ u8 MapBlock::getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
#ifndef SERVER #ifndef SERVER
void MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p, 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) core::array<FastFace> &dest)
{ {
@ -283,7 +283,7 @@ void MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
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(MapNode mn, v3s16 p, v3s16 face_dir, TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
NodeModMap &temp_mods) NodeModMap &temp_mods)
{ {
TileSpec spec; TileSpec spec;
@ -335,7 +335,7 @@ TileSpec MapBlock::getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
return spec; return spec;
} }
u8 MapBlock::getNodeContent(v3s16 p, MapNode mn, NodeModMap &temp_mods) u8 getNodeContent(v3s16 p, MapNode mn, NodeModMap &temp_mods)
{ {
/* /*
Check temporary modifications on this node Check temporary modifications on this node
@ -378,7 +378,7 @@ u8 MapBlock::getNodeContent(v3s16 p, MapNode mn, NodeModMap &temp_mods)
translate_dir: unit vector with only one of x, y or z translate_dir: unit vector with only one of x, y or z
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 updateFastFaceRow(
u32 daynight_ratio, u32 daynight_ratio,
v3f posRelative_f, v3f posRelative_f,
v3s16 startpos, v3s16 startpos,
@ -388,19 +388,19 @@ void MapBlock::updateFastFaceRow(
v3s16 face_dir, v3s16 face_dir,
v3f face_dir_f, v3f face_dir_f,
core::array<FastFace> &dest, core::array<FastFace> &dest,
NodeModMap &temp_mods) NodeModMap &temp_mods,
VoxelManipulator &vmanip,
v3s16 blockpos_nodes)
{ {
v3s16 p = startpos; v3s16 p = startpos;
u16 continuous_tiles_count = 0; u16 continuous_tiles_count = 0;
MapNode n0 = getNodeParentNoEx(p); MapNode n0 = vmanip.getNodeNoEx(blockpos_nodes + p);
MapNode n1 = getNodeParentNoEx(p + face_dir); MapNode n1 = vmanip.getNodeNoEx(blockpos_nodes + p + face_dir);
u8 light = getFaceLight(daynight_ratio, n0, n1, face_dir);
TileSpec tile0 = getNodeTile(n0, p, face_dir, temp_mods); TileSpec tile0 = getNodeTile(n0, p, face_dir, temp_mods);
TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods); TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods);
u8 light = getFaceLight(daynight_ratio, n0, n1, face_dir);
for(u16 j=0; j<length; j++) for(u16 j=0; j<length; j++)
{ {
@ -418,8 +418,9 @@ void MapBlock::updateFastFaceRow(
if(j != length - 1) if(j != length - 1)
{ {
p_next = p + translate_dir; p_next = p + translate_dir;
n0_next = getNodeParentNoEx(p_next);
n1_next = getNodeParentNoEx(p_next + face_dir); n0_next = vmanip.getNodeNoEx(blockpos_nodes + p_next);
n1_next = vmanip.getNodeNoEx(blockpos_nodes + p_next + face_dir);
tile0_next = getNodeTile(n0_next, p_next, face_dir, temp_mods); tile0_next = getNodeTile(n0_next, p_next, face_dir, temp_mods);
tile1_next = getNodeTile(n1_next,p_next+face_dir,-face_dir, temp_mods); tile1_next = getNodeTile(n1_next,p_next+face_dir,-face_dir, temp_mods);
light_next = getFaceLight(daynight_ratio, n0_next, n1_next, face_dir); light_next = getFaceLight(daynight_ratio, n0_next, n1_next, face_dir);
@ -610,36 +611,20 @@ private:
core::array<PreMeshBuffer> m_prebuffers; core::array<PreMeshBuffer> m_prebuffers;
}; };
void MapBlock::updateMesh(u32 daynight_ratio) scene::SMesh* makeMapBlockMesh(
u32 daynight_ratio,
NodeModMap &temp_mods,
VoxelManipulator &vmanip,
v3s16 blockpos_nodes)
{ {
#if 0
/*
DEBUG: If mesh has been generated, don't generate it again
*/
{
JMutexAutoLock meshlock(mesh_mutex);
if(mesh != NULL)
return;
}
#endif
// 4-21ms for MAP_BLOCKSIZE=16 // 4-21ms for MAP_BLOCKSIZE=16
// 24-155ms for MAP_BLOCKSIZE=32 // 24-155ms for MAP_BLOCKSIZE=32
//TimeTaker timer1("updateMesh()"); //TimeTaker timer1("makeMapBlockMesh()");
core::array<FastFace> fastfaces_new; core::array<FastFace> fastfaces_new;
v3f posRelative_f(getPosRelative().X, getPosRelative().Y, // floating point conversion
getPosRelative().Z); // floating point conversion v3f posRelative_f(blockpos_nodes.X, blockpos_nodes.Y, blockpos_nodes.Z);
/*
Avoid interlocks by copying m_temp_mods
*/
NodeModMap temp_mods;
{
JMutexAutoLock lock(m_temp_mods_mutex);
m_temp_mods.copy(temp_mods);
}
/* /*
Some settings Some settings
@ -675,7 +660,9 @@ void MapBlock::updateMesh(u32 daynight_ratio)
v3s16(0,1,0), //face dir v3s16(0,1,0), //face dir
v3f (0,1,0), v3f (0,1,0),
fastfaces_new, fastfaces_new,
temp_mods); temp_mods,
vmanip,
blockpos_nodes);
} }
} }
/* /*
@ -690,7 +677,9 @@ void MapBlock::updateMesh(u32 daynight_ratio)
v3s16(1,0,0), v3s16(1,0,0),
v3f (1,0,0), v3f (1,0,0),
fastfaces_new, fastfaces_new,
temp_mods); temp_mods,
vmanip,
blockpos_nodes);
} }
} }
/* /*
@ -705,7 +694,9 @@ void MapBlock::updateMesh(u32 daynight_ratio)
v3s16(0,0,1), v3s16(0,0,1),
v3f (0,0,1), v3f (0,0,1),
fastfaces_new, fastfaces_new,
temp_mods); temp_mods,
vmanip,
blockpos_nodes);
} }
} }
} }
@ -790,7 +781,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
{ {
v3s16 p(x,y,z); v3s16 p(x,y,z);
MapNode &n = getNodeRef(x,y,z); MapNode &n = vmanip.getNodeRef(blockpos_nodes+p);
/* /*
Add torches to mesh Add torches to mesh
@ -825,7 +816,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
if(dir == v3s16(0,1,0)) if(dir == v3s16(0,1,0))
vertices[i].Pos.rotateXZBy(-45); vertices[i].Pos.rotateXZBy(-45);
vertices[i].Pos += intToFloat(p + getPosRelative(), BS); vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
} }
// Set material // Set material
@ -890,7 +881,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
if(dir == v3s16(0,1,0)) if(dir == v3s16(0,1,0))
vertices[i].Pos.rotateXYBy(90); vertices[i].Pos.rotateXYBy(90);
vertices[i].Pos += intToFloat(p + getPosRelative(), BS); vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
} }
// Set material // Set material
@ -917,7 +908,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
{ {
bool top_is_water = false; bool top_is_water = false;
try{ try{
MapNode n = getNodeParent(v3s16(x,y+1,z)); MapNode n = vmanip.getNode(blockpos_nodes + v3s16(x,y+1,z));
if(n.d == CONTENT_WATER || n.d == CONTENT_WATERSOURCE) if(n.d == CONTENT_WATER || n.d == CONTENT_WATERSOURCE)
top_is_water = true; top_is_water = true;
}catch(InvalidPositionException &e){} }catch(InvalidPositionException &e){}
@ -950,7 +941,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
try{ try{
// Check neighbor // Check neighbor
v3s16 p2 = p + neighbor_dirs[i]; v3s16 p2 = p + neighbor_dirs[i];
MapNode n2 = getNodeParent(p2); MapNode n2 = vmanip.getNode(blockpos_nodes + p2);
content = n2.d; content = n2.d;
@ -964,7 +955,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
// NOTE: This doesn't get executed if neighbor // NOTE: This doesn't get executed if neighbor
// doesn't exist // doesn't exist
p2.Y += 1; p2.Y += 1;
n2 = getNodeParent(p2); n2 = vmanip.getNode(blockpos_nodes + p2);
if(n2.d == CONTENT_WATERSOURCE || n2.d == CONTENT_WATER) if(n2.d == CONTENT_WATERSOURCE || n2.d == CONTENT_WATER)
flags |= neighborflag_top_is_water; flags |= neighborflag_top_is_water;
} }
@ -1124,7 +1115,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
if(dir == v3s16(1,0,-0)) if(dir == v3s16(1,0,-0))
vertices[j].Pos.rotateXZBy(-90); vertices[j].Pos.rotateXZBy(-90);
vertices[j].Pos += intToFloat(p + getPosRelative(), BS); vertices[j].Pos += intToFloat(p + blockpos_nodes, BS);
} }
u16 indices[] = {0,1,2,2,3,0}; u16 indices[] = {0,1,2,2,3,0};
@ -1163,7 +1154,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
//vertices[i].Pos.Y += neighbor_levels[v3s16(0,0,0)]; //vertices[i].Pos.Y += neighbor_levels[v3s16(0,0,0)];
s32 j = corner_resolve[i]; s32 j = corner_resolve[i];
vertices[i].Pos.Y += corner_levels[j]; vertices[i].Pos.Y += corner_levels[j];
vertices[i].Pos += intToFloat(p + getPosRelative(), BS); vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
} }
u16 indices[] = {0,1,2,2,3,0}; u16 indices[] = {0,1,2,2,3,0};
@ -1179,7 +1170,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
//bool top_is_water = false; //bool top_is_water = false;
bool top_is_air = false; bool top_is_air = false;
try{ try{
MapNode n = getNodeParent(v3s16(x,y+1,z)); MapNode n = vmanip.getNode(blockpos_nodes + v3s16(x,y+1,z));
/*if(n.d == CONTENT_WATER || n.d == CONTENT_WATERSOURCE) /*if(n.d == CONTENT_WATER || n.d == CONTENT_WATERSOURCE)
top_is_water = true;*/ top_is_water = true;*/
if(n.d == CONTENT_AIR) if(n.d == CONTENT_AIR)
@ -1213,7 +1204,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
for(s32 i=0; i<4; i++) for(s32 i=0; i<4; i++)
{ {
vertices[i].Pos.Y += (-0.5+node_water_level)*BS; vertices[i].Pos.Y += (-0.5+node_water_level)*BS;
vertices[i].Pos += intToFloat(p + getPosRelative(), BS); vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
} }
u16 indices[] = {0,1,2,2,3,0}; u16 indices[] = {0,1,2,2,3,0};
@ -1280,7 +1271,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
for(u16 i=0; i<4; i++) for(u16 i=0; i<4; i++)
{ {
vertices[i].Pos += intToFloat(p + getPosRelative(), BS); vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
} }
u16 indices[] = {0,1,2,2,3,0}; u16 indices[] = {0,1,2,2,3,0};
@ -1335,10 +1326,91 @@ void MapBlock::updateMesh(u32 daynight_ratio)
*/ */
} }
return mesh_new;
//std::cout<<"added "<<fastfaces.getSize()<<" faces."<<std::endl;
}
/*scene::SMesh* makeMapBlockMesh(
u32 daynight_ratio,
NodeModMap &temp_mods,
VoxelManipulator &vmanip,
v3s16 blockpos_nodes)
{
}*/
#if 1
void MapBlock::updateMesh(u32 daynight_ratio)
{
#if 0
/*
DEBUG: If mesh has been generated, don't generate it again
*/
{
JMutexAutoLock meshlock(mesh_mutex);
if(mesh != NULL)
return;
}
#endif
/*
Avoid interlocks by copying m_temp_mods
*/
NodeModMap temp_mods;
copyTempMods(temp_mods);
v3s16 blockpos_nodes = getPosRelative();
VoxelManipulator vmanip;
// Allocate this block + borders
vmanip.addArea(VoxelArea(blockpos_nodes-v3s16(1,1,1),
blockpos_nodes+v3s16(1,1,1)*MAP_BLOCKSIZE));
// Copy our data
copyTo(vmanip);
// Copy borders from map
// +-Z
for(s16 x=-1; x<=MAP_BLOCKSIZE; x++)
for(s16 y=-1; y<=MAP_BLOCKSIZE; y++)
for(s16 z=-1; z<=MAP_BLOCKSIZE; z+=MAP_BLOCKSIZE+1)
{
v3s16 p(x,y,z);
vmanip.setNodeNoRef(blockpos_nodes+p, getNodeParentNoEx(p));
}
// +-Y
for(s16 x=-1; x<=MAP_BLOCKSIZE; x++)
for(s16 y=-1; y<=MAP_BLOCKSIZE; y+=MAP_BLOCKSIZE+1)
for(s16 z=-1; z<=MAP_BLOCKSIZE; z++)
{
v3s16 p(x,y,z);
vmanip.setNodeNoRef(blockpos_nodes+p, getNodeParentNoEx(p));
}
// +-Z
for(s16 x=-1; x<=MAP_BLOCKSIZE; x+=MAP_BLOCKSIZE+1)
for(s16 y=-1; y<=MAP_BLOCKSIZE; y++)
for(s16 z=-1; z<=MAP_BLOCKSIZE; z++)
{
v3s16 p(x,y,z);
vmanip.setNodeNoRef(blockpos_nodes+p, getNodeParentNoEx(p));
}
scene::SMesh *mesh_new = makeMapBlockMesh(
daynight_ratio,
temp_mods,
vmanip,
getPosRelative()
);
/* /*
Replace the mesh Replace the mesh
*/ */
replaceMesh(mesh_new);
}
#endif
void MapBlock::replaceMesh(scene::SMesh *mesh_new)
{
mesh_mutex.Lock(); mesh_mutex.Lock();
//scene::SMesh *mesh_old = mesh[daynight_i]; //scene::SMesh *mesh_old = mesh[daynight_i];
@ -1375,22 +1447,8 @@ void MapBlock::updateMesh(u32 daynight_ratio)
} }
mesh_mutex.Unlock(); mesh_mutex.Unlock();
//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);
}
}*/
#endif // !SERVER #endif // !SERVER
/* /*
@ -1597,6 +1655,7 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
return block_below_is_valid; return block_below_is_valid;
} }
void MapBlock::copyTo(VoxelManipulator &dst) void MapBlock::copyTo(VoxelManipulator &dst)
{ {
v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE); v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);

@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "voxel.h" #include "voxel.h"
#include "nodemetadata.h" #include "nodemetadata.h"
// Named by looking towards z+ // Named by looking towards z+
enum{ enum{
FACE_BACK=0, FACE_BACK=0,
@ -157,6 +158,23 @@ public:
virtual u16 nodeContainerId() const = 0; virtual u16 nodeContainerId() const = 0;
}; };
/*
Plain functions in mapblock.cpp
*/
u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
v3s16 face_dir);
scene::SMesh* makeMapBlockMesh(
u32 daynight_ratio,
NodeModMap &temp_mods,
VoxelManipulator &vmanip,
v3s16 blockpos_nodes);
/*
MapBlock itself
*/
class MapBlock : public NodeContainer class MapBlock : public NodeContainer
{ {
public: public:
@ -380,11 +398,18 @@ public:
Graphics-related methods Graphics-related methods
*/ */
// A quick version with nodes passed as parameters /*// A quick version with nodes passed as parameters
u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2, u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
v3s16 face_dir); v3s16 face_dir);*/
// A more convenient version /*// A more convenient version
u8 getFaceLight(u32 daynight_ratio, v3s16 p, v3s16 face_dir) u8 getFaceLight(u32 daynight_ratio, v3s16 p, v3s16 face_dir)
{
return getFaceLight(daynight_ratio,
getNodeParentNoEx(p),
getNodeParentNoEx(p + face_dir),
face_dir);
}*/
u8 getFaceLight2(u32 daynight_ratio, v3s16 p, v3s16 face_dir)
{ {
return getFaceLight(daynight_ratio, return getFaceLight(daynight_ratio,
getNodeParentNoEx(p), getNodeParentNoEx(p),
@ -394,14 +419,14 @@ public:
#ifndef SERVER #ifndef SERVER
// light = 0...255 // light = 0...255
static void 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); core::array<FastFace> &dest);*/
TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir, /*TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
NodeModMap &temp_mods); NodeModMap &temp_mods);*/
u8 getNodeContent(v3s16 p, MapNode mn, /*u8 getNodeContent(v3s16 p, MapNode mn,
NodeModMap &temp_mods); NodeModMap &temp_mods);*/
/* /*
Generates the FastFaces of a node row. This has a Generates the FastFaces of a node row. This has a
@ -411,7 +436,7 @@ public:
translate_dir: unit vector with only one of x, y or z translate_dir: unit vector with only one of x, y or z
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 daynight_ratio, u32 daynight_ratio,
v3f posRelative_f, v3f posRelative_f,
v3s16 startpos, v3s16 startpos,
@ -421,12 +446,16 @@ public:
v3s16 face_dir, v3s16 face_dir,
v3f face_dir_f, v3f face_dir_f,
core::array<FastFace> &dest, core::array<FastFace> &dest,
NodeModMap &temp_mods); NodeModMap &temp_mods);*/
/* /*
Thread-safely updates the whole mesh of the mapblock. Thread-safely updates the whole mesh of the mapblock.
*/ */
#if 1
void updateMesh(u32 daynight_ratio); void updateMesh(u32 daynight_ratio);
#endif
void replaceMesh(scene::SMesh *mesh_new);
#endif // !SERVER #endif // !SERVER
@ -545,6 +574,11 @@ public:
return m_temp_mods.clear(); return m_temp_mods.clear();
} }
void copyTempMods(NodeModMap &dst)
{
JMutexAutoLock lock(m_temp_mods_mutex);
m_temp_mods.copy(dst);
}
#endif #endif
/* /*

@ -517,14 +517,14 @@ struct TestMapBlock
assert(b.getNode(v3s16(1,1,0)).getLight(LIGHTBANK_DAY) == 0); assert(b.getNode(v3s16(1,1,0)).getLight(LIGHTBANK_DAY) == 0);
assert(b.getNode(v3s16(1,0,0)).getLight(LIGHTBANK_DAY) == 0); assert(b.getNode(v3s16(1,0,0)).getLight(LIGHTBANK_DAY) == 0);
assert(b.getNode(v3s16(1,2,3)).getLight(LIGHTBANK_DAY) == LIGHT_SUN); assert(b.getNode(v3s16(1,2,3)).getLight(LIGHTBANK_DAY) == LIGHT_SUN);
assert(b.getFaceLight(1000, p, v3s16(0,1,0)) == LIGHT_SUN); assert(b.getFaceLight2(1000, p, v3s16(0,1,0)) == LIGHT_SUN);
assert(b.getFaceLight(1000, p, v3s16(0,-1,0)) == 0); assert(b.getFaceLight2(1000, p, v3s16(0,-1,0)) == 0);
assert(b.getFaceLight(0, p, v3s16(0,-1,0)) == 0); assert(b.getFaceLight2(0, p, v3s16(0,-1,0)) == 0);
// According to MapBlock::getFaceLight, // According to MapBlock::getFaceLight,
// The face on the z+ side should have double-diminished light // The face on the z+ side should have double-diminished light
//assert(b.getFaceLight(p, v3s16(0,0,1)) == diminish_light(diminish_light(LIGHT_MAX))); //assert(b.getFaceLight(p, v3s16(0,0,1)) == diminish_light(diminish_light(LIGHT_MAX)));
// The face on the z+ side should have diminished light // The face on the z+ side should have diminished light
assert(b.getFaceLight(1000, p, v3s16(0,0,1)) == diminish_light(LIGHT_MAX)); assert(b.getFaceLight2(1000, p, v3s16(0,0,1)) == diminish_light(LIGHT_MAX));
} }
/* /*
Check how the block handles being in between blocks with some non-sunlight Check how the block handles being in between blocks with some non-sunlight

@ -271,6 +271,7 @@ struct TileSpec
// Use this so that leaves don't need a separate material // Use this so that leaves don't need a separate material
//material_type(MATERIAL_ALPHA_SIMPLE), //material_type(MATERIAL_ALPHA_SIMPLE),
material_flags( material_flags(
//0 // <- DEBUG, Use the one below
MATERIAL_FLAG_BACKFACE_CULLING MATERIAL_FLAG_BACKFACE_CULLING
) )
{ {

@ -1391,6 +1391,7 @@ public:
} }
u32 size() u32 size()
{ {
JMutexAutoLock lock(m_mutex);
return m_list.size(); return m_list.size();
} }
void push_back(T t) void push_back(T t)

@ -373,6 +373,34 @@ public:
return m_data[m_area.index(p)]; return m_data[m_area.index(p)];
} }
MapNode getNodeNoEx(v3s16 p)
{
emerge(p);
if(m_flags[m_area.index(p)] & VOXELFLAG_INEXISTENT)
{
return MapNode(CONTENT_IGNORE);
}
return m_data[m_area.index(p)];
}
MapNode & getNodeRef(v3s16 p)
{
emerge(p);
if(m_flags[m_area.index(p)] & VOXELFLAG_INEXISTENT)
{
dstream<<"EXCEPT: VoxelManipulator::getNode(): "
<<"p=("<<p.X<<","<<p.Y<<","<<p.Z<<")"
<<", index="<<m_area.index(p)
<<", flags="<<(int)m_flags[m_area.index(p)]
<<" is inexistent"<<std::endl;
throw InvalidPositionException
("VoxelManipulator: getNode: inexistent");
}
return m_data[m_area.index(p)];
}
void setNode(v3s16 p, MapNode &n) void setNode(v3s16 p, MapNode &n)
{ {
emerge(p); emerge(p);