static void updateAllFastFaceRows(MeshMakeData *data, std::vector<FastFace> &dest, int step) { s16 to = MAP_BLOCKSIZE/step; /* Go through every y,z and get top(y+) faces in rows of x+ */ for(s16 y = 0; y < to; y++) { for(s16 z = 0; z < to; z++) { updateFastFaceRow(data, v3s16(0,y,z), v3s16(1,0,0), //dir v3f (1,0,0), v3s16(0,1,0), //face dir v3f (0,1,0), dest, step); } } /* Go through every x,y and get right(x+) faces in rows of z+ */ for(s16 x = 0; x < to; x++) { for(s16 y = 0; y < to; y++) { updateFastFaceRow(data, v3s16(x,y,0), v3s16(0,0,1), //dir v3f (0,0,1), v3s16(1,0,0), //face dir v3f (1,0,0), dest, step); } } /* Go through every y,z and get back(z+) faces in rows of x+ */ for(s16 z = 0; z < to; z++) { for(s16 y = 0; y < to; y++) { updateFastFaceRow(data, v3s16(0,y,z), v3s16(1,0,0), //dir v3f (1,0,0), v3s16(0,0,1), //face dir v3f (0,0,1), dest, step); } } }
static void updateAllFastFaceRows(MeshMakeData *data, core::array<FastFace> &dest) { /* Go through every y,z and get top(y+) faces in rows of x+ */ for(s16 y=0; y<MAP_BLOCKSIZE; y++) { for(s16 z=0; z<MAP_BLOCKSIZE; z++) { updateFastFaceRow(data, v3s16(0,y,z), v3s16(1,0,0), //dir v3f (1,0,0), v3s16(0,1,0), //face dir v3f (0,1,0), dest); } } /* Go through every x,y and get right(x+) faces in rows of z+ */ for(s16 x=0; x<MAP_BLOCKSIZE; x++) { for(s16 y=0; y<MAP_BLOCKSIZE; y++) { updateFastFaceRow(data, v3s16(x,y,0), v3s16(0,0,1), //dir v3f (0,0,1), v3s16(1,0,0), //face dir v3f (1,0,0), dest); } } /* Go through every y,z and get back(z+) faces in rows of x+ */ for(s16 z=0; z<MAP_BLOCKSIZE; z++) { for(s16 y=0; y<MAP_BLOCKSIZE; y++) { updateFastFaceRow(data, v3s16(0,y,z), v3s16(1,0,0), //dir v3f (1,0,0), v3s16(0,0,1), //face dir v3f (0,0,1), dest); } } }
scene::SMesh* makeMapBlockMesh(MeshMakeData *data) { // 4-21ms for MAP_BLOCKSIZE=16 // 24-155ms for MAP_BLOCKSIZE=32 //TimeTaker timer1("makeMapBlockMesh()"); core::array<FastFace> fastfaces_new; v3s16 blockpos_nodes = data->m_blockpos*MAP_BLOCKSIZE; // floating point conversion v3f posRelative_f(blockpos_nodes.X, blockpos_nodes.Y, blockpos_nodes.Z); /* Some settings */ //bool new_style_water = g_settings.getBool("new_style_water"); //bool new_style_leaves = g_settings.getBool("new_style_leaves"); bool smooth_lighting = g_settings.getBool("smooth_lighting"); /* We are including the faces of the trailing edges of the block. This means that when something changes, the caller must also update the meshes of the blocks at the leading edges. NOTE: This is the slowest part of this method. */ { // 4-23ms for MAP_BLOCKSIZE=16 //TimeTaker timer2("updateMesh() collect"); /* Go through every y,z and get top(y+) faces in rows of x+ */ for(s16 y=0; y<MAP_BLOCKSIZE; y++){ for(s16 z=0; z<MAP_BLOCKSIZE; z++){ updateFastFaceRow(data->m_daynight_ratio, posRelative_f, v3s16(0,y,z), MAP_BLOCKSIZE, v3s16(1,0,0), //dir v3f (1,0,0), v3s16(0,1,0), //face dir v3f (0,1,0), fastfaces_new, data->m_temp_mods, data->m_vmanip, blockpos_nodes, smooth_lighting); } } /* Go through every x,y and get right(x+) faces in rows of z+ */ for(s16 x=0; x<MAP_BLOCKSIZE; x++){ for(s16 y=0; y<MAP_BLOCKSIZE; y++){ updateFastFaceRow(data->m_daynight_ratio, posRelative_f, v3s16(x,y,0), MAP_BLOCKSIZE, v3s16(0,0,1), v3f (0,0,1), v3s16(1,0,0), v3f (1,0,0), fastfaces_new, data->m_temp_mods, data->m_vmanip, blockpos_nodes, smooth_lighting); } } /* Go through every y,z and get back(z+) faces in rows of x+ */ for(s16 z=0; z<MAP_BLOCKSIZE; z++){ for(s16 y=0; y<MAP_BLOCKSIZE; y++){ updateFastFaceRow(data->m_daynight_ratio, posRelative_f, v3s16(0,y,z), MAP_BLOCKSIZE, v3s16(1,0,0), v3f (1,0,0), v3s16(0,0,1), v3f (0,0,1), fastfaces_new, data->m_temp_mods, data->m_vmanip, blockpos_nodes, smooth_lighting); } } } // End of slow part /* Convert FastFaces to SMesh */ MeshCollector collector; if(fastfaces_new.size() > 0) { // avg 0ms (100ms spikes when loading textures the first time) //TimeTaker timer2("updateMesh() mesh building"); video::SMaterial material; material.setFlag(video::EMF_LIGHTING, false); material.setFlag(video::EMF_BILINEAR_FILTER, false); material.setFlag(video::EMF_FOG_ENABLE, true); //material.setFlag(video::EMF_ANTI_ALIASING, video::EAAM_OFF); //material.setFlag(video::EMF_ANTI_ALIASING, video::EAAM_SIMPLE); for(u32 i=0; i<fastfaces_new.size(); i++) { FastFace &f = fastfaces_new[i]; const u16 indices[] = {0,1,2,2,3,0}; const u16 indices_alternate[] = {0,1,3,2,3,1}; video::ITexture *texture = f.tile.texture.atlas; if(texture == NULL) continue; material.setTexture(0, texture); f.tile.applyMaterialOptions(material); const u16 *indices_p = indices; /* Revert triangles for nicer looking gradient if vertices 1 and 3 have same color or 0 and 2 have different color. */ if(f.vertices[0].Color != f.vertices[2].Color || f.vertices[1].Color == f.vertices[3].Color) indices_p = indices_alternate; collector.append(material, f.vertices, 4, indices_p, 6); } } /* Add special graphics: - torches - flowing water - fences - whatever */ mapblock_mesh_generate_special(data, collector); /* Add stuff from collector to mesh */ scene::SMesh *mesh_new = NULL; mesh_new = new scene::SMesh(); collector.fillMesh(mesh_new); /* Do some stuff to the mesh */ mesh_new->recalculateBoundingBox(); /* Delete new mesh if it is empty */ if(mesh_new->getMeshBufferCount() == 0) { mesh_new->drop(); mesh_new = NULL; } if(mesh_new) { #if 0 // Usually 1-700 faces and 1-7 materials std::cout<<"Updated MapBlock has "<<fastfaces_new.size()<<" faces " <<"and uses "<<mesh_new->getMeshBufferCount() <<" materials (meshbuffers)"<<std::endl; #endif // Use VBO for mesh (this just would set this for ever buffer) // This will lead to infinite memory usage because or irrlicht. //mesh_new->setHardwareMappingHint(scene::EHM_STATIC); /* NOTE: If that is enabled, some kind of a queue to the main thread should be made which would call irrlicht to delete the hardware buffer and then delete the mesh */ } return mesh_new; //std::cout<<"added "<<fastfaces.getSize()<<" faces."<<std::endl; }