@@ -1032,69 +1032,75 @@ void Map::removeNodeTimer(v3s16 p)
1032
1032
block->m_node_timers .remove (p_rel);
1033
1033
}
1034
1034
1035
- bool Map::isOccluded (v3s16 p0 , v3s16 p1 , float step, float stepfac ,
1036
- float start_off , float end_off , u32 needed_count)
1037
- {
1038
- float d0 = ( float ) BS * p0 .getDistanceFrom (p1 );
1039
- v3s16 u0 = p1 - p0 ;
1040
- v3f uf = v3f (u0. X , u0. Y , u0. Z ) * BS ;
1041
- uf. normalize ( );
1042
- v3f p0f = v3f (p0. X , p0. Y , p0. Z ) * BS;
1035
+ bool Map::isOccluded (v3s16 pos_origin , v3s16 pos_blockcenter , float step,
1036
+ float stepfac , float offset, float end_offset , u32 needed_count)
1037
+ {
1038
+ float distance = BS * pos_origin .getDistanceFrom (pos_blockcenter );
1039
+ v3f direction = intToFloat (pos_blockcenter - pos_origin, BS) ;
1040
+ direction. normalize () ;
1041
+ v3f pos_origin_f = intToFloat (pos_origin, BS );
1042
+
1043
1043
u32 count = 0 ;
1044
- for (float s=start_off; s<d0+end_off; s+=step){
1045
- v3f pf = p0f + uf * s;
1046
- v3s16 p = floatToInt (pf, BS);
1047
- MapNode n = getNode (p);
1048
- const ContentFeatures &f = m_nodedef->get (n);
1049
- if (f.drawtype == NDT_NORMAL){
1044
+ for (; offset < distance + end_offset; offset += step){
1045
+ v3f pf = pos_origin_f + direction * offset;
1046
+ v3s16 pos_node = floatToInt (pf, BS);
1047
+ MapNode node = getNode (pos_node);
1048
+ if (m_nodedef->get (node).drawtype == NDT_NORMAL) {
1050
1049
// not transparent, see ContentFeature::updateTextures
1051
1050
count++;
1052
- if (count >= needed_count)
1051
+ if (count >= needed_count)
1053
1052
return true ;
1054
1053
}
1055
1054
step *= stepfac;
1056
1055
}
1057
1056
return false ;
1058
1057
}
1059
1058
1060
- bool Map::isBlockOccluded (MapBlock *block, v3s16 cam_pos_nodes) {
1061
- v3s16 cpn = block->getPos () * MAP_BLOCKSIZE;
1062
- cpn += v3s16 (MAP_BLOCKSIZE / 2 , MAP_BLOCKSIZE / 2 , MAP_BLOCKSIZE / 2 );
1059
+ bool Map::isBlockOccluded (MapBlock *block, v3s16 cam_pos_nodes)
1060
+ {
1061
+ static const s16 bs2 = MAP_BLOCKSIZE / 2 + 1 ;
1062
+ static const v3s16 dir8[8 ] = {
1063
+ v3s16 ( 1 , 1 , 1 ) * bs2,
1064
+ v3s16 ( 1 , 1 , -1 ) * bs2,
1065
+ v3s16 ( 1 , -1 , 1 ) * bs2,
1066
+ v3s16 ( 1 , -1 , -1 ) * bs2,
1067
+ v3s16 (-1 , 1 , 1 ) * bs2,
1068
+ v3s16 (-1 , 1 , -1 ) * bs2,
1069
+ v3s16 (-1 , -1 , 1 ) * bs2,
1070
+ v3s16 (-1 , -1 , -1 ) * bs2,
1071
+ };
1072
+
1073
+ v3s16 pos_blockcenter = block->getPos () * MAP_BLOCKSIZE;
1074
+ pos_blockcenter += v3s16 (MAP_BLOCKSIZE) / 2 ;
1075
+
1063
1076
float step = BS * 1 ;
1077
+ // Multiply step by each iteraction by 'stepfac' to reduce checks in distance
1064
1078
float stepfac = 1.1 ;
1065
- float startoff = BS * 1 ;
1079
+
1080
+ float start_offset = BS * 1 ;
1066
1081
// The occlusion search of 'isOccluded()' must stop short of the target
1067
- // point by distance 'endoff ' (end offset) to not enter the target mapblock.
1068
- // For the 8 mapblock corners 'endoff ' must therefore be the maximum diagonal
1082
+ // point by distance 'end_offset ' (end offset) to not enter the target mapblock.
1083
+ // For the 8 mapblock corners 'end_offset ' must therefore be the maximum diagonal
1069
1084
// of a mapblock, because we must consider all view angles.
1070
1085
// sqrt(1^2 + 1^2 + 1^2) = 1.732
1071
- float endoff = -BS * MAP_BLOCKSIZE * 1.732050807569 ;
1072
- s16 bs2 = MAP_BLOCKSIZE / 2 + 1 ;
1086
+ float end_offset = -BS * MAP_BLOCKSIZE * 1.7321 ;
1087
+
1073
1088
// to reduce the likelihood of falsely occluded blocks
1074
1089
// require at least two solid blocks
1075
1090
// this is a HACK, we should think of a more precise algorithm
1076
1091
u32 needed_count = 2 ;
1077
1092
1078
- return (
1079
- // For the central point of the mapblock 'endoff' can be halved
1080
- isOccluded (cam_pos_nodes, cpn,
1081
- step, stepfac, startoff, endoff / 2 .0f , needed_count) &&
1082
- isOccluded (cam_pos_nodes, cpn + v3s16 (bs2,bs2,bs2),
1083
- step, stepfac, startoff, endoff, needed_count) &&
1084
- isOccluded (cam_pos_nodes, cpn + v3s16 (bs2,bs2,-bs2),
1085
- step, stepfac, startoff, endoff, needed_count) &&
1086
- isOccluded (cam_pos_nodes, cpn + v3s16 (bs2,-bs2,bs2),
1087
- step, stepfac, startoff, endoff, needed_count) &&
1088
- isOccluded (cam_pos_nodes, cpn + v3s16 (bs2,-bs2,-bs2),
1089
- step, stepfac, startoff, endoff, needed_count) &&
1090
- isOccluded (cam_pos_nodes, cpn + v3s16 (-bs2,bs2,bs2),
1091
- step, stepfac, startoff, endoff, needed_count) &&
1092
- isOccluded (cam_pos_nodes, cpn + v3s16 (-bs2,bs2,-bs2),
1093
- step, stepfac, startoff, endoff, needed_count) &&
1094
- isOccluded (cam_pos_nodes, cpn + v3s16 (-bs2,-bs2,bs2),
1095
- step, stepfac, startoff, endoff, needed_count) &&
1096
- isOccluded (cam_pos_nodes, cpn + v3s16 (-bs2,-bs2,-bs2),
1097
- step, stepfac, startoff, endoff, needed_count));
1093
+ // For the central point of the mapblock 'end_offset' can be halved
1094
+ if (!isOccluded (cam_pos_nodes, pos_blockcenter,
1095
+ step, stepfac, start_offset, end_offset / 2 .0f , needed_count))
1096
+ return false ;
1097
+
1098
+ for (const v3s16 &dir : dir8) {
1099
+ if (!isOccluded (cam_pos_nodes, pos_blockcenter + dir,
1100
+ step, stepfac, start_offset, end_offset, needed_count))
1101
+ return false ;
1102
+ }
1103
+ return true ;
1098
1104
}
1099
1105
1100
1106
/*
0 commit comments