fixed face updating slowness bug
authorPerttu Ahola <celeron55@gmail.com>
Mon, 29 Nov 2010 12:03:40 +0000 (14:03 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Mon, 29 Nov 2010 12:03:40 +0000 (14:03 +0200)
src/client.cpp
src/client.h
src/main.cpp
src/map.cpp
src/map.h
src/mapblock.cpp
src/server.cpp

index b461549d2fbf2b36b100eb15df732325ca09105d..7652e047e8caa56d96de47c366cf1b833d5c6087 100644 (file)
@@ -1224,8 +1224,7 @@ bool Client::AsyncProcessData()
        }
        return false;
 
-       /*
-       LazyMeshUpdater mesh_updater(&m_env);
+       /*LazyMeshUpdater mesh_updater(&m_env);
        for(;;)
        {
                bool r = AsyncProcessPacket(mesh_updater);
@@ -1233,6 +1232,7 @@ bool Client::AsyncProcessData()
                        break;
        }
        return false;*/
+
 }
 
 void Client::Send(u16 channelnum, SharedBuffer<u8> data, bool reliable)
index 92375974ab659937f8a7d5908b56b719adf16a7b..e7811d28f9e8ed1aa923d71e3bcd9af364276fc9 100644 (file)
@@ -95,6 +95,7 @@ struct IncomingPacket
        s32 *m_refcount;
 };
 
