Skip to content

Commit

Permalink
Refactor of viewport rendering and hopefully fix for sensor_fit issue (
Browse files Browse the repository at this point in the history
  • Loading branch information
neo2068 committed May 5, 2018
1 parent f41646b commit e7acca9
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 59 deletions.
15 changes: 9 additions & 6 deletions draw/viewport.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

def draw_quad(offset_x, offset_y, width, height):
glBegin(GL_QUADS)

# 0, 0 (top left)
glTexCoord2f(0, 0)
glVertex2f(offset_x, offset_y)
Expand Down Expand Up @@ -116,12 +115,16 @@ def _calc_offset(self, context, region_size, view_camera_offset, zoom):
context.scene.render.resolution_y * context.scene.render.pixel_aspect_y,
context.scene.camera.data.sensor_fit)

base = 0.5 * zoom * max(region_width, region_height)
base = 0.5 * zoom
if context.scene.camera.data.sensor_fit == "AUTO":
base *= max(region_width, region_height)
elif context.scene.camera.data.sensor_fit == "HORIZONTAL":
base *= region_width
elif context.scene.camera.data.sensor_fit == "VERTICAL":
base *= region_height

offset_x = ((0.5 - 2 * zoom * view_camera_offset[0])
* region_width + aspect_x * base * (2 * border_min_x - 1))
offset_y = ((0.5 - 2 * zoom * view_camera_offset[1])
* region_height + aspect_y * base * (2 * border_min_y - 1))
offset_x = ((0.5 - 2 * zoom * view_camera_offset[0]) * region_width + aspect_x * base * (2 * border_min_x - 1))
offset_y = ((0.5 - 2 * zoom * view_camera_offset[1]) * region_height + aspect_y * base * (2 * border_min_y - 1))

else:
offset_x = region_width * border_min_x + 1
Expand Down
35 changes: 12 additions & 23 deletions export/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,9 @@ def _view_persp(scene, context, definitions):

definitions["type"] = "perspective"
zoom = 2
# Magic stuff, found in Cycles export code
# TODO: non-standard sensor (is that where the 0.5 * 32 came from?)
definitions["fieldofview"] = math.degrees(2 * math.atan(16 / context.space_data.lens))

definitions["screenwindow"] = utils.calc_screenwindow(zoom, 0, 0, 0, 0, scene, context)
definitions["screenwindow"] = utils.calc_screenwindow(zoom, 0, 0, scene, context)


def _view_camera(scene, context, definitions):
Expand All @@ -88,7 +86,7 @@ def _view_camera(scene, context, definitions):

if camera.data.type == "ORTHO":
definitions["type"] = "orthographic"
zoom *= camera.data.ortho_scale / 2
zoom *= 0.5 * camera.data.ortho_scale
elif camera.data.type == "PANO":
definitions["type"] = "environment"
elif camera.data.type == "PERSP":
Expand All @@ -99,18 +97,7 @@ def _view_camera(scene, context, definitions):
raise NotImplementedError("Unknown camera.data.type")

# Screenwindow
view_camera_offset = list(context.region_data.view_camera_offset)

if scene.render.use_border:
aspectratio, xaspect, yaspect = utils.calc_aspect(scene.render.resolution_x, scene.render.resolution_y)
else:
aspectratio, xaspect, yaspect = utils.calc_aspect(context.region.width, context.region.height)

offset_x = 2 * (view_camera_offset[0] * xaspect * 2)
offset_y = 2 * (view_camera_offset[1] * yaspect * 2)

definitions["screenwindow"] = utils.calc_screenwindow(zoom, camera.data.shift_x, camera.data.shift_y,
offset_x, offset_y, scene, context)
definitions["screenwindow"] = utils.calc_screenwindow(zoom, camera.data.shift_x, camera.data.shift_y, scene, context)


def _final(scene, definitions):
Expand All @@ -123,7 +110,7 @@ def _final(scene, definitions):

if camera.data.type == "ORTHO":
cam_type = "orthographic"
zoom = camera.data.ortho_scale / 2
zoom = 0.5 * camera.data.ortho_scale

elif camera.data.type == "PANO":
cam_type = "environment"
Expand All @@ -135,17 +122,19 @@ def _final(scene, definitions):
# Correction for vertical fit sensor, must truncate the float to .1f precision and round down
width, height = utils.calc_filmsize_raw(scene)

if camera.data.sensor_fit == "VERTICAL" and width > height:
aspect_fix = round(width / height - 0.05, 1) # make sure it rounds down
else:
aspect_fix = 1.0
#if camera.data.sensor_fit == "VERTICAL" and width > height:
# aspect_fix = round(width / height - 0.05, 1) # make sure it rounds down
#else:
# aspect_fix = 1.0

if cam_type == "perspective":
definitions["fieldofview"] = math.degrees(camera.data.angle * aspect_fix)
#definitions["fieldofview"] = math.degrees(camera.data.angle * aspect_fix)
definitions["fieldofview"] = math.degrees(camera.data.angle)
_depth_of_field(scene, definitions)


