diff options
Diffstat (limited to 'source/blender/editors/space_view3d/drawobject.c')
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 357 |
1 files changed, 170 insertions, 187 deletions
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 1b008c27fc0..9d25c3e5f52 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -101,7 +101,6 @@ #include "ED_sculpt.h" #include "ED_types.h" #include "ED_curve.h" /* for curve_editnurbs */ -#include "ED_armature.h" #include "UI_resources.h" @@ -240,6 +239,107 @@ static int check_ob_drawface_dot(Scene *sce, View3D *vd, char dt) return 1; } +/* ************* only use while object drawing ************** + * or after running ED_view3d_init_mats_rv3d + * */ +static void view3d_project_short_clip(ARegion *ar, const float vec[3], short adr[2], int is_local) +{ + RegionView3D *rv3d = ar->regiondata; + float fx, fy, vec4[4]; + + adr[0] = IS_CLIPPED; + + /* clipplanes in eye space */ + if (rv3d->rflag & RV3D_CLIPPING) { + if (ED_view3d_clipping_test(rv3d, vec, is_local)) + return; + } + + copy_v3_v3(vec4, vec); + vec4[3] = 1.0; + + mul_m4_v4(rv3d->persmatob, vec4); + + /* clipplanes in window space */ + if (vec4[3] > (float)BL_NEAR_CLIP) { /* is the NEAR clipping cutoff for picking */ + fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); + + if (fx > 0 && fx < ar->winx) { + + fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); + + if (fy > 0.0f && fy < (float)ar->winy) { + adr[0] = (short)floorf(fx); + adr[1] = (short)floorf(fy); + } + } + } +} + +/* BMESH NOTE: this function is unused in bmesh only */ + +/* only use while object drawing */ +static void UNUSED_FUNCTION(view3d_project_short_noclip) (ARegion * ar, const float vec[3], short adr[2]) +{ + RegionView3D *rv3d = ar->regiondata; + float fx, fy, vec4[4]; + + adr[0] = IS_CLIPPED; + + copy_v3_v3(vec4, vec); + vec4[3] = 1.0; + + mul_m4_v4(rv3d->persmatob, vec4); + + if (vec4[3] > (float)BL_NEAR_CLIP) { /* is the NEAR clipping cutoff for picking */ + fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); + + if (fx > -32700 && fx < 32700) { + + fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); + + if (fy > -32700.0f && fy < 32700.0f) { + adr[0] = (short)floorf(fx); + adr[1] = (short)floorf(fy); + } + } + } +} + +/* same as view3d_project_short_clip but use persmat instead of persmatob for projection */ +static void view3d_project_short_clip_persmat(ARegion *ar, const float vec[3], short adr[2], int is_local) +{ + RegionView3D *rv3d = ar->regiondata; + float fx, fy, vec4[4]; + + adr[0] = IS_CLIPPED; + + /* clipplanes in eye space */ + if (rv3d->rflag & RV3D_CLIPPING) { + if (ED_view3d_clipping_test(rv3d, vec, is_local)) + return; + } + + copy_v3_v3(vec4, vec); + vec4[3] = 1.0; + + mul_m4_v4(rv3d->persmat, vec4); + + /* clipplanes in window space */ + if (vec4[3] > (float)BL_NEAR_CLIP) { /* is the NEAR clipping cutoff for picking */ + fx = (ar->winx / 2) * (1 + vec4[0] / vec4[3]); + + if (fx > 0 && fx < ar->winx) { + + fy = (ar->winy / 2) * (1 + vec4[1] / vec4[3]); + + if (fy > 0.0f && fy < (float)ar->winy) { + adr[0] = (short)floorf(fx); + adr[1] = (short)floorf(fy); + } + } + } +} /* ************************ */ /* check for glsl drawing */ @@ -783,17 +883,13 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa if (mat && !(vos->flag & V3D_CACHE_TEXT_WORLDSPACE)) mul_m4_v3(mat, vos->vec); - if (ED_view3d_project_short_ex(ar, - (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob, - (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0, - vos->vec, vos->sco, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { + if (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) + view3d_project_short_clip_persmat(ar, vos->vec, vos->sco, (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0); + else + view3d_project_short_clip(ar, vos->vec, vos->sco, (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0); + + if (vos->sco[0] != IS_CLIPPED) tot++; - } - else { - vos->sco[0] = IS_CLIPPED; - } } if (tot) { @@ -1878,17 +1974,15 @@ void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPo DispList *dl = BKE_displist_find(&obedit->disp, DL_VERTS); float *co = dl ? dl->verts : NULL; int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; + short s[2] = {IS_CLIPPED, 0}; ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */ for (i = 0; i < N; i++, bp++, co += 3) { if (bp->hide == 0) { - int screen_co[2]; - if (ED_view3d_project_int_object(vc->ar, dl ? co : bp->vec, screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, bp, screen_co[0], screen_co[1]); - } + view3d_project_short_clip(vc->ar, dl ? co : bp->vec, s, TRUE); + if (s[0] != IS_CLIPPED) + func(userData, bp, s[0], s[1]); } } } @@ -1990,16 +2084,19 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const flo BMVert *eve = EDBM_vert_at_index(data->vc.em, index); if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_OFF) ? - V3D_PROJ_TEST_NOP : - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN; - int screen_co[2]; + short s[2] = {IS_CLIPPED, 0}; - if (ED_view3d_project_int_object(data->vc.ar, co, screen_co, flag) != V3D_PROJ_RET_OK) { - return; + if (data->clipVerts != V3D_CLIP_TEST_OFF) { + view3d_project_short_clip(data->vc.ar, co, s, TRUE); + } + else { + float co2[2]; + mul_v3_m4v3(co2, data->vc.obedit->obmat, co); + ED_view3d_project_short_noclip(data->vc.ar, co2, s); } - data->func(data->userData, eve, screen_co[0], screen_co[1], index); + if (s[0] != IS_CLIPPED) + data->func(data->userData, eve, s[0], s[1], index); } } @@ -2060,34 +2157,38 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const flo BMEdge *eed = EDBM_edge_at_index(data->vc.em, index); if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - int screen_co_a[2]; - int screen_co_b[2]; - - const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) ? - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN : - V3D_PROJ_TEST_NOP; - - if (ED_view3d_project_int_object(data->vc.ar, v0co, screen_co_a, flag) != V3D_PROJ_RET_OK) { - return; - } - if (ED_view3d_project_int_object(data->vc.ar, v1co, screen_co_b, flag) != V3D_PROJ_RET_OK) { - return; - } + short s[2][2]; if (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) { - /* pass */ + view3d_project_short_clip(data->vc.ar, v0co, s[0], TRUE); + view3d_project_short_clip(data->vc.ar, v1co, s[1], TRUE); + + if (s[0][0] == IS_CLIPPED || s[1][0] == IS_CLIPPED) { + return; + } } else { + float v1_co[3], v2_co[3]; + + mul_v3_m4v3(v1_co, data->vc.obedit->obmat, v0co); + mul_v3_m4v3(v2_co, data->vc.obedit->obmat, v1co); + + /* XXX, todo, use ED_view3d_project_int_noclip(...), however these functions work differently + * and need to be cleaned up, Campbell */ + ED_view3d_project_short_noclip(data->vc.ar, v1_co, s[0]); + ED_view3d_project_short_noclip(data->vc.ar, v2_co, s[1]); + if (data->clipVerts == V3D_CLIP_TEST_REGION) { - if (!BLI_rcti_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) { + /* make an int copy */ + int s_int[2][2] = {{s[0][0], s[0][1]}, + {s[1][0], s[1][1]}}; + if (!BLI_rcti_isect_segment(&data->win_rect, s_int[0], s_int[1])) { return; } } } - data->func(data->userData, eed, - screen_co_a[0], screen_co_a[1], - screen_co_b[0], screen_co_b[1], index); + data->func(data->userData, eed, s[0][0], s[0][1], s[1][0], s[1][1], index); } } @@ -2126,11 +2227,14 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const flo BMFace *efa = EDBM_face_at_index(data->vc.em, index); if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - int screen_co[2]; - if (ED_view3d_project_int_object(data->vc.ar, cent, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - data->func(data->userData, efa, screen_co[0], screen_co[1], index); + float cent2[3]; + short s[2]; + + mul_v3_m4v3(cent2, data->vc.obedit->obmat, cent); + ED_view3d_project_short(data->vc.ar, cent2, s); + + if (s[0] != IS_CLIPPED) { + data->func(data->userData, efa, s[0], s[1], index); } } } @@ -2147,7 +2251,8 @@ void mesh_foreachScreenFace( data.func = func; data.userData = userData; - ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); + //if (clipVerts) + ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ EDBM_index_arrays_init(vc->em, 0, 0, 1); dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); @@ -2162,6 +2267,7 @@ void nurbs_foreachScreenVert( void *userData) { Curve *cu = vc->obedit->data; + short s[2] = {IS_CLIPPED, 0}; Nurb *nu; int i; ListBase *nurbs = BKE_curve_editNurbs_get(cu); @@ -2174,31 +2280,22 @@ void nurbs_foreachScreenVert( BezTriple *bezt = &nu->bezt[i]; if (bezt->hide == 0) { - int screen_co[2]; if (cu->drawflag & CU_HIDE_HANDLES) { - if (ED_view3d_project_int_object(vc->ar, bezt->vec[1], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]); - } + view3d_project_short_clip(vc->ar, bezt->vec[1], s, TRUE); + if (s[0] != IS_CLIPPED) + func(userData, nu, NULL, bezt, 1, s[0], s[1]); } else { - if (ED_view3d_project_int_object(vc->ar, bezt->vec[0], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, nu, NULL, bezt, 0, screen_co[0], screen_co[1]); - } - if (ED_view3d_project_int_object(vc->ar, bezt->vec[1], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]); - } - if (ED_view3d_project_int_object(vc->ar, bezt->vec[2], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, nu, NULL, bezt, 2, screen_co[0], screen_co[1]); - } + view3d_project_short_clip(vc->ar, bezt->vec[0], s, TRUE); + if (s[0] != IS_CLIPPED) + func(userData, nu, NULL, bezt, 0, s[0], s[1]); + view3d_project_short_clip(vc->ar, bezt->vec[1], s, TRUE); + if (s[0] != IS_CLIPPED) + func(userData, nu, NULL, bezt, 1, s[0], s[1]); + view3d_project_short_clip(vc->ar, bezt->vec[2], s, TRUE); + if (s[0] != IS_CLIPPED) + func(userData, nu, NULL, bezt, 2, s[0], s[1]); } } } @@ -2208,129 +2305,15 @@ void nurbs_foreachScreenVert( BPoint *bp = &nu->bp[i]; if (bp->hide == 0) { - int screen_co[2]; - if (ED_view3d_project_int_object(vc->ar, bp->vec, screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, nu, bp, NULL, -1, screen_co[0], screen_co[1]); - } + view3d_project_short_clip(vc->ar, bp->vec, s, TRUE); + if (s[0] != IS_CLIPPED) + func(userData, nu, bp, NULL, -1, s[0], s[1]); } } } } } -/* ED_view3d_init_mats_rv3d must be called first */ -void mball_foreachScreenElem( - struct ViewContext *vc, - void (*func)(void *userData, struct MetaElem *ml, int x, int y), - void *userData) -{ - MetaBall *mb = (MetaBall *)vc->obedit->data; - MetaElem *ml; - - for (ml = mb->editelems->first; ml; ml = ml->next) { - int screen_co[2]; - if (ED_view3d_project_int_object(vc->ar, &ml->x, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, ml, screen_co[0], screen_co[1]); - } - } -} - -/* ED_view3d_init_mats_rv3d must be called first */ -void armature_foreachScreenBone( - struct ViewContext *vc, - void (*func)(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1), - void *userData) -{ - bArmature *arm = vc->obedit->data; - EditBone *ebone; - - for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone)) { - int screen_co_a[2], screen_co_b[2]; - int points_proj_tot = 0; - - /* project head location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, ebone->head, screen_co_a, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - points_proj_tot++; - } - else { - screen_co_a[0] = IS_CLIPPED; /* weak */ - /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ - } - - /* project tail location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, ebone->tail, screen_co_b, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - points_proj_tot++; - } - else { - screen_co_b[0] = IS_CLIPPED; /* weak */ - /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ - } - - if (points_proj_tot) { /* at least one point's projection worked */ - func(userData, ebone, - screen_co_a[0], screen_co_a[1], - screen_co_b[0], screen_co_b[1]); - } - } - } -} - -/* ED_view3d_init_mats_rv3d must be called first */ -/* almost _exact_ copy of #armature_foreachScreenBone */ -void pose_foreachScreenBone( - struct ViewContext *vc, - void (*func)(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1), - void *userData) -{ - bArmature *arm = vc->obact->data; - bPose *pose = vc->obact->pose; - bPoseChannel *pchan; - - for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { - if (PBONE_VISIBLE(arm, pchan->bone)) { - int screen_co_a[2], screen_co_b[2]; - int points_proj_tot = 0; - - /* project head location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, pchan->pose_head, screen_co_a, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - points_proj_tot++; - } - else { - screen_co_a[0] = IS_CLIPPED; /* weak */ - /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ - } - - /* project tail location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, pchan->pose_tail, screen_co_b, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - points_proj_tot++; - } - else { - screen_co_b[0] = IS_CLIPPED; /* weak */ - /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ - } - - if (points_proj_tot) { /* at least one point's projection worked */ - func(userData, pchan, - screen_co_a[0], screen_co_a[1], - screen_co_b[0], screen_co_b[1]); - } - } - } -} - /* ************** DRAW MESH ****************** */ /* First section is all the "simple" draw routines, @@ -6639,7 +6622,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short /* which wire color */ if ((dflag & DRAW_CONSTCOLOR) == 0) { - ED_view3d_project_base(ar, base); + ED_view3d_project_short(ar, ob->obmat[3], &base->sx); draw_object_wire_color(scene, base, _ob_wire_col, warning_recursive); ob_wire_col = _ob_wire_col; |