+// TODO: Remove this. It is not used as supposed.
 class LazyMeshUpdater
 {
 public:
index 991185ca6b89fe2bf1e5f5bd4a99c40ac3f32766..0452aca317db5e1eae3b880c8fe126c091fd013f 100644 (file)
@@ -197,6 +197,8 @@ Before release:
 \r
 TODO: Check what goes wrong with caching map to disk (Kray)\r
 \r
+TODO: Remove LazyMeshUpdater. It is not used as supposed.\r
+\r
 Doing now:\r
 ======================================================================\r
 \r
@@ -335,6 +337,7 @@ void set_default_settings()
        g_settings.set("height_randfactor", "constant 0.6");\r
        g_settings.set("height_base", "linear 0 35 0");\r
        g_settings.set("plants_amount", "1.0");\r
+       g_settings.set("ravines_amount", "1.0");\r
        g_settings.set("objectdata_interval", "0.2");\r
        g_settings.set("active_object_range", "2");\r
        g_settings.set("max_simultaneous_block_sends_per_client", "2");\r
@@ -1024,6 +1027,7 @@ int main(int argc, char *argv[])
 \r
        MapParams map_params;\r
        map_params.plants_amount = g_settings.getFloat("plants_amount");\r
+       map_params.ravines_amount = g_settings.getFloat("ravines_amount");\r
 \r
        /*\r
                Ask some stuff\r
index 1fbaf0899043e13f2d8c14885ae89681ec64289b..2b11b7a4850ce3e02b2c13917fac3eb24a73b933 100644 (file)
@@ -1521,7 +1521,7 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
                Add ravine (randomly)
        */
        {
-               if(rand()%10 == 0)
+               if(rand()%(s32)(10.0 * m_params.ravines_amount) == 0)
                {
                        s16 s = 6;
                        s16 x = rand()%(MAP_BLOCKSIZE-s*2-1)+s;
index eb459fbcaf80421ed5682997080fdfc59fe2db32..2f0942182068a7d2cdf69b9e2dd682d0065991ae 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -388,9 +388,11 @@ struct MapParams
        MapParams()
        {
                plants_amount = 1.0;
+               ravines_amount = 1.0;
                //max_objects_in_block = 30;
        }
        float plants_amount;
+       float ravines_amount;
        //u16 max_objects_in_block;
 };
 
index 25561008a1796beb9ffafa8fffdde1701762ddce..5ca8749463ef8a14f10717653854ffe99d8d4416 100644 (file)
@@ -283,6 +283,98 @@ void MapBlock::updateFastFaceRow(v3s16 startpos,
        }
 }
 
+/*
+       This is used because CMeshBuffer::append() is very slow
+*/
+struct PreMeshBuffer
+{
+       video::SMaterial material;
+       core::array<u16> indices;
+       core::array<video::S3DVertex> vertices;
+};
+
+class MeshCollector
+{
+public:
+       void append(
+                       video::SMaterial material,
+                       const video::S3DVertex* const vertices,
+                       u32 numVertices,
+                       const u16* const indices,
+                       u32 numIndices
+               )
+       {
+               PreMeshBuffer *p = NULL;
+               for(u32 i=0; i<m_prebuffers.size(); i++)
+               {
+                       PreMeshBuffer &pp = m_prebuffers[i];
+                       if(pp.material != material)
+                               continue;
+
+                       p = &pp;
+                       break;
+               }
+
+               if(p == NULL)
+               {
+                       PreMeshBuffer pp;
+                       pp.material = material;
+                       m_prebuffers.push_back(pp);
+                       p = &m_prebuffers[m_prebuffers.size()-1];
+               }
+
+               u32 vertex_count = p->vertices.size();
+               for(u32 i=0; i<numIndices; i++)
+               {
+                       u32 j = indices[i] + vertex_count;
+                       if(j > 65535)
+                       {
+                               dstream<<"FIXME: Meshbuffer ran out of indices"<<std::endl;
+                               // NOTE: Fix is to just add an another MeshBuffer
+                       }
+                       p->indices.push_back(j);
+               }
+               for(u32 i=0; i<numVertices; i++)
+               {
+                       p->vertices.push_back(vertices[i]);
+               }
+       }
+
+       void fillMesh(scene::SMesh *mesh)
+       {
+               /*dstream<<"Filling mesh with "<<m_prebuffers.size()
+                               <<" meshbuffers"<<std::endl;*/
+               for(u32 i=0; i<m_prebuffers.size(); i++)
+               {
+                       PreMeshBuffer &p = m_prebuffers[i];
+
+                       /*dstream<<"p.vertices.size()="<<p.vertices.size()
+                                       <<", p.indices.size()="<<p.indices.size()
+                                       <<std::endl;*/
+                       
+                       // Create meshbuffer
+                       
+                       // This is a "Standard MeshBuffer",
+                       // it's a typedeffed CMeshBuffer<video::S3DVertex>
+                       scene::IMeshBuffer *buf = new scene::SMeshBuffer();
+                       // Set material
+                       ((scene::SMeshBuffer*)buf)->Material = p.material;
+                       // Use VBO
+                       //buf->setHardwareMappingHint(scene::EHM_STATIC);
+                       // Add to mesh
+                       mesh->addMeshBuffer(buf);
+                       // Mesh grabbed it
+                       buf->drop();
+
+                       buf->append(p.vertices.pointer(), p.vertices.size(),
+                                       p.indices.pointer(), p.indices.size());
+               }
+       }
+
+private:
+       core::array<PreMeshBuffer> m_prebuffers;
+};
+
 void MapBlock::updateMesh()
 {
        /*v3s16 p = getPosRelative();
@@ -344,7 +436,25 @@ void MapBlock::updateMesh()
        
        if(fastfaces_new->getSize() > 0)
        {
+               MeshCollector collector;
+
+               core::list<FastFace*>::Iterator i = fastfaces_new->begin();
+
+               for(; i != fastfaces_new->end(); i++)
+               {
+                       FastFace *f = *i;
+
+                       const u16 indices[] = {0,1,2,2,3,0};
+
+                       collector.append(g_materials[f->material], f->vertices, 4,
+                                       indices, 6);
+               }
+
                mesh_new = new scene::SMesh();
+               
+               collector.fillMesh(mesh_new);
+
+#if 0
                scene::IMeshBuffer *buf = NULL;
 
                core::list<FastFace*>::Iterator i = fastfaces_new->begin();
@@ -377,17 +487,19 @@ void MapBlock::updateMesh()
                                }
                                material_in_use = f->material;
                        }
-
-                       u16 indices[] = {0,1,2,2,3,0};
-                       buf->append(f->vertices, 4, indices, 6);
+                       
+                       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)
                //mesh_new->setHardwareMappingHint(scene::EHM_STATIC);
                
                /*std::cout<<"MapBlock has "<<fastfaces_new->getSize()<<" faces "
                                <<"and uses "<<mesh_new->getMeshBufferCount()
-                               <<" materials"<<std::endl;*/
+                               <<" materials (meshbuffers)"<<std::endl;*/
        }
 
        // TODO: Get rid of the FastFace stage
index e17e21d324c4ac7ea8f171feb6331d10cc107819..16f6611cafbcd0b1a10d0cc8bbb03bb06acac05b 100644 (file)
@@ -380,7 +380,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
 
                                Also, don't send blocks that are already flying.
                        */
-                       if(d >= BLOCK_SEND_DISABLE_LIMITS_MAX_D)
+                       if(d > BLOCK_SEND_DISABLE_LIMITS_MAX_D)
                        {
                                JMutexAutoLock lock(m_blocks_sending_mutex);