From: Perttu Ahola Date: Sun, 3 Apr 2011 16:50:54 +0000 (+0300) Subject: Modified block mesh generation to have clearer input and output. Instead of being... X-Git-Url: http://81.2.79.47:8989/gitweb/?a=commitdiff_plain;h=e0f7bd4d57bf0c9b497c4d0bb73f7bd4d5cc0643;p=zefram%2Fminetest%2Fminetest_engine.git 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. --- diff --git a/src/client.cpp b/src/client.cpp index 4cae9d02..357cbe36 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1238,6 +1238,35 @@ bool Client::AsyncProcessPacket() block->deSerialize(istr, ser_version); sector->insertBlock(block); //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 diff --git a/src/environment.cpp b/src/environment.cpp index 8d9af480..d144baee 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -891,7 +891,8 @@ void ClientEnvironment::step(float dtime) { v3s16 p_blocks = getNodeBlockPos(bottompos); MapBlock *b = m_map->getBlockNoCreate(p_blocks); - b->updateMesh(m_daynight_ratio); + //b->updateMesh(m_daynight_ratio); + b->setMeshExpired(true); } } } diff --git a/src/map.cpp b/src/map.cpp index 39e35156..1608f3e0 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -5482,8 +5482,8 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) mesh_update_count++; // Mesh has been expired: generate new mesh - //block->updateMeshes(daynight_i); block->updateMesh(daynight_ratio); + //m_client->addUpdateMeshTask(block); mesh_expired = false; } @@ -5691,6 +5691,7 @@ void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio) v3s16 p = blockpos + v3s16(0,0,0); MapBlock *b = getBlockNoCreate(p); b->updateMesh(daynight_ratio); + //b->setMeshExpired(true); } catch(InvalidPositionException &e){} // Leading edge @@ -5698,18 +5699,21 @@ void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio) v3s16 p = blockpos + v3s16(-1,0,0); MapBlock *b = getBlockNoCreate(p); b->updateMesh(daynight_ratio); + //b->setMeshExpired(true); } catch(InvalidPositionException &e){} try{ v3s16 p = blockpos + v3s16(0,-1,0); MapBlock *b = getBlockNoCreate(p); b->updateMesh(daynight_ratio); + //b->setMeshExpired(true); } catch(InvalidPositionException &e){} try{ v3s16 p = blockpos + v3s16(0,0,-1); MapBlock *b = getBlockNoCreate(p); b->updateMesh(daynight_ratio); + //b->setMeshExpired(true); } catch(InvalidPositionException &e){} } diff --git a/src/mapblock.cpp b/src/mapblock.cpp index 26280dec..c38887b6 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -146,7 +146,7 @@ MapNode MapBlock::getNodeParentNoEx(v3s16 p) 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) { try{ @@ -182,7 +182,7 @@ u8 MapBlock::getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2, #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, core::array &dest) { @@ -283,7 +283,7 @@ void MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p, Gets node tile from any place relative to block. 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) { TileSpec spec; @@ -335,7 +335,7 @@ TileSpec MapBlock::getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir, 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 @@ -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 face_dir: unit vector with only one of x, y or z */ -void MapBlock::updateFastFaceRow( +void updateFastFaceRow( u32 daynight_ratio, v3f posRelative_f, v3s16 startpos, @@ -388,19 +388,19 @@ void MapBlock::updateFastFaceRow( v3s16 face_dir, v3f face_dir_f, core::array &dest, - NodeModMap &temp_mods) + NodeModMap &temp_mods, + VoxelManipulator &vmanip, + v3s16 blockpos_nodes) { v3s16 p = startpos; u16 continuous_tiles_count = 0; - MapNode n0 = getNodeParentNoEx(p); - MapNode n1 = getNodeParentNoEx(p + face_dir); - - u8 light = getFaceLight(daynight_ratio, n0, n1, face_dir); - + MapNode n0 = vmanip.getNodeNoEx(blockpos_nodes + p); + MapNode n1 = vmanip.getNodeNoEx(blockpos_nodes + p + face_dir); TileSpec tile0 = getNodeTile(n0, p, 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 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 // 24-155ms for MAP_BLOCKSIZE=32 - //TimeTaker timer1("updateMesh()"); + //TimeTaker timer1("makeMapBlockMesh()"); core::array fastfaces_new; - v3f posRelative_f(getPosRelative().X, getPosRelative().Y, - getPosRelative().Z); // floating point conversion - - /* - Avoid interlocks by copying m_temp_mods - */ - NodeModMap temp_mods; - { - JMutexAutoLock lock(m_temp_mods_mutex); - m_temp_mods.copy(temp_mods); - } + // floating point conversion + v3f posRelative_f(blockpos_nodes.X, blockpos_nodes.Y, blockpos_nodes.Z); /* Some settings @@ -675,7 +660,9 @@ void MapBlock::updateMesh(u32 daynight_ratio) v3s16(0,1,0), //face dir v3f (0,1,0), fastfaces_new, - temp_mods); + temp_mods, + vmanip, + blockpos_nodes); } } /* @@ -690,7 +677,9 @@ void MapBlock::updateMesh(u32 daynight_ratio) v3s16(1,0,0), v3f (1,0,0), fastfaces_new, - temp_mods); + temp_mods, + vmanip, + blockpos_nodes); } } /* @@ -705,7 +694,9 @@ void MapBlock::updateMesh(u32 daynight_ratio) v3s16(0,0,1), v3f (0,0,1), fastfaces_new, - temp_mods); + temp_mods, + vmanip, + blockpos_nodes); } } } @@ -790,7 +781,7 @@ void MapBlock::updateMesh(u32 daynight_ratio) { v3s16 p(x,y,z); - MapNode &n = getNodeRef(x,y,z); + MapNode &n = vmanip.getNodeRef(blockpos_nodes+p); /* Add torches to mesh @@ -825,7 +816,7 @@ void MapBlock::updateMesh(u32 daynight_ratio) if(dir == v3s16(0,1,0)) vertices[i].Pos.rotateXZBy(-45); - vertices[i].Pos += intToFloat(p + getPosRelative(), BS); + vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); } // Set material @@ -890,7 +881,7 @@ void MapBlock::updateMesh(u32 daynight_ratio) if(dir == v3s16(0,1,0)) vertices[i].Pos.rotateXYBy(90); - vertices[i].Pos += intToFloat(p + getPosRelative(), BS); + vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); } // Set material @@ -917,7 +908,7 @@ void MapBlock::updateMesh(u32 daynight_ratio) { bool top_is_water = false; 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) top_is_water = true; }catch(InvalidPositionException &e){} @@ -950,7 +941,7 @@ void MapBlock::updateMesh(u32 daynight_ratio) try{ // Check neighbor v3s16 p2 = p + neighbor_dirs[i]; - MapNode n2 = getNodeParent(p2); + MapNode n2 = vmanip.getNode(blockpos_nodes + p2); content = n2.d; @@ -964,7 +955,7 @@ void MapBlock::updateMesh(u32 daynight_ratio) // NOTE: This doesn't get executed if neighbor // doesn't exist p2.Y += 1; - n2 = getNodeParent(p2); + n2 = vmanip.getNode(blockpos_nodes + p2); if(n2.d == CONTENT_WATERSOURCE || n2.d == CONTENT_WATER) flags |= neighborflag_top_is_water; } @@ -1124,7 +1115,7 @@ void MapBlock::updateMesh(u32 daynight_ratio) if(dir == v3s16(1,0,-0)) 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}; @@ -1163,7 +1154,7 @@ void MapBlock::updateMesh(u32 daynight_ratio) //vertices[i].Pos.Y += neighbor_levels[v3s16(0,0,0)]; s32 j = corner_resolve[i]; 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}; @@ -1179,7 +1170,7 @@ void MapBlock::updateMesh(u32 daynight_ratio) //bool top_is_water = false; bool top_is_air = false; 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) top_is_water = true;*/ if(n.d == CONTENT_AIR) @@ -1213,7 +1204,7 @@ void MapBlock::updateMesh(u32 daynight_ratio) for(s32 i=0; i<4; i++) { 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}; @@ -1280,7 +1271,7 @@ void MapBlock::updateMesh(u32 daynight_ratio) 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}; @@ -1334,11 +1325,92 @@ void MapBlock::updateMesh(u32 daynight_ratio) the hardware buffer and then delete the mesh */ } + + return mesh_new; + + //std::cout<<"added "<= 0 && first_i <= DAYNIGHT_CACHE_COUNT); - updateMesh(first_i); - for(s32 i=0; i & light_sources, return block_below_is_valid; } + void MapBlock::copyTo(VoxelManipulator &dst) { v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE); diff --git a/src/mapblock.h b/src/mapblock.h index 6af4070b..1894269b 100644 --- a/src/mapblock.h +++ b/src/mapblock.h @@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "voxel.h" #include "nodemetadata.h" + // Named by looking towards z+ enum{ FACE_BACK=0, @@ -157,6 +158,23 @@ public: 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 { public: @@ -380,11 +398,18 @@ public: 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, - v3s16 face_dir); - // A more convenient version + v3s16 face_dir);*/ + /*// A more convenient version 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, getNodeParentNoEx(p), @@ -394,14 +419,14 @@ public: #ifndef SERVER // 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, - core::array &dest); + core::array &dest);*/ - TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir, - NodeModMap &temp_mods); - u8 getNodeContent(v3s16 p, MapNode mn, - NodeModMap &temp_mods); + /*TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir, + NodeModMap &temp_mods);*/ + /*u8 getNodeContent(v3s16 p, MapNode mn, + NodeModMap &temp_mods);*/ /* 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 face_dir: unit vector with only one of x, y or z */ - void updateFastFaceRow( + /*void updateFastFaceRow( u32 daynight_ratio, v3f posRelative_f, v3s16 startpos, @@ -421,12 +446,16 @@ public: v3s16 face_dir, v3f face_dir_f, core::array &dest, - NodeModMap &temp_mods); + NodeModMap &temp_mods);*/ /* Thread-safely updates the whole mesh of the mapblock. */ +#if 1 void updateMesh(u32 daynight_ratio); +#endif + + void replaceMesh(scene::SMesh *mesh_new); #endif // !SERVER @@ -545,6 +574,11 @@ public: return m_temp_mods.clear(); } + void copyTempMods(NodeModMap &dst) + { + JMutexAutoLock lock(m_temp_mods_mutex); + m_temp_mods.copy(dst); + } #endif /* diff --git a/src/test.cpp b/src/test.cpp index 1de90278..c7bffcdf 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -517,14 +517,14 @@ struct TestMapBlock 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,2,3)).getLight(LIGHTBANK_DAY) == LIGHT_SUN); - assert(b.getFaceLight(1000, p, v3s16(0,1,0)) == LIGHT_SUN); - assert(b.getFaceLight(1000, p, v3s16(0,-1,0)) == 0); - assert(b.getFaceLight(0, p, v3s16(0,-1,0)) == 0); + assert(b.getFaceLight2(1000, p, v3s16(0,1,0)) == LIGHT_SUN); + assert(b.getFaceLight2(1000, p, v3s16(0,-1,0)) == 0); + assert(b.getFaceLight2(0, p, v3s16(0,-1,0)) == 0); // According to MapBlock::getFaceLight, // 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))); // 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 diff --git a/src/tile.h b/src/tile.h index d1189943..f0628596 100644 --- a/src/tile.h +++ b/src/tile.h @@ -271,6 +271,7 @@ struct TileSpec // Use this so that leaves don't need a separate material //material_type(MATERIAL_ALPHA_SIMPLE), material_flags( + //0 // <- DEBUG, Use the one below MATERIAL_FLAG_BACKFACE_CULLING ) { diff --git a/src/utility.h b/src/utility.h index 6e14a4bb..89c5f998 100644 --- a/src/utility.h +++ b/src/utility.h @@ -1391,6 +1391,7 @@ public: } u32 size() { + JMutexAutoLock lock(m_mutex); return m_list.size(); } void push_back(T t) diff --git a/src/voxel.h b/src/voxel.h index eced43ed..5d45ab18 100644 --- a/src/voxel.h +++ b/src/voxel.h @@ -373,6 +373,34 @@ public: 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=("<