Skip to content

Commit 1369503

Browse files
Warr1024PilzAdam
authored andcommittedMay 17, 2013
Fix math for isBlockInSight. Fixes #718 (client-side).
1 parent fedf644 commit 1369503

File tree

2 files changed

+18
-18
lines changed

2 files changed

+18
-18
lines changed
 

‎src/camera.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize,
342342
m_fov_y = fov_degrees * M_PI / 180.0;
343343
// Increase vertical FOV on lower aspect ratios (<16:10)
344344
m_fov_y *= MYMAX(1.0, MYMIN(1.4, sqrt(16./10. / m_aspect)));
345-
// WTF is this? It can't be right
346-
m_fov_x = 2 * atan(0.5 * m_aspect * tan(m_fov_y));
345+
m_fov_x = 2 * atan(m_aspect * tan(0.5 * m_fov_y));
347346
m_cameranode->setAspectRatio(m_aspect);
348347
m_cameranode->setFOV(m_fov_y);
349348

‎src/util/numeric.cpp

+17-16
Original file line numberDiff line numberDiff line change
@@ -159,40 +159,41 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
159159
// Block position relative to camera
160160
v3f blockpos_relative = blockpos - camera_pos;
161161

162-
// Distance in camera direction (+=front, -=back)
163-
f32 dforward = blockpos_relative.dotProduct(camera_dir);
164-
165162
// Total distance
166163
f32 d = blockpos_relative.getLength();
167164

168165
if(distance_ptr)
169166
*distance_ptr = d;
170167

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-
175168
// If block is far away, it's not in sight
176169
if(d > range)
177170
return false;
178171

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;
181175

182176
// If block is (nearly) touching the camera, don't
183177
// bother validating further (that is, render it anyway)
184178
if(d < block_max_radius)
185179
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+
187193
// Cosine of the angle between the camera direction
188194
// and the block direction (camera_dir is an unit vector)
189-
f32 cosangle = dforward / d;
195+
f32 cosangle = dforward / blockpos_adj.getLength();
190196

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-
196197
// If block is not in the field of view, skip it
197198
if(cosangle < cos(camera_fov / 2))
198199
return false;

0 commit comments

Comments
 (0)
Please sign in to comment.