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.c357
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;