# screenwindow (for border rendering and camera shift)
definitions["screenwindow"] = utils.calc_screenwindow(zoom, camera.data.shift_x, camera.data.shift_y, 0, 0, scene)
definitions["screenwindow"] = utils.calc_screenwindow(zoom, camera.data.shift_x, camera.data.shift_y, scene)


def _depth_of_field(scene, definitions):
Expand Down
66 changes: 36 additions & 30 deletions utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,14 @@ def calc_filmsize(scene, context=None):
scene.camera.data.sensor_fit)

if scene.render.use_border:
base = zoom * max(width_raw, height_raw)
base = zoom
if scene.camera.data.sensor_fit == "AUTO":
base *= max(width, height)
elif scene.camera.data.sensor_fit == "HORIZONTAL":
base *= width
elif scene.camera.data.sensor_fit == "VERTICAL":
base *= height

width = int(base * aspect_x * border_max_x) - int(base * aspect_x * border_min_x)
height = int(base * aspect_y * border_max_y) - int(base * aspect_y * border_min_y)
else:
Expand Down Expand Up @@ -239,40 +246,36 @@ def calc_blender_border(scene, context=None):
return blender_border


def calc_screenwindow(zoom, shift_x, shift_y, offset_x, offset_y, scene, context=None):
def calc_screenwindow(zoom, shift_x, shift_y, scene, context=None):
# shift is in range -2..2
# offset is in range -4..4

width_raw, height_raw = calc_filmsize_raw(scene, context)
border_min_x, border_max_x, border_min_y, border_max_y = calc_blender_border(scene, context)

# Following: Black Magic
scale = 2
scale = 1
if scene.camera and scene.camera.data.type == "ORTHO":
scale = scene.camera.data.ortho_scale
scale = 0.5 * scene.camera.data.ortho_scale

offset_x = 0
offset_y = 0

if context:
# Viewport rendering
if context.region_data.view_perspective == "CAMERA":
# Camera view

offset_x, offset_y = context.region_data.view_camera_offset
# Camera view
if scene.render.use_border:
offset_x = 0
offset_y = 0
zoom = 1
aspectratio, xaspect, yaspect = calc_aspect(scene.render.resolution_x * scene.render.pixel_aspect_x,
scene.render.resolution_y * scene.render.pixel_aspect_y,
scene.camera.data.sensor_fit)
offset_x = 0
offset_y = 0

if scene.camera.data.sensor_fit == "AUTO":
zoom = 1
elif scene.camera.data.sensor_fit == "HORIZONTAL":
zoom = max(width_raw, height_raw)/width_raw
elif scene.camera.data.sensor_fit == "VERTICAL":
zoom = max(width_raw, height_raw)/height_raw

if scene.camera and scene.camera.data.type == "ORTHO":
zoom = 0.5*scene.camera.data.ortho_scale

zoom = 0.5 * scene.camera.data.ortho_scale
else:
# No border
aspectratio, xaspect, yaspect = calc_aspect(width_raw, height_raw, scene.camera.data.sensor_fit)
Expand All @@ -282,22 +285,25 @@ def calc_screenwindow(zoom, shift_x, shift_y, offset_x, offset_y, scene, context
else:
# Final rendering
aspectratio, xaspect, yaspect = calc_aspect(scene.render.resolution_x * scene.render.pixel_aspect_x,
scene.render.resolution_y * scene.render.pixel_aspect_y)
offset_x = 0
offset_y = 0
scene.render.resolution_y * scene.render.pixel_aspect_y,
scene.camera.data.sensor_fit)


dx = scale * 2 * (shift_x + 2 * xaspect * offset_x)
dy = scale * 2 * (shift_y + 2 * yaspect * offset_y)

screenwindow = [
scale*shift_x - xaspect*zoom,
scale*shift_x + xaspect*zoom,
scale*shift_y - yaspect*zoom,
scale*shift_y + yaspect*zoom
-xaspect*zoom + dx,
xaspect*zoom + dx,
-yaspect*zoom + dy,
yaspect*zoom + dy
]

screenwindow = [
screenwindow[0] * (1 - border_min_x) + screenwindow[1] * border_min_x + 0.5*scale*offset_x,
screenwindow[0] * (1 - border_max_x) + screenwindow[1] * border_max_x + 0.5*scale*offset_x,
screenwindow[2] * (1 - border_min_y) + screenwindow[3] * border_min_y + 0.5*scale*offset_y,
screenwindow[2] * (1 - border_max_y) + screenwindow[3] * border_max_y + 0.5*scale*offset_y
screenwindow[0] * (1 - border_min_x) + screenwindow[1] * border_min_x,
screenwindow[0] * (1 - border_max_x) + screenwindow[1] * border_max_x,
screenwindow[2] * (1 - border_min_y) + screenwindow[3] * border_min_y,
screenwindow[2] * (1 - border_max_y) + screenwindow[3] * border_max_y
]

return screenwindow
Expand All @@ -320,7 +326,7 @@ def calc_aspect(width, height, fit = "AUTO"):
aspect = width / height
xaspect = aspect
yaspect = 1

return aspect, xaspect, yaspect


Expand Down

0 comments on commit e7acca9

Please sign in to comment.