@@ -159,40 +159,41 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
159
159
// Block position relative to camera
160
160
v3f blockpos_relative = blockpos - camera_pos;
161
161
162
- // Distance in camera direction (+=front, -=back)
163
- f32 dforward = blockpos_relative.dotProduct (camera_dir);
164
-
165
162
// Total distance
166
163
f32 d = blockpos_relative.getLength ();
167
164
168
165
if (distance_ptr)
169
166
*distance_ptr = d;
170
167
171
- // If block is very close, it is always in sight
172
- if (d < 1.44 *1.44 *MAP_BLOCKSIZE*BS/2 )
173
- return true ;
174
-
175
168
// If block is far away, it's not in sight
176
169
if (d > range)
177
170
return false ;
178
171
179
- // Maximum radius of a block
180
- f32 block_max_radius = 0.5 *1.44 *1.44 *MAP_BLOCKSIZE*BS;
172
+ // Maximum radius of a block. The magic number is
173
+ // sqrt(3.0) / 2.0 in literal form.
174
+ f32 block_max_radius = 0.866025403784 * MAP_BLOCKSIZE * BS;
181
175
182
176
// If block is (nearly) touching the camera, don't
183
177
// bother validating further (that is, render it anyway)
184
178
if (d < block_max_radius)
185
179
return true ;
186
-
180
+
181
+ // Adjust camera position, for purposes of computing the angle,
182
+ // such that a block that has any portion visible with the
183
+ // current camera position will have the center visible at the
184
+ // adjusted postion
185
+ f32 adjdist = block_max_radius / cos ((M_PI - camera_fov) / 2 );
186
+
187
+ // Block position relative to adjusted camera
188
+ v3f blockpos_adj = blockpos - (camera_pos - camera_dir * adjdist);
189
+
190
+ // Distance in camera direction (+=front, -=back)
191
+ f32 dforward = blockpos_adj.dotProduct (camera_dir);
192
+
187
193
// Cosine of the angle between the camera direction
188
194
// and the block direction (camera_dir is an unit vector)
189
- f32 cosangle = dforward / d ;
195
+ f32 cosangle = dforward / blockpos_adj. getLength () ;
190
196
191
- // Compensate for the size of the block
192
- // (as the block has to be shown even if it's a bit off FOV)
193
- // This is an estimate, plus an arbitary factor
194
- cosangle += block_max_radius / d * 0.5 ;
195
-
196
197
// If block is not in the field of view, skip it
197
198
if (cosangle < cos (camera_fov / 2 ))
198
199
return false ;
0 commit comments