Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2012-03-24 02:12:24 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2014-04-17 17:11:34 +0400
commit02e5bdf864bdf001af5ef751f296e90c02edad5b (patch)
tree98aef831e7ef5e854c5542219e74d0be4bdf13d2
parente0e05ae85eee83dfc5c07f3dba0664a3ade62d7a (diff)
Initial implementation of overscan renderingoverscan
For now only affects blender internal renderer and viewport. Currently it's possible to define overscan (in %%) manually or make it so distortion matches the motrack displacement model. Still need to do loads of things in compositor, but it's not such a bad starting point. We can even start a branch for this. Reviewers: dfelinto Differential Revision: https://developer.blender.org/D462
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py6
-rw-r--r--source/blender/blenkernel/BKE_camera.h7
-rw-r--r--source/blender/blenkernel/BKE_scene.h4
-rw-r--r--source/blender/blenkernel/BKE_tracking.h2
-rw-r--r--source/blender/blenkernel/intern/camera.c55
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c6
-rw-r--r--source/blender/blenkernel/intern/scene.c14
-rw-r--r--source/blender/blenkernel/intern/tracking.c29
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c2
-rw-r--r--source/blender/editors/include/ED_view3d.h5
-rw-r--r--source/blender/editors/render/render_internal.c4
-rw-r--r--source/blender/editors/render/render_opengl.c4
-rw-r--r--source/blender/editors/space_node/drawnode.c12
-rw-r--r--source/blender/editors/space_view3d/drawobject.c9
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c161
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h2
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c14
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c2
-rw-r--r--source/blender/editors/transform/transform_manipulator.c18
-rw-r--r--source/blender/makesdna/DNA_node_types.h4
-rw-r--r--source/blender/makesdna/DNA_scene_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c18
-rw-r--r--source/blender/makesrna/intern/rna_scene.c27
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h2
-rw-r--r--source/blender/render/intern/source/initrender.c10
-rw-r--r--source/blender/render/intern/source/pipeline.c12
30 files changed, 341 insertions, 103 deletions
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index ce375eca894..c8c3ae3c389 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -172,6 +172,12 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel):
subrow.prop(rd, "frame_map_old", text="Old")
subrow.prop(rd, "frame_map_new", text="New")
+ col = layout.column()
+ col.prop(rd, "use_detect_overscan")
+ sub = col.row()
+ sub.active = not rd.use_detect_overscan
+ sub.prop(rd, "overscan")
+
class RENDER_PT_antialiasing(RenderButtonsPanel, Panel):
bl_label = "Anti-Aliasing"
diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index 01b401c6bcc..ac5915168c7 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -97,7 +97,12 @@ typedef struct CameraParams {
float ycor;
float viewdx;
float viewdy;
- rctf viewplane;
+ rctf viewplane; /* viewplane used for displaying/rendering which might include overscan correction */
+ rctf underscan_viewplane; /* viewplane which isn't affected by overscan */
+
+ /* overscan */
+ float overscan;
+ bool apply_overscan;
/* computed matrix */
float winmat[4][4];
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 5fe890461e0..a02b192e316 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -138,6 +138,10 @@ int BKE_scene_num_threads(const struct Scene *scene);
int BKE_render_num_threads(const struct RenderData *r);
int BKE_scene_num_omp_threads(const struct Scene *scene);
+
+/* overscan */
+void BKE_scene_update_overscan(struct Scene *scene);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index 6d155ba37de..3a0d7f489a1 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -188,6 +188,8 @@ void BKE_tracking_distortion_free(struct MovieDistortion *distortion);
void BKE_tracking_distort_v2(struct MovieTracking *tracking, const float co[2], float r_co[2]);
void BKE_tracking_undistort_v2(struct MovieTracking *tracking, const float co[2], float r_co[2]);
+float BKE_tracking_overscan_detect(struct MovieClip *clip);
+
struct ImBuf *BKE_tracking_undistort_frame(struct MovieTracking *tracking, struct ImBuf *ibuf,
int calibration_width, int calibration_height, float overscan);
struct ImBuf *BKE_tracking_distort_frame(struct MovieTracking *tracking, struct ImBuf *ibuf,
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index b20ba40c0dd..ded7db71960 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -202,6 +202,9 @@ void BKE_camera_params_init(CameraParams *params)
/* fallback for non camera objects */
params->clipsta = 0.1f;
params->clipsta = 100.0f;
+
+ params->overscan = 0.0f;
+ params->apply_overscan = false;
}
void BKE_camera_params_from_object(CameraParams *params, Object *ob)
@@ -227,6 +230,8 @@ void BKE_camera_params_from_object(CameraParams *params, Object *ob)
params->clipsta = cam->clipsta;
params->clipend = cam->clipend;
+
+ params->apply_overscan = true;
}
else if (ob->type == OB_LAMP) {
/* lamp object */
@@ -286,9 +291,11 @@ void BKE_camera_params_from_view3d(CameraParams *params, View3D *v3d, RegionView
void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int winy, float xasp, float yasp)
{
- rctf viewplane;
+ rctf viewplane, underscan_viewplane;
float pixsize, viewfac, sensor_size, dx, dy;
int sensor_fit;
+ float overscan = params->overscan / 100.0f;
+ float viewx, viewy;
/* fields rendering */
params->ycor = yasp / xasp;
@@ -335,15 +342,32 @@ void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int win
viewplane.xmax += dx;
viewplane.ymax += dy;
+ underscan_viewplane = viewplane;
+
+ /* apply overscan */
+ if (params->apply_overscan) {
+ viewx = viewplane.xmax - viewplane.xmin;
+ viewy = viewplane.ymax - viewplane.ymin;
+
+ viewplane.xmin -= 0.5f*overscan*viewx;
+ viewplane.xmax += 0.5f*overscan*viewx;
+ viewplane.ymin -= 0.5f*overscan*viewy;
+ viewplane.ymax += 0.5f*overscan*viewy;
+ }
+
/* fields offset */
if (params->field_second) {
if (params->field_odd) {
viewplane.ymin -= 0.5f * params->ycor;
viewplane.ymax -= 0.5f * params->ycor;
+ underscan_viewplane.ymin -= 0.5f * params->ycor;
+ underscan_viewplane.ymax -= 0.5f * params->ycor;
}
else {
viewplane.ymin += 0.5f * params->ycor;
viewplane.ymax += 0.5f * params->ycor;
+ underscan_viewplane.ymin += 0.5f * params->ycor;
+ underscan_viewplane.ymax += 0.5f * params->ycor;
}
}
@@ -354,9 +378,15 @@ void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int win
viewplane.ymin *= pixsize;
viewplane.ymax *= pixsize;
+ underscan_viewplane.xmin *= pixsize;
+ underscan_viewplane.xmax *= pixsize;
+ underscan_viewplane.ymin *= pixsize;
+ underscan_viewplane.ymax *= pixsize;
+
params->viewdx = pixsize;
params->viewdy = params->ycor * pixsize;
params->viewplane = viewplane;
+ params->underscan_viewplane = underscan_viewplane;
}
/* viewplane is assumed to be already computed */
@@ -380,6 +410,7 @@ void BKE_camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, cons
{
float facx, facy;
float depth;
+ float overscan_factor= 1.0f;
/* aspect correcton */
if (scene) {
@@ -387,6 +418,8 @@ void BKE_camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, cons
float aspy = (float) scene->r.ysch * scene->r.yasp;
int sensor_fit = BKE_camera_sensor_fit(camera->sensor_fit, aspx, aspy);
+ overscan_factor = 1.0f + scene->r.overscan / 100.0f;
+
if (sensor_fit == CAMERA_SENSOR_FIT_HOR) {
r_asp[0] = 1.0;
r_asp[1] = aspy / aspx;
@@ -401,12 +434,12 @@ void BKE_camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, cons
r_asp[1] = 1.0f;
}
- if (camera->type == CAM_ORTHO) {
- facx = 0.5f * camera->ortho_scale * r_asp[0] * scale[0];
- facy = 0.5f * camera->ortho_scale * r_asp[1] * scale[1];
- r_shift[0] = camera->shiftx * camera->ortho_scale * scale[0];
- r_shift[1] = camera->shifty * camera->ortho_scale * scale[1];
- depth = do_clip ? -((camera->clipsta * scale[2]) + 0.1f) : -drawsize * camera->ortho_scale * scale[2];
+ if (camera->type==CAM_ORTHO) {
+ facx = 0.5f * camera->ortho_scale * r_asp[0] * scale[0] * overscan_factor;
+ facy = 0.5f * camera->ortho_scale * r_asp[1] * scale[1] * overscan_factor;
+ r_shift[0] = camera->shiftx * camera->ortho_scale * scale[0] * overscan_factor;
+ r_shift[1] = camera->shifty * camera->ortho_scale * scale[1] * overscan_factor;
+ depth = do_clip ? -((camera->clipsta * scale[2]) + 0.1f) : - drawsize * camera->ortho_scale * scale[2];
*r_drawsize = 0.5f * camera->ortho_scale;
}
@@ -435,10 +468,10 @@ void BKE_camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, cons
scale_y = scale[1];
}
- facx = fac * r_asp[0] * scale_x;
- facy = fac * r_asp[1] * scale_y;
- r_shift[0] = camera->shiftx * fac * 2.0f * scale_x;
- r_shift[1] = camera->shifty * fac * 2.0f * scale_y;
+ facx = fac * r_asp[0] * scale_x * overscan_factor;
+ facy = fac * r_asp[1] * scale_y * overscan_factor;
+ r_shift[0] = camera->shiftx * fac * 2.0f * scale_x * overscan_factor;
+ r_shift[1] = camera->shifty * fac * 2.0f * scale_y * overscan_factor;
}
r_vec[0][0] = r_shift[0] + facx; r_vec[0][1] = r_shift[1] + facy; r_vec[0][2] = depth;
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index df1695daf5b..f051582d9f4 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -2475,9 +2475,15 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id)
if (idtype == ID_MC) {
MovieClip *clip = (MovieClip *) id;
+ Scene *scene;
BKE_tracking_dopesheet_tag_update(&clip->tracking);
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
+ if (scene->clip == (MovieClip*)id)
+ BKE_scene_update_overscan(scene);
+ }
+
for (obt = bmain->object.first; obt; obt = obt->id.next) {
bConstraint *con;
for (con = obt->constraints.first; con; con = con->next) {
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 608b0495454..01eb2457ed5 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -52,6 +52,7 @@
#include "DNA_screen_types.h"
#include "DNA_sequence_types.h"
#include "DNA_space_types.h"
+#include "DNA_movieclip_types.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
@@ -86,6 +87,8 @@
#include "BKE_sequencer.h"
#include "BKE_sound.h"
#include "BKE_world.h"
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
#include "RE_engine.h"
@@ -1891,3 +1894,14 @@ int BKE_scene_num_omp_threads(const struct Scene *scene)
else
return scene->omp_threads;
}
+
+/* overscan */
+void BKE_scene_update_overscan(Scene *scene)
+{
+ float overscan = scene->r.overscan;
+
+ if (scene->r.detect_overscan && scene->clip)
+ overscan = BKE_tracking_overscan_detect(scene->clip);
+
+ scene->r.overscan = overscan;
+}
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index ca0b52bd7c2..80db404fbe5 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -49,6 +49,7 @@
#include "BLI_listbase.h"
#include "BLI_ghash.h"
#include "BLI_path_util.h"
+#include "BLI_rect.h"
#include "BLI_string.h"
#include "BLI_threads.h"
@@ -1954,6 +1955,34 @@ void BKE_tracking_max_undistortion_delta_across_bound(MovieTracking *tracking, r
}
}
+float BKE_tracking_overscan_detect(MovieClip *clip)
+{
+ float overscan = 0.0f;
+ float scalex = 1.0f, scaley = 1.0f;
+ int width, height;
+ float delta[2];
+ rcti rect;
+ MovieClipUser user= {0};
+
+ BKE_movieclip_user_set_frame(&user, 1);
+
+ BKE_movieclip_get_size(clip, &user, &width, &height);
+ BLI_rcti_init(&rect, 0, width, 0, height);
+ BKE_tracking_max_undistortion_delta_across_bound(&clip->tracking, &rect, delta);
+
+ if (delta[0] > 0.0f) {
+ scalex = 1.0f + delta[0] / width;
+ }
+
+ if (delta[1] > 0.0f) {
+ scaley = 1.0f + delta[1] / height;
+ }
+
+ overscan = (MAX2(scalex, scaley) - 1.0f) * 100.0f;
+
+ return overscan;
+}
+
/*********************** Image sampling *************************/
static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, bool grayscale)
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index a4597b6bf6c..6f134aef5a3 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -782,7 +782,7 @@ void draw_gpencil_view3d(Scene *scene, View3D *v3d, ARegion *ar, bool only3d)
* deal with the camera border, otherwise map the coords to the camera border. */
if ((rv3d->persp == RV3D_CAMOB) && !(G.f & G_RENDER_OGL)) {
rctf rectf;
- ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &rectf, true); /* no shift */
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &rectf, NULL, true); /* no shift */
offsx = iroundf(rectf.xmin);
offsy = iroundf(rectf.ymin);
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 4c4926f5ae7..8593aa68a2e 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -1389,7 +1389,7 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect)
/* for camera view set the subrect */
if (rv3d->persp == RV3D_CAMOB) {
Scene *scene = CTX_data_scene(C);
- ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, subrect, true); /* no shift */
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, subrect, NULL, true); /* no shift */
return 1;
}
}
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 6bbaca73eb5..253a34eae3a 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -1278,7 +1278,7 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode)
/* for camera view set the subrect */
if (rv3d->persp == RV3D_CAMOB) {
- ED_view3d_calc_camera_border(p->scene, p->ar, v3d, rv3d, &p->subrect_data, true); /* no shift */
+ ED_view3d_calc_camera_border(p->scene, p->ar, v3d, rv3d, &p->subrect_data, NULL, true); /* no shift */
p->subrect = &p->subrect_data;
}
}
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 377bb7cebb1..992b9eeb3ac 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -221,13 +221,14 @@ void ED_view3d_unproject(struct bglMats *mats, float out[3], const float x, cons
bool ED_view3d_clip_range_get(struct View3D *v3d, struct RegionView3D *rv3d,
float *r_clipsta, float *r_clipend, const bool use_ortho_factor);
bool ED_view3d_viewplane_get(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi,
- struct rctf *r_viewplane, float *r_clipsta, float *r_clipend, float *r_pixsize);
+ float overscan, struct rctf *r_viewplane, float *r_clipsta,
+ float *r_clipend, float *r_pixsize);
void ED_view3d_polygon_offset(const struct RegionView3D *rv3d, const float dist);
void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar,
struct View3D *v3d, struct RegionView3D *rv3d,
- struct rctf *r_viewborder, const bool no_shift);
+ struct rctf *r_viewborder, struct rctf *r_underscan_viewborder, const bool no_shift);
void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar,
struct View3D *v3d, struct RegionView3D *rv3d,
float r_size[2]);
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 3078b16ceeb..fd896665e65 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -1035,7 +1035,7 @@ static int render_view3d_disprect(Scene *scene, ARegion *ar, View3D *v3d, Region
if (draw_border) {
if (rv3d->persp == RV3D_CAMOB) {
- ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false);
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, NULL, false);
disprect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
disprect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
@@ -1063,7 +1063,7 @@ static bool render_view3d_get_rects(ARegion *ar, View3D *v3d, RegionView3D *rv3d
if (ar->winx < 4 || ar->winy < 4) return false;
- *r_ortho = ED_view3d_viewplane_get(v3d, rv3d, ar->winx, ar->winy, viewplane, r_clipsta, r_clipend, r_pixsize);
+ *r_ortho = ED_view3d_viewplane_get(v3d, rv3d, ar->winx, ar->winy, 0.0f, viewplane, r_clipsta, r_clipend, r_pixsize);
engine->resolution_x = ar->winx;
engine->resolution_y = ar->winy;
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index e095485f68b..892c69c9005 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -194,9 +194,9 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
rctf viewplane;
float clipsta, clipend;
- bool is_ortho = ED_view3d_viewplane_get(v3d, rv3d, sizex, sizey, &viewplane, &clipsta, &clipend, NULL);
+ bool is_ortho = ED_view3d_viewplane_get(v3d, rv3d, sizex, sizey, 0.0f, &viewplane, &clipsta, &clipend, NULL);
if (is_ortho) orthographic_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, -clipend, clipend);
- else perspective_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
+ else perspective_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
}
rect = MEM_mallocN(sizex * sizey * sizeof(unsigned char) * 4, "offscreen rect");
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index eb5c23a60f7..d97c0aa82d6 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -1897,6 +1897,18 @@ static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, Po
return;
uiItemR(layout, ptr, "distortion_type", 0, "", ICON_NONE);
+ uiItemR(layout, ptr, "use_detect_overscan", 0, NULL, 0);
+
+ if ((node->custom2 & CMP_NODE_MOVIEDISTORTION_DETECTOVERSCAN) == 0) {
+ uiItemR(layout, ptr, "overscan", 0, NULL, 0);
+ }
+ else {
+ char buf[64];
+ BLI_snprintf(buf, sizeof(buf), "Overscan: %.1f%%", node->custom3);
+ uiItemL(layout, buf, 0);
+ }
+
+ uiItemR(layout, ptr, "use_crop_overscan", 0, NULL, 0);
}
static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index d9bc40b6555..50db6282e4e 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -1723,6 +1723,7 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
float drawsize;
const bool is_view = (rv3d->persp == RV3D_CAMOB && ob == v3d->camera);
MovieClip *clip = BKE_object_movieclip_get(scene, base->object, false);
+ float overscan_factor = 1.0f + scene->r.overscan / 100.0f;
/* draw data for movie clip set as active for scene */
if (clip) {
@@ -1795,15 +1796,15 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base
else if (i == 1 && (ob == v3d->camera)) glBegin(GL_TRIANGLES);
else break;
- tvec[0] = shift[0] + ((-0.7f * drawsize) * scale[0]);
- tvec[1] = shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]);
+ tvec[0] = shift[0] + ((-0.7f * drawsize) * scale[0]) * overscan_factor;
+ tvec[1] = shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]) * overscan_factor;
glVertex3fv(tvec); /* left */
- tvec[0] = shift[0] + ((0.7f * drawsize) * scale[0]);
+ tvec[0] = shift[0] + ((0.7f * drawsize) * scale[0]) * overscan_factor;
glVertex3fv(tvec); /* right */
tvec[0] = shift[0];
- tvec[1] = shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]);
+ tvec[1] = shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]) * overscan_factor;
glVertex3fv(tvec); /* top */
glEnd();
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index d22dca4ad88..fbd5c3f4e1f 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -934,17 +934,27 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
BLF_draw_default(offset, 0.5f * U.widget_unit, 0.0f, info, sizeof(info));
}
+static void view3d_camera_border_within_viewport(ARegion *ar, rctf *rect_view, rctf *rect_camera, rctf *viewborder_r)
+{
+ viewborder_r->xmin = ((rect_camera->xmin - rect_view->xmin)/BLI_rctf_size_x(rect_view))*ar->winx;
+ viewborder_r->xmax = ((rect_camera->xmax - rect_view->xmin)/BLI_rctf_size_x(rect_view))*ar->winx;
+ viewborder_r->ymin = ((rect_camera->ymin - rect_view->ymin)/BLI_rctf_size_y(rect_view))*ar->winy;
+ viewborder_r->ymax = ((rect_camera->ymax - rect_view->ymin)/BLI_rctf_size_y(rect_view))*ar->winy;
+}
+
static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d,
- rctf *r_viewborder, const bool no_shift, const bool no_zoom)
+ rctf *r_viewborder, rctf *r_underscan_viewborder,
+ const bool no_shift, const bool no_zoom)
{
CameraParams params;
- rctf rect_view, rect_camera;
+ rctf rect_view, rect_camera, rect_camera_underscan;
/* get viewport viewplane */
BKE_camera_params_init(&params);
BKE_camera_params_from_view3d(&params, v3d, rv3d);
if (no_zoom)
params.zoom = 1.0f;
+ params.overscan = scene->r.overscan;
BKE_camera_params_compute_viewplane(&params, ar->winx, ar->winy, 1.0f, 1.0f);
rect_view = params.viewplane;
@@ -958,29 +968,33 @@ static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionV
params.shiftx = 0.0f;
params.shifty = 0.0f;
}
+ params.overscan = scene->r.overscan;
BKE_camera_params_compute_viewplane(&params, scene->r.xsch, scene->r.ysch, scene->r.xasp, scene->r.yasp);
rect_camera = params.viewplane;
+ rect_camera_underscan = params.underscan_viewplane;
/* get camera border within viewport */
- r_viewborder->xmin = ((rect_camera.xmin - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx;
- r_viewborder->xmax = ((rect_camera.xmax - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx;
- r_viewborder->ymin = ((rect_camera.ymin - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy;
- r_viewborder->ymax = ((rect_camera.ymax - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy;
+ if (r_viewborder)
+ view3d_camera_border_within_viewport(ar, &rect_view, &rect_camera, r_viewborder);
+
+ if (r_underscan_viewborder)
+ view3d_camera_border_within_viewport(ar, &rect_view, &rect_camera_underscan, r_underscan_viewborder);
}
void ED_view3d_calc_camera_border_size(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, float r_size[2])
{
rctf viewborder;
- view3d_camera_border(scene, ar, v3d, rv3d, &viewborder, true, true);
+ view3d_camera_border(scene, ar, v3d, rv3d, &viewborder, NULL, true, true);
r_size[0] = BLI_rctf_size_x(&viewborder);
r_size[1] = BLI_rctf_size_y(&viewborder);
}
void ED_view3d_calc_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d,
- rctf *r_viewborder, const bool no_shift)
+ rctf *r_viewborder, rctf *r_underscan_viewborder,
+ const bool no_shift)
{
- view3d_camera_border(scene, ar, v3d, rv3d, r_viewborder, no_shift, false);
+ view3d_camera_border(scene, ar, v3d, rv3d, r_viewborder, r_underscan_viewborder, no_shift, false);
}
static void drawviewborder_grid3(float x1, float x2, float y1, float y2, float fac)
@@ -1058,24 +1072,31 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
{
float hmargin, vmargin;
float x1, x2, y1, y2;
- float x1i, x2i, y1i, y2i;
+ float x1i, x2i, y1i, y2i, x5i, x6i, y5i, y6i;
+ float x5, y5, x6, y6;
- rctf viewborder;
+ rctf viewborder, underscan_viewborder;
Camera *ca = NULL;
RegionView3D *rv3d = ar->regiondata;
+ int draw_passepart;
if (v3d->camera == NULL)
return;
if (v3d->camera->type == OB_CAMERA)
ca = v3d->camera->data;
- ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false);
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, &underscan_viewborder, false);
/* the offsets */
x1 = viewborder.xmin;
y1 = viewborder.ymin;
x2 = viewborder.xmax;
y2 = viewborder.ymax;
-
+
+ x5 = underscan_viewborder.xmin;
+ y5 = underscan_viewborder.ymin;
+ x6 = underscan_viewborder.xmax;
+ y6 = underscan_viewborder.ymax;
+
/* apply offsets so the real 3D camera shows through */
/* note: quite un-scientific but without this bit extra
@@ -1085,11 +1106,18 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
* but keep it here in case we need to remove the workaround */
x1i = (int)(x1 - 1.0001f);
y1i = (int)(y1 - 1.0001f);
- x2i = (int)(x2 + (1.0f - 0.0001f));
- y2i = (int)(y2 + (1.0f - 0.0001f));
+ x2i = (int)(x2 + (1.0f-0.0001f));
+ y2i = (int)(y2 + (1.0f-0.0001f));
+
+ /* same goes to underscan border */
+ x5i = (int)(x5 - 1.0001f);
+ y5i = (int)(y5 - 1.0001f);
+ x6i = (int)(x6 + (1.0f-0.0001f));
+ y6i = (int)(y6 + (1.0f-0.0001f));
/* passepartout, specified in camera edit buttons */
- if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT) && ca->passepartalpha > 0.000001f) {
+ draw_passepart= (ca->flag & CAM_SHOWPASSEPARTOUT) && ca->passepartalpha > 0.000001f;
+ if (draw_passepart) {
if (ca->passepartalpha == 1.0f) {
glColor3f(0, 0, 0);
}
@@ -1138,6 +1166,32 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
UI_ThemeColor(TH_VIEW_OVERLAY);
glRectf(x1i, y1i, x2i, y2i);
+ if (scene->r.overscan > 0.0f) {
+ UI_ThemeColorShade(TH_WIRE, 100);
+ uiDrawBox(GL_LINE_LOOP, x5i, y5i, x6i, y6i, 2.0);
+
+ if (draw_passepart) {
+ setlinestyle(0);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glColor4f(0, 0, 0, ca->passepartalpha*0.5f);
+
+ if (x5i > x1i)
+ glRectf(x1i, y1i, x5i, y2i);
+ if (x6i < x2i)
+ glRectf(x6i, y1i, x2i, y2i);
+ if (y6i < y2i)
+ glRectf(x5i, y6i, x6i, y2i);
+ if (y5i > y1i)
+ glRectf(x5i, y5i, x6i, y1i);
+ setlinestyle(3);
+ }
+
+ glDisable(GL_BLEND);
+ }
+
/* border */
if (scene->r.mode & R_BORDER) {
float x3, y3, x4, y4;
@@ -1148,7 +1202,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
y4 = y1 + scene->r.border.ymax * (y2 - y1);
cpack(0x4040FF);
- glRecti(x3, y3, x4, y4);
+ glRectf(x3, y3, x4, y4);
}
/* safety border */
@@ -1158,15 +1212,15 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- x3 = x1 + 0.5f * (x2 - x1);
- y3 = y1 + 0.5f * (y2 - y1);
+ x3 = x5+ 0.5f*(x6-x5);
+ y3 = y5+ 0.5f*(y6-y5);
glBegin(GL_LINES);
- glVertex2f(x1, y3);
- glVertex2f(x2, y3);
+ glVertex2f(x5, y3);
+ glVertex2f(x6, y3);
- glVertex2f(x3, y1);
- glVertex2f(x3, y2);
+ glVertex2f(x3, y5);
+ glVertex2f(x3, y6);
glEnd();
}
@@ -1174,54 +1228,54 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
glBegin(GL_LINES);
- glVertex2f(x1, y1);
- glVertex2f(x2, y2);
+ glVertex2f(x5, y5);
+ glVertex2f(x6, y6);
- glVertex2f(x1, y2);
- glVertex2f(x2, y1);
+ glVertex2f(x5, y6);
+ glVertex2f(x6, y5);
glEnd();
}
if (ca->dtx & CAM_DTX_THIRDS) {
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_grid3(x1, x2, y1, y2, 1.0f / 3.0f);
+ drawviewborder_grid3(x5, x6, y5, y6, 1.0f / 3.0f);
}
if (ca->dtx & CAM_DTX_GOLDEN) {
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_grid3(x1, x2, y1, y2, 1.0f - (1.0f / 1.61803399f));
+ drawviewborder_grid3(x5, x6, y5, y6, 1.0f - (1.0f / 1.61803399f));
}
if (ca->dtx & CAM_DTX_GOLDEN_TRI_A) {
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_triangle(x1, x2, y1, y2, 0, 'A');
+ drawviewborder_triangle(x5, x6, y5, y6, 0, 'A');
}
if (ca->dtx & CAM_DTX_GOLDEN_TRI_B) {
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_triangle(x1, x2, y1, y2, 0, 'B');
+ drawviewborder_triangle(x5, x6, y5, y6, 0, 'B');
}
if (ca->dtx & CAM_DTX_HARMONY_TRI_A) {
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_triangle(x1, x2, y1, y2, 1, 'A');
+ drawviewborder_triangle(x5, x6, y5, y6, 1, 'A');
}
if (ca->dtx & CAM_DTX_HARMONY_TRI_B) {
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- drawviewborder_triangle(x1, x2, y1, y2, 1, 'B');
+ drawviewborder_triangle(x5, x6, y5, y6, 1, 'B');
}
if (ca->flag & CAM_SHOWTITLESAFE) {
UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
- hmargin = 0.1f * (x2 - x1);
- vmargin = 0.05f * (y2 - y1);
- uiDrawBox(GL_LINE_LOOP, x1 + hmargin, y1 + vmargin, x2 - hmargin, y2 - vmargin, 2.0f);
+ hmargin = 0.1f * (x6 - x5);
+ vmargin = 0.05f * (y6 - y5);
+ uiDrawBox(GL_LINE_LOOP, x5 + hmargin, y5 + vmargin, x6 - hmargin, y6 - vmargin, 2.0f);
- hmargin = 0.035f * (x2 - x1);
- vmargin = 0.035f * (y2 - y1);
- uiDrawBox(GL_LINE_LOOP, x1 + hmargin, y1 + vmargin, x2 - hmargin, y2 - vmargin, 2.0f);
+ hmargin = 0.035f * (x6 - x5);
+ vmargin = 0.035f * (y6 - y5);
+ uiDrawBox(GL_LINE_LOOP, x5 + hmargin, y5 + vmargin, x6 - hmargin, y6 - vmargin, 2.0f);
}
if (ca->flag & CAM_SHOWSENSOR) {
/* determine sensor fit, and get sensor x/y, for auto fit we
@@ -1236,22 +1290,22 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
rctf rect;
if (sensor_fit == CAMERA_SENSOR_FIT_HOR) {
- float sensor_scale = (x2i - x1i) / sensor_x;
+ float sensor_scale = (x6i-x5i) / sensor_x;
float sensor_height = sensor_scale * sensor_y;
- rect.xmin = x1i;
- rect.xmax = x2i;
- rect.ymin = (y1i + y2i) * 0.5f - sensor_height * 0.5f;
+ rect.xmin = x5i;
+ rect.xmax = x6i;
+ rect.ymin = (y5i + y6i) * 0.5f - sensor_height * 0.5f;
rect.ymax = rect.ymin + sensor_height;
}
else {
- float sensor_scale = (y2i - y1i) / sensor_y;
+ float sensor_scale = (y6i-y5i) / sensor_y;
float sensor_width = sensor_scale * sensor_x;
- rect.xmin = (x1i + x2i) * 0.5f - sensor_width * 0.5f;
+ rect.xmin = (x5i + x6i) * 0.5f - sensor_width * 0.5f;
rect.xmax = rect.xmin + sensor_width;
- rect.ymin = y1i;
- rect.ymax = y2i;
+ rect.ymin = y5i;
+ rect.ymax = y6i;
}
/* draw */
@@ -1669,7 +1723,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
if (do_camera_frame) {
rctf vb;
- ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, false);
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, NULL, &vb, false);
x1 = vb.xmin;
y1 = vb.ymin;
x2 = vb.xmax;
@@ -2221,9 +2275,10 @@ float view3d_depth_near(ViewDepths *d)
void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
{
short zbuf = v3d->zbuf;
+ float overscan = scene->r.overscan;
RegionView3D *rv3d = ar->regiondata;
- setwinmatrixview3d(ar, v3d, NULL);
+ setwinmatrixview3d(ar, v3d, NULL, overscan);
setviewmatrixview3d(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
@@ -2253,6 +2308,7 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (*func)(void *), boo
short flag = v3d->flag;
float glalphaclip = U.glalphaclip;
int obcenter_dia = U.obcenter_dia;
+ float overscan = scene->r.overscan;
/* temp set drawtype to solid */
/* Setting these temporarily is not nice */
@@ -2260,7 +2316,7 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (*func)(void *), boo
U.glalphaclip = alphaoverride ? 0.5f : glalphaclip; /* not that nice but means we wont zoom into billboards */
U.obcenter_dia = 0;
- setwinmatrixview3d(ar, v3d, NULL);
+ setwinmatrixview3d(ar, v3d, NULL, overscan);
setviewmatrixview3d(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
@@ -2514,12 +2570,13 @@ CustomDataMask ED_view3d_screen_datamask(bScreen *screen)
void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
{
RegionView3D *rv3d = ar->regiondata;
+ float overscan= scene->r.overscan;
/* setup window matrices */
if (winmat)
copy_m4_m4(rv3d->winmat, winmat);
else
- setwinmatrixview3d(ar, v3d, NULL);
+ setwinmatrixview3d(ar, v3d, NULL, overscan);
/* setup view matrix */
if (viewmat)
@@ -3027,7 +3084,7 @@ bool ED_view3d_calc_render_border(Scene *scene, View3D *v3d, ARegion *ar, rcti *
/* compute border */
if (rv3d->persp == RV3D_CAMOB) {
- ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false);
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, NULL, false);
rect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
rect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 6b08ae98677..d91aa92bbc7 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -3082,7 +3082,7 @@ static int render_border_exec(bContext *C, wmOperator *op)
/* calculate range */
if (rv3d->persp == RV3D_CAMOB) {
- ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, false);
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, NULL, false);
}
else {
vb.xmin = 0;
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index 6afe0ef896f..ae61931e4d5 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -234,7 +234,7 @@ static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar),
float x1, x2, y1, y2;
if (fly->scene->camera) {
- ED_view3d_calc_camera_border(fly->scene, fly->ar, fly->v3d, fly->rv3d, &viewborder, false);
+ ED_view3d_calc_camera_border(fly->scene, fly->ar, fly->v3d, fly->rv3d, &viewborder, NULL, false);
xoff = viewborder.xmin;
yoff = viewborder.ymin;
}
@@ -391,7 +391,7 @@ static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent
/* calculate center */
if (fly->scene->camera) {
- ED_view3d_calc_camera_border(fly->scene, fly->ar, fly->v3d, fly->rv3d, &viewborder, false);
+ ED_view3d_calc_camera_border(fly->scene, fly->ar, fly->v3d, fly->rv3d, &viewborder, NULL, false);
fly->width = BLI_rctf_size_x(&viewborder);
fly->height = BLI_rctf_size_y(&viewborder);
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 3e7c97abaa9..0a9e0ab85aa 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -208,7 +208,7 @@ void ED_view3d_smooth_view(struct bContext *C, struct View3D *v3d, struct ARegio
float *ofs, float *quat, float *dist, float *lens,
const int smooth_viewtx);
-void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect);
+void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect, float overscan);
void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d);
void fly_modal_keymap(struct wmKeyConfig *keyconf);
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index fdfce062adc..169bd584c94 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -728,12 +728,13 @@ bool ED_view3d_clip_range_get(View3D *v3d, RegionView3D *rv3d, float *r_clipsta,
}
/* also exposed in previewrender.c */
-bool ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy,
+bool ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy, float overscan,
rctf *r_viewplane, float *r_clipsta, float *r_clipend, float *r_pixsize)
{
CameraParams params;
BKE_camera_params_init(&params);
+ params.overscan = overscan;
BKE_camera_params_from_view3d(&params, v3d, rv3d);
BKE_camera_params_compute_viewplane(&params, winx, winy, 1.0f, 1.0f);
@@ -767,14 +768,14 @@ void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist)
/*!
* \param rect for picking, NULL not to use.
*/
-void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect)
+void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect, float overscan)
{
RegionView3D *rv3d = ar->regiondata;
rctf viewplane;
float clipsta, clipend, x1, y1, x2, y2;
bool is_ortho;
- is_ortho = ED_view3d_viewplane_get(v3d, rv3d, ar->winx, ar->winy, &viewplane, &clipsta, &clipend, NULL);
+ is_ortho = ED_view3d_viewplane_get(v3d, rv3d, ar->winx, ar->winy, overscan, &viewplane, &clipsta, &clipend, NULL);
rv3d->is_persp = !is_ortho;
#if 0
@@ -963,6 +964,7 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b
char dt;
short dtx;
const bool use_obedit_skip = (scene->obedit != NULL) && (vc->obedit == NULL);
+ float overscan = scene->r.overscan;
G.f |= G_PICKSEL;
@@ -977,7 +979,7 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b
BLI_rctf_rcti_copy(&rect, input);
}
- setwinmatrixview3d(ar, v3d, &rect);
+ setwinmatrixview3d(ar, v3d, &rect, overscan);
mul_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
if (v3d->drawtype > OB_WIRE) {
@@ -1061,7 +1063,7 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b
hits = glRenderMode(GL_RENDER);
G.f &= ~G_PICKSEL;
- setwinmatrixview3d(ar, v3d, NULL);
+ setwinmatrixview3d(ar, v3d, NULL, overscan);
mul_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
if (v3d->drawtype > OB_WIRE) {
@@ -1550,7 +1552,7 @@ static int game_engine_exec(bContext *C, wmOperator *op)
{
/* Letterbox */
rctf cam_framef;
- ED_view3d_calc_camera_border(startscene, ar, CTX_wm_view3d(C), rv3d, &cam_framef, false);
+ ED_view3d_calc_camera_border(startscene, ar, CTX_wm_view3d(C), rv3d, &cam_framef, NULL, false);
cam_frame.xmin = cam_framef.xmin + ar->winrct.xmin;
cam_frame.xmax = cam_framef.xmax + ar->winrct.xmin;
cam_frame.ymin = cam_framef.ymin + ar->winrct.ymin;
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index fa395c9af31..96d3286eb1c 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -308,7 +308,7 @@ static void drawWalkPixel(const struct bContext *UNUSED(C), ARegion *ar, void *a
rctf viewborder;
if (walk->scene->camera) {
- ED_view3d_calc_camera_border(walk->scene, ar, walk->v3d, walk->rv3d, &viewborder, false);
+ ED_view3d_calc_camera_border(walk->scene, ar, walk->v3d, walk->rv3d, &viewborder, NULL, false);
xoff = viewborder.xmin + BLI_rctf_size_x(&viewborder) * 0.5f;
yoff = viewborder.ymin + BLI_rctf_size_y(&viewborder) * 0.5f;
}
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index 0f4e9fa16f2..25ff62aefcd 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -1692,7 +1692,7 @@ void BIF_draw_manipulator(const bContext *C)
}
}
-static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], float hotspot)
+static int manipulator_selectbuf(Scene *scene, ScrArea *sa, ARegion *ar, const int mval[2], float hotspot)
{
View3D *v3d = sa->spacedata.first;
RegionView3D *rv3d = ar->regiondata;
@@ -1701,19 +1701,24 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl
short hits;
const bool is_picksel = true;
- extern void setwinmatrixview3d(ARegion *, View3D *, rctf *); // XXX check a bit later on this... (ton)
+ extern void setwinmatrixview3d(ARegion *, View3D *, rctf *, float /*overscan*/); // XXX check a bit later on this... (ton)
+ float overscan = 0.0f;
/* when looking through a selected camera, the manipulator can be at the
* exact same position as the view, skip so we don't break selection */
if (fabsf(mat4_to_scale(rv3d->twmat)) < 1e-7f)
return 0;
+ if (rv3d->persp == RV3D_CAMOB) {
+ overscan = scene->r.overscan;
+ }
+
rect.xmin = mval[0] - hotspot;
rect.xmax = mval[0] + hotspot;
rect.ymin = mval[1] - hotspot;
rect.ymax = mval[1] + hotspot;
- setwinmatrixview3d(ar, v3d, &rect);
+ setwinmatrixview3d(ar, v3d, &rect, overscan);
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
glSelectBuffer(64, buffer);
@@ -1734,7 +1739,7 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl
glPopName();
hits = glRenderMode(GL_RENDER);
- setwinmatrixview3d(ar, v3d, NULL);
+ setwinmatrixview3d(ar, v3d, NULL, overscan);
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
if (hits == 1) return buffer[3];
@@ -1786,6 +1791,7 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
ARegion *ar = CTX_wm_region(C);
+ Scene *scene = CTX_data_scene(C);
int constraint_axis[3] = {0, 0, 0};
int val;
int shift = event->shift;
@@ -1797,11 +1803,11 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
RNA_enum_set(op->ptr, "constraint_orientation", v3d->twmode);
// find the hotspots first test narrow hotspot
- val = manipulator_selectbuf(sa, ar, event->mval, 0.5f * (float)U.tw_hotspot);
+ val = manipulator_selectbuf(scene, sa, ar, event->mval, 0.5f * (float)U.tw_hotspot);
if (val) {
// drawflags still global, for drawing call above
- drawflags = manipulator_selectbuf(sa, ar, event->mval, 0.2f * (float)U.tw_hotspot);
+ drawflags = manipulator_selectbuf(scene, sa, ar, event->mval, 0.2f * (float)U.tw_hotspot);
if (drawflags == 0) drawflags = val;
if (drawflags & MAN_TRANS_C) {
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index e13d53934cb..5e885b82c36 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1041,4 +1041,8 @@ enum {
/* viewer and cmposite output */
#define CMP_NODE_OUTPUT_IGNORE_ALPHA 1
+/* movie distoriton */
+#define CMP_NODE_MOVIEDISTORTION_DETECTOVERSCAN (1<<0)
+#define CMP_NODE_MOVIEDISTORTION_CROPOVERSCAN (1<<1)
+
#endif
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index e36ce7d9657..4b93de39a3a 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -533,7 +533,10 @@ typedef struct RenderData {
char seq_prev_type;
char seq_rend_type;
char seq_flag; /* flag use for sequence render/draw */
- char pad5[5];
+
+ /* overscan */
+ char detect_overscan;
+ float overscan;
/* render simplify */
int simplify_flag;
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 0f2380cbad4..cd68393c4c1 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -5486,6 +5486,24 @@ static void def_cmp_moviedistortion(StructRNA *srna)
RNA_def_property_enum_items(prop, distortion_type_items);
RNA_def_property_ui_text(prop, "Distortion", "Distortion to use to filter image");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "overscan", PROP_FLOAT, PROP_PERCENTAGE);
+ RNA_def_property_float_sdna(prop, NULL, "custom3");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_range(prop, 0.0f, 100.0f);
+ RNA_def_property_ui_range(prop, 0, 100, 10, 1);
+ RNA_def_property_ui_text(prop, "Overscan", "Factor of overscan meaning percentage from original resolution to be added in both directions");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "use_detect_overscan", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "custom2", CMP_NODE_MOVIEDISTORTION_DETECTOVERSCAN);
+ RNA_def_property_ui_text(prop, "Detect Overscan", "Automatically detect overscan value from input image buffer");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "use_crop_overscan", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "custom2", CMP_NODE_MOVIEDISTORTION_CROPOVERSCAN);
+ RNA_def_property_ui_text(prop, "Crop Overscan", "Crop overscan pixels from output image");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_cmp_mask(StructRNA *srna)
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 1d83206f17f..deab69dbcbe 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -511,6 +511,19 @@ static void rna_Scene_volume_set(PointerRNA *ptr, float value)
sound_set_scene_volume(scene, value);
}
+static void rna_Scene_overscan_set(PointerRNA *ptr, float value)
+{
+ Scene *scene = (Scene*)(ptr->id.data);
+
+ if (!scene->r.detect_overscan)
+ scene->r.overscan = value;
+}
+
+static void rna_Scene_detect_overscan_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+{
+ BKE_scene_update_overscan(scene);
+}
+
static void rna_Scene_framelen_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
{
scene->r.framelen = (float)scene->r.framapto / (float)scene->r.images;
@@ -4240,6 +4253,20 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "FPS Base", "Framerate base");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_fps_update");
+ prop = RNA_def_property(srna, "overscan", PROP_FLOAT, PROP_PERCENTAGE);
+ RNA_def_property_float_sdna(prop, NULL, "overscan");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_float_funcs(prop, NULL, "rna_Scene_overscan_set", NULL);
+ RNA_def_property_range(prop, 0.0f, 100.0f);
+ RNA_def_property_ui_range(prop, 0, 100, 10, 1);
+ RNA_def_property_ui_text(prop, "Overscan", "Amount of overscan meaning percentage from original resolution to be added in both directions");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "use_detect_overscan", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "detect_overscan", 1);
+ RNA_def_property_ui_text(prop, "Detect Overscan", "Automatically detect overscan from distortion mode of active scene clip");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_detect_overscan_update");
+
/* frame mapping */
prop = RNA_def_property(srna, "frame_map_old", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "framapto");
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 6d994b36f26..e1131ca2be4 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -200,6 +200,8 @@ void RE_SetWindow(struct Render *re, rctf *viewplane, float clipsta, float clipe
void RE_SetOrtho(struct Render *re, rctf *viewplane, float clipsta, float clipend);
void RE_SetPixelSize(struct Render *re, float pixsize);
+void RE_SceneRenderSize(struct Scene *scene, int *width, int *height);
+
/* option to set viewmatrix before making dbase */
void RE_SetView(struct Render *re, float mat[4][4]);
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 2c431bf869c..25dedf57ca1 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -493,9 +493,11 @@ void RE_SetEnvmapCamera(Render *re, Object *cam_ob, float viewscale, float clips
void RE_SetCamera(Render *re, Object *cam_ob)
{
CameraParams params;
+ float overscan = re->scene->r.overscan;
/* setup parameters */
BKE_camera_params_init(&params);
+ params.overscan = overscan;
BKE_camera_params_from_object(&params, cam_ob);
params.use_fields = (re->r.mode & R_FIELDS);
@@ -523,6 +525,14 @@ void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, flo
copy_m4_m4(mat, re->winmat);
}
+void RE_SceneRenderSize(Scene *scene, int *width, int *height)
+{
+ float overscan_factor = 1.0f + scene->r.overscan / 100.0f;
+
+ *width = (scene->r.size*scene->r.xsch*overscan_factor) / 100;
+ *height = (scene->r.size*scene->r.ysch*overscan_factor) / 100;
+}
+
/* ~~~~~~~~~~~~~~~~ part (tile) calculus ~~~~~~~~~~~~~~~~~~~~~~ */
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 1a3d07f9aeb..401d561a09d 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -1568,8 +1568,7 @@ static void render_scene(Render *re, Scene *sce, int cfra)
/* exception: scene uses own size (unfinished code) */
if (0) {
- winx = (sce->r.size * sce->r.xsch) / 100;
- winy = (sce->r.size * sce->r.ysch) / 100;
+ RE_SceneRenderSize(sce, &winx, &winy);
}
/* initial setup */
@@ -2559,8 +2558,7 @@ static int render_initialize_from_main(Render *re, Main *bmain, Scene *scene, Sc
* r.border is the clipping rect */
/* calculate actual render result and display size */
- winx = (scene->r.size * scene->r.xsch) / 100;
- winy = (scene->r.size * scene->r.ysch) / 100;
+ RE_SceneRenderSize(scene, &winx, &winy);
/* we always render smaller part, inserting it in larger image is compositor bizz, it uses disprect for it */
if (scene->r.mode & R_BORDER) {
@@ -2953,8 +2951,7 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)
Object *camera;
int winx, winy;
- winx = (sce->r.size * sce->r.xsch) / 100;
- winy = (sce->r.size * sce->r.ysch) / 100;
+ RE_SceneRenderSize(sce, &winx, &winy);
RE_InitState(re, NULL, &sce->r, NULL, winx, winy, NULL);
@@ -2985,8 +2982,7 @@ bool RE_ReadRenderResult(Scene *scene, Scene *scenode)
rcti disprect;
/* calculate actual render result and display size */
- winx = (scene->r.size * scene->r.xsch) / 100;
- winy = (scene->r.size * scene->r.ysch) / 100;
+ RE_SceneRenderSize(scene, &winx, &winy);
/* only in movie case we render smaller part */
if (scene->r.mode & R_BORDER) {