Add option to enable mesh caching, add wallmounted for meshes.
authorRealBadAngel <maciej.kasatkin@o2.pl>
Tue, 28 Oct 2014 07:02:28 +0000 (08:02 +0100)
committerRealBadAngel <maciej.kasatkin@o2.pl>
Wed, 29 Oct 2014 07:37:33 +0000 (08:37 +0100)
minetest.conf.example
src/content_mapblock.cpp
src/defaultsettings.cpp
src/itemdef.cpp
src/nodedef.cpp

index 2ceb0a14283f9363b96941d874e5662ad2409c9b..af85d26a2714d1c5e483aa695edcf37d3f93db88 100644 (file)
 #enable_waving_leaves = false
 # Set to true enables waving plants. Requires shaders enabled.
 #enable_waving_plants = false
+# Enables caching of facedir rotated meshes
+#enable_mesh_cache = true
 # The time in seconds it takes between repeated
 # right clicks when holding the right mouse button
 #repeat_rightclick_time = 0.25
index ef1f1d858628dbf02633ac421c4ce469c0006968..9f0d8aa5f335fcef29ff5f7f18031ded0516d655 100644 (file)
@@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "settings.h"
 #include "nodedef.h"
 #include "tile.h"
+#include "mesh.h"
+#include <IMeshManipulator.h>
 #include "gamedef.h"
 #include "log.h"
 
@@ -171,6 +173,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
 {
        INodeDefManager *nodedef = data->m_gamedef->ndef();
        ITextureSource *tsrc = data->m_gamedef->tsrc();
+       scene::ISceneManager* smgr = data->m_gamedef->getSceneManager();
+       scene::IMeshManipulator* meshmanip = smgr->getMeshManipulator();
 
        // 0ms
        //TimeTaker timer("mapblock_mesh_generate_special()");
@@ -178,6 +182,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
        /*
                Some settings
        */
+       bool enable_mesh_cache  = g_settings->getBool("enable_mesh_cache");
        bool new_style_water = g_settings->getBool("new_style_water");
 
        float node_liquid_level = 1.0;
@@ -1719,14 +1724,41 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                {
                        v3f pos = intToFloat(p, BS);
                        video::SColor c = MapBlock_LightColor(255, getInteriorLight(n, 1, nodedef), f.light_source);
-                       u8 facedir = n.getFaceDir(nodedef);
+
+                       u8 facedir = 0;
+                       if (f.param_type_2 == CPT2_FACEDIR) {
+                               facedir = n.getFaceDir(nodedef);
+                       } else if (f.param_type_2 == CPT2_WALLMOUNTED) {
+                               //convert wallmounted to 6dfacedir.
+                               //when cache enabled, it is already converted
+                               facedir = n.getWallMounted(nodedef);                            
+                               if (!enable_mesh_cache) {
+                                       static const u8 wm_to_6d[6] =   {20, 0, 16, 12, 8, 4};
+                                       facedir = wm_to_6d[facedir];
+                               }
+                       }
+
                        if (f.mesh_ptr[facedir]) {
-                               for(u16 j = 0; j < f.mesh_ptr[facedir]->getMeshBufferCount(); j++) {
+                               // use cached meshes
+                               for(u16 j = 0; j < f.mesh_ptr[0]->getMeshBufferCount(); j++) {
                                        scene::IMeshBuffer *buf = f.mesh_ptr[facedir]->getMeshBuffer(j);
                                        collector.append(getNodeTileN(n, p, j, data),
                                                (video::S3DVertex *)buf->getVertices(), buf->getVertexCount(),
                                                buf->getIndices(), buf->getIndexCount(), pos, c);
                                }
+                       } else if (f.mesh_ptr[0]) {
+                               // no cache, clone and rotate mesh
+                               scene::IMesh* mesh = cloneMesh(f.mesh_ptr[0]);
+                               rotateMeshBy6dFacedir(mesh, facedir);
+                               recalculateBoundingBox(mesh);
+                               meshmanip->recalculateNormals(mesh, true, false);
+                               for(u16 j = 0; j < mesh->getMeshBufferCount(); j++) {
+                                       scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
+                                       collector.append(getNodeTileN(n, p, j, data),
+                                               (video::S3DVertex *)buf->getVertices(), buf->getVertexCount(),
+                                               buf->getIndices(), buf->getIndexCount(), pos, c);
+                               }
+                               mesh->drop();
                        }
                break;}
                }
index 2d6851c2c2f2f3f25eeb23665b3229e21ab41cab..e3d2dc7b721bdeaa747f36a5ac37c5cd58499a27 100644 (file)
@@ -153,6 +153,7 @@ void set_default_settings(Settings *settings)
        settings->setDefault("enable_shaders", "true");
        settings->setDefault("repeat_rightclick_time", "0.25");
        settings->setDefault("enable_particles", "true");
+       settings->setDefault("enable_mesh_cache", "true");
 
        settings->setDefault("curl_timeout", "5000");
        settings->setDefault("curl_parallel_limit", "8");
index 10e1afe2dbaedcf160e1ad692a5030d0ffda3b8e..f976c3eb7ad7a2a61a16d9e8cfe44960a9c90b04 100644 (file)
@@ -400,7 +400,10 @@ public:
                                g_settings->setBool("enable_shaders",false);
                        }
                        MeshMakeData mesh_make_data(gamedef);
