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:
Diffstat (limited to 'source/blender/editors/space_view3d/drawobject.c')
-rw-r--r--source/blender/editors/space_view3d/drawobject.c336
1 files changed, 170 insertions, 166 deletions
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index fe4e393b45d..9e628f2f0ff 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -101,6 +101,7 @@
#include "ED_sculpt.h"
#include "ED_types.h"
#include "ED_curve.h" /* for curve_editnurbs */
+#include "ED_armature.h"
#include "UI_resources.h"
@@ -239,107 +240,6 @@ 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 */
@@ -883,13 +783,17 @@ 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 (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)
+ 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_SUCCESS)
+ {
tot++;
+ }
+ else {
+ vos->sco[0] = IS_CLIPPED;
+ }
}
if (tot) {
@@ -1974,15 +1878,17 @@ 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) {
- view3d_project_short_clip(vc->ar, dl ? co : bp->vec, s, TRUE);
- if (s[0] != IS_CLIPPED)
- func(userData, bp, s[0], s[1]);
+ 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_SUCCESS)
+ {
+ func(userData, bp, screen_co[0], screen_co[1]);
+ }
}
}
}
@@ -2084,19 +1990,16 @@ 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)) {
- short s[2] = {IS_CLIPPED, 0};
+ 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];
- 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);
+ if (ED_view3d_project_int_object(data->vc.ar, co, screen_co, flag) != V3D_PROJ_RET_SUCCESS) {
+ return;
}
- if (s[0] != IS_CLIPPED)
- data->func(data->userData, eve, s[0], s[1], index);
+ data->func(data->userData, eve, screen_co[0], screen_co[1], index);
}
}
@@ -2157,32 +2060,34 @@ 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)) {
- short s[2][2];
+ 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_SUCCESS) {
+ return;
+ }
+ if (ED_view3d_project_int_object(data->vc.ar, v1co, screen_co_b, flag) != V3D_PROJ_RET_SUCCESS) {
+ return;
+ }
if (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) {
- view3d_project_short_clip(data->vc.ar, v0co, s[0], TRUE);
- view3d_project_short_clip(data->vc.ar, v1co, s[1], TRUE);
+ /* pass */
}
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);
-
- 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) {
- /* 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])) {
+ if (!BLI_rcti_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) {
return;
}
}
}
- data->func(data->userData, eed, s[0][0], s[0][1], s[1][0], s[1][1], index);
+ data->func(data->userData, eed,
+ screen_co_a[0], screen_co_a[1],
+ screen_co_b[0], screen_co_b[1], index);
}
}
@@ -2221,14 +2126,11 @@ 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)) {
- 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);
+ 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_SUCCESS)
+ {
+ data->func(data->userData, efa, screen_co[0], screen_co[1], index);
}
}
}
@@ -2245,8 +2147,7 @@ void mesh_foreachScreenFace(
data.func = func;
data.userData = userData;
- //if (clipVerts)
- ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
EDBM_index_arrays_init(vc->em, 0, 0, 1);
dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data);
@@ -2261,7 +2162,6 @@ 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);
@@ -2274,22 +2174,31 @@ void nurbs_foreachScreenVert(
BezTriple *bezt = &nu->bezt[i];
if (bezt->hide == 0) {
+ int screen_co[2];
if (cu->drawflag & CU_HIDE_HANDLES) {
- 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]);
+ 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_SUCCESS)
+ {
+ func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]);
+ }
}
else {
- 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]);
+ 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_SUCCESS)
+ {
+ 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_SUCCESS)
+ {
+ 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_SUCCESS)
+ {
+ func(userData, nu, NULL, bezt, 2, screen_co[0], screen_co[1]);
+ }
}
}
}
@@ -2299,15 +2208,110 @@ void nurbs_foreachScreenVert(
BPoint *bp = &nu->bp[i];
if (bp->hide == 0) {
- 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]);
+ 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_SUCCESS)
+ {
+ func(userData, nu, bp, NULL, -1, 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_SUCCESS)
+ {
+ 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_SUCCESS)
+ {
+ 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_SUCCESS)
+ {
+ 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_SUCCESS)
+ {
+ 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,
@@ -3672,7 +3676,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
}
}
- if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) {
+ if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
/* GPU_begin_object_materials checked if this is needed */
if (do_alpha_after) {
if (ob->dtx & OB_DRAWXRAY) {
@@ -6581,7 +6585,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
return;
/* xray delay? */
- if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) {
+ if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
/* don't do xray in particle mode, need the z-buffer */
if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) {
/* xray and transp are set when it is drawing the 2nd/3rd pass */
@@ -6616,7 +6620,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_short(ar, ob->obmat[3], &base->sx);
+ ED_view3d_project_base(ar, base);
draw_object_wire_color(scene, base, _ob_wire_col, warning_recursive);
ob_wire_col = _ob_wire_col;