Blender 2.8 - View 3d FOV calculation

Hi all,

I’m trying to update an addon for 2.8. At some point, this addon compute the 3Dview FOV from focal lens. The original code works great, it uses the same constants and equations than used in Blender’s source code. The FOV equation uses a sensor width of 32mm (hardcoded value), then the angle value is corrected because the 3dview have an hardcoded zoom factor of 2.

With the FOV value it’s easy to compute the real horizontal distance covered by the 3dView. The script bellow illustrate the FOV calculation for a sensor width of 32mm, a focal lens of 50mm and a camera distance fixed to 10 meters.


import math

distance = 10
aperture = 32
focal = 50
zoom = 2

fov = 2 * math.atan(aperture / (focal*2) ) #standard fov equation
fov = math.atan(math.tan(fov/2) * zoom) * 2 #zoom correction (see source code)
realw = math.tan(fov/2) * distance * 2 #simple trigo

print(math.degrees(fov), realw) #(65.2, 12.8)

For controling these values, I reproduce the setup in the 3d view with another script and then I measure the horizontal distance with the ruler : in Blender 2.7 it gives me the correct distance (12.8m), but in 2.8 I get about 14.4m.

import bpy

for area in bpy.context.screen.areas:
    for space in area.spaces:
        if space.type == 'VIEW_3D':
            s = space

s.lens = 50
r = s.region_3d
r.view_location = (0, 0, 0)
r.view_rotation = (1, 0, 0, 0)
r.view_distance = 10

checking the source code give me no clue about the origin of this difference. The relevant parts of the source code are

File DNA_camera_types.h line 139

#define DEFAULT_SENSOR_WIDTH 32.0f
#define DEFAULT_SENSOR_HEIGHT 18.0f

File BKE_camera.h line 111

#define CAMERA_PARAM_ZOOM_INIT_PERSP 2.0f

File view3d_utils.c line 1098

lens = v3d->lens;
sensor_size = DEFAULT_SENSOR_WIDTH;
zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
angle = focallength_to_fov(lens, sensor_size);
/* zoom influences lens, correct this by scaling the angle as a distance (by the zoom-level) */
angle = atanf(tanf(angle / 2.0f) * zoom) * 2.0f;

File math_rotation.c line 2078

* lens/angle conversion (radians) */
float focallength_to_fov(float focal_length, float sensor)
{
  return 2.0f * atanf((sensor / 2.0f) / focal_length);
}

Any help will be appreciate !