]> git.lizzy.rs Git - minetest.git/commitdiff
Restore approximate occlusion check
authorsfan5 <sfan5@live.de>
Fri, 23 Aug 2019 19:52:11 +0000 (21:52 +0200)
committersfan5 <sfan5@live.de>
Fri, 23 Aug 2019 23:41:55 +0000 (01:41 +0200)
While less precise, it worked better which is what matters in the end.

src/map.cpp
src/map.h

index 6b027d34bc3d6844b38774eebe3e86ab39046353..fba970823f887cc89c615c773893f431f8b694da 100644 (file)
@@ -1033,21 +1033,11 @@ void Map::removeNodeTimer(v3s16 p)
 }
 
 bool Map::isOccluded(const v3s16 &pos_camera, const v3s16 &pos_target,
-       const core::aabbox3d<s16> &block_bounds, float step, float stepfac, float offset,
-       u32 needed_count)
+       float step, float stepfac, float offset, float end_offset, u32 needed_count)
 {
-       // Worst-case safety distance to keep to the target position
-       // Anything smaller than the mapblock diagonal could result in in self-occlusion
-       // Diagonal = sqrt(1*1 + 1*1 + 1*1)
-       const static float BLOCK_DIAGONAL = BS * MAP_BLOCKSIZE * 1.732f;
-
        v3f direction = intToFloat(pos_target - pos_camera, BS);
        float distance = direction.getLength();
 
-       // Disable occlusion culling for near mapblocks in underground
-       if (distance < BLOCK_DIAGONAL)
-               return false;
-
        // Normalize direction vector
        if (distance > 0.0f)
                direction /= distance;
@@ -1056,17 +1046,10 @@ bool Map::isOccluded(const v3s16 &pos_camera, const v3s16 &pos_target,
        u32 count = 0;
        bool is_valid_position;
 
-       for (; offset < distance; offset += step) {
+       for (; offset < distance + end_offset; offset += step) {
                v3f pos_node_f = pos_origin_f + direction * offset;
                v3s16 pos_node = floatToInt(pos_node_f, BS);
 
-               if (offset > distance - BLOCK_DIAGONAL) {
-                       // Do accurate position checks:
-                       // Check whether the node is inside the current mapblock
-                       if (block_bounds.isPointInside(pos_node))
-                               return false;
-               }
-
                MapNode node = getNode(pos_node, &is_valid_position);
 
                if (is_valid_position &&
@@ -1098,10 +1081,7 @@ bool Map::isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes)
                v3s16(-1, -1, -1) * bs2,
        };
 
-       // Minimal and maximal positions in the mapblock
-       core::aabbox3d<s16> block_bounds = block->getBox();
-
-       v3s16 pos_blockcenter = block_bounds.MinEdge + (MAP_BLOCKSIZE / 2);
+       v3s16 pos_blockcenter = block->getPosRelative() + (MAP_BLOCKSIZE / 2);
 
        // Starting step size, value between 1m and sqrt(3)m
        float step = BS * 1.2f;
@@ -1110,14 +1090,21 @@ bool Map::isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes)
 
        float start_offset = BS * 1.0f;
 
+       // The occlusion search of 'isOccluded()' must stop short of the target
+       // point by distance 'end_offset' to not enter the target mapblock.
+       // For the 8 mapblock corners 'end_offset' must therefore be the maximum
+       // diagonal of a mapblock, because we must consider all view angles.
+       // sqrt(1^2 + 1^2 + 1^2) = 1.732
+       float end_offset = -BS * MAP_BLOCKSIZE * 1.732f;
+
        // to reduce the likelihood of falsely occluded blocks
        // require at least two solid blocks
        // this is a HACK, we should think of a more precise algorithm
        u32 needed_count = 2;
 
        for (const v3s16 &dir : dir9) {
-               if (!isOccluded(cam_pos_nodes, pos_blockcenter + dir, block_bounds,
-                               step, stepfac, start_offset, needed_count))
+               if (!isOccluded(cam_pos_nodes, pos_blockcenter + dir, step, stepfac,
+                               start_offset, end_offset, needed_count))
                        return false;
        }
        return true;
index 232a25ac72fb9a10a08c6d5b91b296d8a8dae68c..8330a7a5f335b229ff190819b5f967bea73cfedf 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -311,8 +311,8 @@ class Map /*: public NodeContainer*/
        const NodeDefManager *m_nodedef;
 
        bool isOccluded(const v3s16 &pos_camera, const v3s16 &pos_target,
-               const core::aabbox3d<s16> &block_bounds, float step, float stepfac,
-               float offset, u32 needed_count);
+               float step, float stepfac, float start_offset, float end_offset,
+               u32 needed_count);
 
 private:
        f32 m_transforming_liquid_loop_count_multiplier = 1.0f;