diff options
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_draw.c')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 78 |
1 files changed, 67 insertions, 11 deletions
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 6d9507ebff1..fcb4f97bcbe 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1547,6 +1547,8 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, (bgpic->view & (1 << rv3d->view)) || /* check agaist flags */ (rv3d->persp == RV3D_CAMOB && bgpic->view == (1 << RV3D_VIEW_CAMERA))) { + float image_aspect[2]; + /* disable individual images */ if ((bgpic->flag & V3D_BGPIC_DISABLED)) continue; @@ -1558,6 +1560,9 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, continue; BKE_image_user_frame_calc(&bgpic->iuser, CFRA, 0); ibuf = BKE_image_get_ibuf(ima, &bgpic->iuser); + + image_aspect[0] = ima->aspx; + image_aspect[1] = ima->aspx; } else if (bgpic->source == V3D_BGPIC_MOVIE) { clip = NULL; @@ -1574,6 +1579,9 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, BKE_movieclip_user_set_frame(&bgpic->cuser, CFRA); ibuf = BKE_movieclip_get_ibuf(clip, &bgpic->cuser); + image_aspect[0] = clip->aspx; + image_aspect[1] = clip->aspx; + /* working with ibuf from image and clip has got different workflow now. * ibuf acquired from clip is referenced by cache system and should * be dereferenced after usage. */ @@ -1609,6 +1617,50 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, x2 = ar->winrct.xmax; y2 = ar->winrct.ymax; } + + /* apply offset last - camera offset is different to offset in blender units */ + /* so this has some sane way of working - this matches camera's shift _exactly_ */ + { + const float max_dim = maxf(x2 - x1, y2 - y1); + const float xof_scale = bgpic->xof * max_dim; + const float yof_scale = bgpic->yof * max_dim; + + x1 += xof_scale; + y1 += yof_scale; + x2 += xof_scale; + y2 += yof_scale; + } + + /* aspect correction */ + if (bgpic->flag & V3D_BGPIC_CAMERA_ASPECT) { + /* apply aspect from clip */ + const float w_src = ibuf->x * image_aspect[0]; + const float h_src = ibuf->y * image_aspect[1]; + + /* destination aspect is already applied from the camera frame */ + const float w_dst = x1 - x2; + const float h_dst = y1 - y2; + + const float asp_src = w_src / h_src; + const float asp_dst = w_dst / h_dst; + + if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) { + if ((asp_src > asp_dst) == ((bgpic->flag & V3D_BGPIC_CAMERA_CROP) != 0)) { + /* fit X */ + const float div = asp_src / asp_dst; + const float cent = (x1 + x2) / 2.0f; + x1 = ((x1 - cent) * div) + cent; + x2 = ((x2 - cent) * div) + cent; + } + else { + /* fit Y */ + const float div = asp_dst / asp_src; + const float cent = (y1 + y2) / 2.0f; + y1 = ((y1 - cent) * div) + cent; + y2 = ((y2 - cent) * div) + cent; + } + } + } } else { float sco[2]; @@ -2778,13 +2830,17 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw cliprct.ymin += ar->winrct.ymin; cliprct.ymax += ar->winrct.ymin; - cliprct.xmin = MAX2(cliprct.xmin, ar->winrct.xmin); - cliprct.ymin = MAX2(cliprct.ymin, ar->winrct.ymin); - cliprct.xmax = MIN2(cliprct.xmax, ar->winrct.xmax); - cliprct.ymax = MIN2(cliprct.ymax, ar->winrct.ymax); + cliprct.xmin = CLAMPIS(cliprct.xmin, ar->winrct.xmin, ar->winrct.xmax); + cliprct.ymin = CLAMPIS(cliprct.ymin, ar->winrct.ymin, ar->winrct.ymax); + cliprct.xmax = CLAMPIS(cliprct.xmax, ar->winrct.xmin, ar->winrct.xmax); + cliprct.ymax = CLAMPIS(cliprct.ymax, ar->winrct.ymin, ar->winrct.ymax); - glGetIntegerv(GL_SCISSOR_BOX, scissor); - glScissor(cliprct.xmin, cliprct.ymin, cliprct.xmax - cliprct.xmin, cliprct.ymax - cliprct.ymin); + if(cliprct.xmax > cliprct.xmin && cliprct.ymax > cliprct.ymin) { + glGetIntegerv(GL_SCISSOR_BOX, scissor); + glScissor(cliprct.xmin, cliprct.ymin, cliprct.xmax - cliprct.xmin, cliprct.ymax - cliprct.ymin); + } + else + return 0; } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); @@ -2795,11 +2851,6 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw else fdrawcheckerboard(0, 0, ar->winx, ar->winy); - if (draw_border) { - /* restore scissor as it was before */ - glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); - } - /* render result draw */ type = rv3d->render_engine->type; type->view_draw(rv3d->render_engine, C); @@ -2807,6 +2858,11 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw if (v3d->flag & V3D_DISPBGPICS) view3d_draw_bgpic(scene, ar, v3d, TRUE, TRUE); + if (draw_border) { + /* restore scissor as it was before */ + glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); + } + return 1; } |