]> git.lizzy.rs Git - minetest.git/blobdiff - src/client/content_mapblock.cpp
Fix scaled world-aligned textures being aligned inconsistently for non-normal drawtypes
[minetest.git] / src / client / content_mapblock.cpp
index f7d20001f41d33eb3c494d31c225260efd2a71e4..bb2d6398f1015c855a19d07dc3f495fbcaeaafa2 100644 (file)
@@ -17,6 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
+#include <cmath>
 #include "content_mapblock.h"
 #include "util/numeric.h"
 #include "util/directiontables.h"
@@ -59,18 +60,16 @@ static constexpr u16 quad_indices[] = {0, 1, 2, 2, 3, 0};
 
 const std::string MapblockMeshGenerator::raillike_groupname = "connect_to_raillike";
 
-MapblockMeshGenerator::MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output)
+MapblockMeshGenerator::MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output,
+       scene::IMeshManipulator *mm):
+       data(input),
+       collector(output),
+       nodedef(data->m_client->ndef()),
+       meshmanip(mm),
+       blockpos_nodes(data->m_blockpos * MAP_BLOCKSIZE)
 {
-       data      = input;
-       collector = output;
-
-       nodedef   = data->m_client->ndef();
-       meshmanip = RenderingEngine::get_scene_manager()->getMeshManipulator();
-
        enable_mesh_cache = g_settings->getBool("enable_mesh_cache") &&
                !data->m_smooth_lighting; // Mesh cache is not supported with smooth lighting
-
-       blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE;
 }
 
 void MapblockMeshGenerator::useTile(int index, u8 set_flags, u8 reset_flags, bool special)
@@ -512,10 +511,10 @@ f32 MapblockMeshGenerator::getCornerLevel(int i, int k)
                        count++;
                } else if (content == CONTENT_AIR) {
                        air_count++;
-                       if (air_count >= 2)
-                               return -0.5 * BS + 0.2;
                }
        }
+       if (air_count >= 2)
+               return -0.5 * BS + 0.2;
        if (count > 0)
                return sum / count;
        return 0;
@@ -722,7 +721,8 @@ void MapblockMeshGenerator::drawGlasslikeFramedNode()
        for (auto &glass_tile : glass_tiles)
                glass_tile = tiles[4];
 
-       u8 param2 = n.getParam2();
+       // Only respect H/V merge bits when paramtype2 = "glasslikeliquidlevel" (liquid tank)
+       u8 param2 = (f->param_type_2 == CPT2_GLASSLIKE_LIQUID_LEVEL) ? n.getParam2() : 0;
        bool H_merge = !(param2 & 128);
        bool V_merge = !(param2 & 64);
        param2 &= 63;
@@ -958,15 +958,43 @@ void MapblockMeshGenerator::drawPlantlikeQuad(float rotation, float quad_offset,
                vertex.rotateXZBy(rotation + rotate_degree);
                vertex += offset;
        }
+
+       u8 wall = n.getWallMounted(nodedef);
+       if (wall != DWM_YN) {
+               for (v3f &vertex : vertices) {
+                       switch (wall) {
+                               case DWM_YP:
+                                       vertex.rotateYZBy(180);
+                                       vertex.rotateXZBy(180);
+                                       break;
+                               case DWM_XP:
+                                       vertex.rotateXYBy(90);
+                                       break;
+                               case DWM_XN:
+                                       vertex.rotateXYBy(-90);
+                                       vertex.rotateYZBy(180);
+                                       break;
+                               case DWM_ZP:
+                                       vertex.rotateYZBy(-90);
+                                       vertex.rotateXYBy(90);
+                                       break;
+                               case DWM_ZN:
+                                       vertex.rotateYZBy(90);
+                                       vertex.rotateXYBy(90);
+                                       break;
+                       }
+               }
+       }
+
        drawQuad(vertices, v3s16(0, 0, 0), plant_height);
 }
 