-                       MapNode mesh_make_node(id, param1, 0);
+                       u8 param2 = 0;
+                       if (f.param_type_2 == CPT2_WALLMOUNTED)
+                               param2 = 1;
+                       MapNode mesh_make_node(id, param1, param2);
                        mesh_make_data.fillSingleNode(&mesh_make_node);
                        MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0));
                        scene::IMesh *node_mesh = mapblock_mesh.getMesh();
index 820f4eb300210703af2901070480187d2b678471..7dbaaee9cf07179dbe6a32dcacf901455fbe2942 100644 (file)
@@ -714,6 +714,7 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef)
        bool enable_shaders            = g_settings->getBool("enable_shaders");
        bool enable_bumpmapping        = g_settings->getBool("enable_bumpmapping");
        bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion");
+       bool enable_mesh_cache         = g_settings->getBool("enable_mesh_cache");
 
        bool use_normal_texture = enable_shaders &&
                (enable_bumpmapping || enable_parallax_occlusion);
@@ -847,23 +848,21 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef)
                                f->tiledef_special[j].backface_culling, f->alpha, material_type);
                }
 
-               // Meshnode drawtype
-               // Read the mesh and apply scale
                if ((f->drawtype == NDT_MESH) && (f->mesh != "")) {
+                       // Meshnode drawtype
+                       // Read the mesh and apply scale
                        f->mesh_ptr[0] = gamedef->getMesh(f->mesh);
                        if (f->mesh_ptr[0]){
                                v3f scale = v3f(1.0, 1.0, 1.0) * BS * f->visual_scale;
                                scaleMesh(f->mesh_ptr[0], scale);
                                recalculateBoundingBox(f->mesh_ptr[0]);
                        }
-               }
-
-               //Convert regular nodebox nodes to meshnodes
-               //Change the drawtype and apply scale
-               else if ((f->drawtype == NDT_NODEBOX) && 
+               } else if ((f->drawtype == NDT_NODEBOX) && 
                                ((f->node_box.type == NODEBOX_REGULAR) ||
                                (f->node_box.type == NODEBOX_FIXED)) &&
                                (!f->node_box.fixed.empty())) {
+                       //Convert regular nodebox nodes to meshnodes
+                       //Change the drawtype and apply scale
                        f->drawtype = NDT_MESH;
                        f->mesh_ptr[0] = convertNodeboxNodeToMesh(f);
                        v3f scale = v3f(1.0, 1.0, 1.0) * f->visual_scale;
@@ -871,14 +870,25 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef)
                        recalculateBoundingBox(f->mesh_ptr[0]);
                }
 
-               //Cache 6dfacedir rotated clones of meshes
-               if (f->mesh_ptr[0] && (f->param_type_2 == CPT2_FACEDIR)) {
+               //Cache 6dfacedir and wallmounted rotated clones of meshes
+               if (enable_mesh_cache && f->mesh_ptr[0] && (f->param_type_2 == CPT2_FACEDIR)) {
                        for (u16 j = 1; j < 24; j++) {
                                f->mesh_ptr[j] = cloneMesh(f->mesh_ptr[0]);
                                rotateMeshBy6dFacedir(f->mesh_ptr[j], j);
                                recalculateBoundingBox(f->mesh_ptr[j]);
-                               meshmanip->recalculateNormals(f->mesh_ptr[j], false, false);
+                               meshmanip->recalculateNormals(f->mesh_ptr[j], true, false);
+                       }
+               } else if (enable_mesh_cache && f->mesh_ptr[0] && (f->param_type_2 == CPT2_WALLMOUNTED)) {
+                       static const u8 wm_to_6d[6] =   {20, 0, 16, 12, 8, 4}; 
+                       for (u16 j = 1; j < 6; j++) {
+                               f->mesh_ptr[j] = cloneMesh(f->mesh_ptr[0]);
+                               rotateMeshBy6dFacedir(f->mesh_ptr[j], wm_to_6d[j]);
+                               recalculateBoundingBox(f->mesh_ptr[j]);
+                               meshmanip->recalculateNormals(f->mesh_ptr[j], true, false);
                        }
+                       rotateMeshBy6dFacedir(f->mesh_ptr[0], wm_to_6d[0]);
+                       recalculateBoundingBox(f->mesh_ptr[0]);
+                       meshmanip->recalculateNormals(f->mesh_ptr[0], true, false);                     
                }
        }
 #endif