@@ -1033,21 +1033,11 @@ void Map::removeNodeTimer(v3s16 p)
1033
1033
}
1034
1034
1035
1035
bool Map::isOccluded (const v3s16 &pos_camera, const v3s16 &pos_target,
1036
- const core::aabbox3d<s16> &block_bounds, float step, float stepfac, float offset,
1037
- u32 needed_count)
1036
+ float step, float stepfac, float offset, float end_offset, u32 needed_count)
1038
1037
{
1039
- // Worst-case safety distance to keep to the target position
1040
- // Anything smaller than the mapblock diagonal could result in in self-occlusion
1041
- // Diagonal = sqrt(1*1 + 1*1 + 1*1)
1042
- const static float BLOCK_DIAGONAL = BS * MAP_BLOCKSIZE * 1 .732f ;
1043
-
1044
1038
v3f direction = intToFloat (pos_target - pos_camera, BS);
1045
1039
float distance = direction.getLength ();
1046
1040
1047
- // Disable occlusion culling for near mapblocks in underground
1048
- if (distance < BLOCK_DIAGONAL)
1049
- return false ;
1050
-
1051
1041
// Normalize direction vector
1052
1042
if (distance > 0 .0f )
1053
1043
direction /= distance;
@@ -1056,17 +1046,10 @@ bool Map::isOccluded(const v3s16 &pos_camera, const v3s16 &pos_target,
1056
1046
u32 count = 0 ;
1057
1047
bool is_valid_position;
1058
1048
1059
- for (; offset < distance; offset += step) {
1049
+ for (; offset < distance + end_offset ; offset += step) {
1060
1050
v3f pos_node_f = pos_origin_f + direction * offset;
1061
1051
v3s16 pos_node = floatToInt (pos_node_f, BS);
1062
1052
1063
- if (offset > distance - BLOCK_DIAGONAL) {
1064
- // Do accurate position checks:
1065
- // Check whether the node is inside the current mapblock
1066
- if (block_bounds.isPointInside (pos_node))
1067
- return false ;
1068
- }
1069
-
1070
1053
MapNode node = getNode (pos_node, &is_valid_position);
1071
1054
1072
1055
if (is_valid_position &&
@@ -1098,10 +1081,7 @@ bool Map::isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes)
1098
1081
v3s16 (-1 , -1 , -1 ) * bs2,
1099
1082
};
1100
1083
1101
- // Minimal and maximal positions in the mapblock
1102
- core::aabbox3d<s16> block_bounds = block->getBox ();
1103
-
1104
- v3s16 pos_blockcenter = block_bounds.MinEdge + (MAP_BLOCKSIZE / 2 );
1084
+ v3s16 pos_blockcenter = block->getPosRelative () + (MAP_BLOCKSIZE / 2 );
1105
1085
1106
1086
// Starting step size, value between 1m and sqrt(3)m
1107
1087
float step = BS * 1 .2f ;
@@ -1110,14 +1090,21 @@ bool Map::isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes)
1110
1090
1111
1091
float start_offset = BS * 1 .0f ;
1112
1092
1093
+ // The occlusion search of 'isOccluded()' must stop short of the target
1094
+ // point by distance 'end_offset' to not enter the target mapblock.
1095
+ // For the 8 mapblock corners 'end_offset' must therefore be the maximum
1096
+ // diagonal of a mapblock, because we must consider all view angles.
1097
+ // sqrt(1^2 + 1^2 + 1^2) = 1.732
1098
+ float end_offset = -BS * MAP_BLOCKSIZE * 1 .732f ;
1099
+
1113
1100
// to reduce the likelihood of falsely occluded blocks
1114
1101
// require at least two solid blocks
1115
1102
// this is a HACK, we should think of a more precise algorithm
1116
1103
u32 needed_count = 2 ;
1117
1104
1118
1105
for (const v3s16 &dir : dir9) {
1119
- if (!isOccluded (cam_pos_nodes, pos_blockcenter + dir, block_bounds ,
1120
- step, stepfac, start_offset , needed_count))
1106
+ if (!isOccluded (cam_pos_nodes, pos_blockcenter + dir, step, stepfac ,
1107
+ start_offset, end_offset , needed_count))
1121
1108
return false ;
1122
1109
}
1123
1110
return true ;
0 commit comments