-void MapblockMeshGenerator::drawPlantlike()
+void MapblockMeshGenerator::drawPlantlike(bool is_rooted)
 {
        draw_style = PLANT_STYLE_CROSS;
        scale = BS / 2 * f->visual_scale;
        offset = v3f(0, 0, 0);
-       rotate_degree = 0;
+       rotate_degree = 0.0f;
        random_offset_Y = false;
        face_num = 0;
        plant_height = 1.0;
@@ -986,7 +1014,8 @@ void MapblockMeshGenerator::drawPlantlike()
                break;
 
        case CPT2_DEGROTATE:
-               rotate_degree = n.param2 * 2;
+       case CPT2_COLORED_DEGROTATE:
+               rotate_degree = 1.5f * n.getDegRotate(nodedef);
                break;
 
        case CPT2_LEVELED:
@@ -997,6 +1026,22 @@ void MapblockMeshGenerator::drawPlantlike()
                break;
        }
 
+       if (is_rooted) {
+               u8 wall = n.getWallMounted(nodedef);
+               switch (wall) {
+                       case DWM_YP:
+                               offset.Y += BS*2;
+                               break;
+                       case DWM_XN:
+                       case DWM_XP:
+                       case DWM_ZN:
+                       case DWM_ZP:
+                               offset.X += -BS;
+                               offset.Y +=  BS;
+                               break;
+               }
+       }
+
        switch (draw_style) {
        case PLANT_STYLE_CROSS:
                drawPlantlikeQuad(46);
@@ -1047,7 +1092,7 @@ void MapblockMeshGenerator::drawPlantlikeRootedNode()
                MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + p);
                light = LightPair(getInteriorLight(ntop, 1, nodedef));
        }
-       drawPlantlike();
+       drawPlantlike(true);
        p.Y--;
 }
 
@@ -1341,6 +1386,7 @@ void MapblockMeshGenerator::drawMeshNode()
        u8 facedir = 0;
        scene::IMesh* mesh;
        bool private_mesh; // as a grab/drop pair is not thread-safe
+       int degrotate = 0;
 
        if (f->param_type_2 == CPT2_FACEDIR ||
                        f->param_type_2 == CPT2_COLORED_FACEDIR) {
@@ -1352,9 +1398,12 @@ void MapblockMeshGenerator::drawMeshNode()
                facedir = n.getWallMounted(nodedef);
                if (!enable_mesh_cache)
                        facedir = wallmounted_to_facedir[facedir];
+       } else if (f->param_type_2 == CPT2_DEGROTATE ||
+                       f->param_type_2 == CPT2_COLORED_DEGROTATE) {
+               degrotate = n.getDegRotate(nodedef);
        }
 
-       if (!data->m_smooth_lighting && f->mesh_ptr[facedir]) {
+       if (!data->m_smooth_lighting && f->mesh_ptr[facedir] && !degrotate) {
                // use cached meshes
                private_mesh = false;
                mesh = f->mesh_ptr[facedir];
@@ -1362,7 +1411,10 @@ void MapblockMeshGenerator::drawMeshNode()
                // no cache, clone and rotate mesh
                private_mesh = true;
                mesh = cloneMesh(f->mesh_ptr[0]);
-               rotateMeshBy6dFacedir(mesh, facedir);
+               if (facedir)
+                       rotateMeshBy6dFacedir(mesh, facedir);
+               else if (degrotate)
+                       rotateMeshXZby(mesh, 1.5f * degrotate);
                recalculateBoundingBox(mesh);
                meshmanip->recalculateNormals(mesh, true, false);
        } else
@@ -1453,10 +1505,10 @@ void MapblockMeshGenerator::generate()
        }
 }
 
-void MapblockMeshGenerator::renderSingle(content_t node)
+void MapblockMeshGenerator::renderSingle(content_t node, u8 param2)
 {
        p = {0, 0, 0};
-       n = MapNode(node, 0xff, 0x00);
+       n = MapNode(node, 0xff, param2);
        f = &nodedef->get(n);
        drawNode();
 }