From dd4c21c1808acedfbcf8402c09ce9129b6ac31c7 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Tue, 28 Oct 2014 08:02:28 +0100 Subject: [PATCH] Add option to enable mesh caching, add wallmounted for meshes. --- minetest.conf.example | 2 ++ src/content_mapblock.cpp | 36 ++++++++++++++++++++++++++++++++++-- src/defaultsettings.cpp | 1 + src/itemdef.cpp | 5 ++++- src/nodedef.cpp | 30 ++++++++++++++++++++---------- 5 files changed, 61 insertions(+), 13 deletions(-) diff --git a/minetest.conf.example b/minetest.conf.example index 2ceb0a142..af85d26a2 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -201,6 +201,8 @@ #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 diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index ef1f1d858..9f0d8aa5f 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -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 #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;} } diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 2d6851c2c..e3d2dc7b7 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -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"); diff --git a/src/itemdef.cpp b/src/itemdef.cpp index 10e1afe2d..f976c3eb7 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -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(); diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 820f4eb30..7dbaaee9c 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -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