replace ED_view3d_project_short_* with ED_view3d_project_int_*, when the result was converted to an int after.

also optimization for particle editmode key_test_depth() was projecting the screen coords, but all callers had already done this, so pass an arg.
This commit is contained in:
Campbell Barton 2012-10-05 05:11:10 +00:00
parent 2ba295bcd1
commit 6e65c7842b
2 changed files with 77 additions and 85 deletions

@ -398,44 +398,41 @@ static void PE_set_view3d_data(bContext *C, PEData *data)
/*************************** selection utilities *******************************/
/* TODO, many of the callers to this function already have a 2d projection that
* could be passed as an arg, save calling ED_view3d_project_short_global again. */
static int key_test_depth(PEData *data, const float co[3])
static int key_test_depth(PEData *data, const float co[3], int screen_co[2])
{
View3D *v3d= data->vc.v3d;
double ux, uy, uz;
float depth;
short wco[3], x, y;
/* nothing to do */
if ((v3d->drawtype<=OB_WIRE) || (v3d->flag & V3D_ZBUF_SELECT)==0)
return 1;
if (ED_view3d_project_short_global(data->vc.ar, co, wco,
V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS)
/* used to calculate here but all callers have the screen_co already, so pass as arg */
#if 0
if (ED_view3d_project_int_global(data->vc.ar, co, screen_co,
V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS)
{
return 0;
}
#endif
gluProject(co[0], co[1], co[2], data->mats.modelview, data->mats.projection,
(GLint *)data->mats.viewport, &ux, &uy, &uz);
x=wco[0];
y=wco[1];
#if 0 /* works well but too slow on some systems [#23118] */
x+= (short)data->vc.ar->winrct.xmin;
y+= (short)data->vc.ar->winrct.ymin;
screen_co[0] += (short)data->vc.ar->winrct.xmin;
screen_co[1] += (short)data->vc.ar->winrct.ymin;
/* PE_set_view3d_data calls this. no need to call here */
/* view3d_validate_backbuf(&data->vc); */
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
glReadPixels(screen_co[0], screen_co[1], 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
#else /* faster to use depths, these are calculated in PE_set_view3d_data */
{
ViewDepths *vd = data->vc.rv3d->depths;
assert(vd && vd->depths);
/* we know its not clipped */
depth= vd->depths[y * vd->w + x];
depth = vd->depths[screen_co[1] * vd->w + screen_co[0]];
}
#endif
@ -448,21 +445,21 @@ static int key_test_depth(PEData *data, const float co[3])
static int key_inside_circle(PEData *data, float rad, const float co[3], float *distance)
{
float dx, dy, dist;
int sco[2];
int screen_co[2];
/* TODO, should this check V3D_PROJ_TEST_CLIP_BB too? */
if (ED_view3d_project_int_global(data->vc.ar, co, sco, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) {
if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) {
return 0;
}
dx= data->mval[0] - sco[0];
dy= data->mval[1] - sco[1];
dx= data->mval[0] - screen_co[0];
dy= data->mval[1] - screen_co[1];
dist= sqrt(dx*dx + dy*dy);
if (dist > rad)
return 0;
if (key_test_depth(data, co)) {
if (key_test_depth(data, co, screen_co)) {
if (distance)
*distance=dist;
@ -474,16 +471,16 @@ static int key_inside_circle(PEData *data, float rad, const float co[3], float *
static int key_inside_rect(PEData *data, const float co[3])
{
int sco[2];
int screen_co[2];
if (ED_view3d_project_int_global(data->vc.ar, co, sco, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) {
if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) {
return 0;
}
if (sco[0] > data->rect->xmin && sco[0] < data->rect->xmax &&
sco[1] > data->rect->ymin && sco[1] < data->rect->ymax)
if (screen_co[0] > data->rect->xmin && screen_co[0] < data->rect->xmax &&
screen_co[1] > data->rect->ymin && screen_co[1] < data->rect->ymax)
{
return key_test_depth(data, co);
return key_test_depth(data, co, screen_co);
}
return 0;
@ -1647,7 +1644,7 @@ int PE_lasso_select(bContext *C, int mcords[][2], short moves, short extend, sho
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
POINT_P; KEY_K;
float co[3], mat[4][4]= MAT4_UNITY;
int vertco[2];
int screen_co[2];
PEData data;
@ -1668,9 +1665,9 @@ int PE_lasso_select(bContext *C, int mcords[][2], short moves, short extend, sho
LOOP_KEYS {
copy_v3_v3(co, key->co);
mul_m4_v3(mat, co);
if ((ED_view3d_project_int_global(ar, co, vertco, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) &&
BLI_lasso_is_point_inside(mcords, moves, vertco[0], vertco[1], IS_CLIPPED) &&
key_test_depth(&data, co))
if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) &&
BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) &&
key_test_depth(&data, co, screen_co))
{
if (select && !(key->flag & PEK_SELECT)) {
key->flag |= PEK_SELECT;
@ -1688,9 +1685,9 @@ int PE_lasso_select(bContext *C, int mcords[][2], short moves, short extend, sho
copy_v3_v3(co, key->co);
mul_m4_v3(mat, co);
if ((ED_view3d_project_int_global(ar, co, vertco, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) &&
BLI_lasso_is_point_inside(mcords, moves, vertco[0], vertco[1], IS_CLIPPED) &&
key_test_depth(&data, co))
if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) &&
BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) &&
key_test_depth(&data, co, screen_co))
{
if (select && !(key->flag & PEK_SELECT)) {
key->flag |= PEK_SELECT;
@ -2791,7 +2788,7 @@ static void brush_cut(PEData *data, int pa_index)
float rad2, cut_time= 1.0;
float x0, x1, v0, v1, o0, o1, xo0, xo1, d, dv;
int k, cut, keys= (int)pow(2.0, (double)pset->draw_step);
int vertco[2];
int screen_co[2];
/* blunt scissors */
if (BLI_frand() > data->cutfac) return;
@ -2800,15 +2797,15 @@ static void brush_cut(PEData *data, int pa_index)
if (edit->points[pa_index].flag & PEP_HIDE)
return;
if (ED_view3d_project_int_global(ar, key->co, vertco, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS)
if (ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS)
return;
rad2= data->rad * data->rad;
cut=0;
x0= (float)vertco[0];
x1= (float)vertco[1];
x0 = (float)screen_co[0];
x1 = (float)screen_co[1];
o0= (float)data->mval[0];
o1= (float)data->mval[1];
@ -2817,7 +2814,7 @@ static void brush_cut(PEData *data, int pa_index)
xo1= x1 - o1;
/* check if root is inside circle */
if (xo0*xo0 + xo1*xo1 < rad2 && key_test_depth(data, key->co)) {
if (xo0*xo0 + xo1*xo1 < rad2 && key_test_depth(data, key->co, screen_co)) {
cut_time= -1.0f;
cut= 1;
}
@ -2825,19 +2822,19 @@ static void brush_cut(PEData *data, int pa_index)
/* calculate path time closest to root that was inside the circle */
for (k=1, key++; k<=keys; k++, key++) {
if ((ED_view3d_project_int_global(ar, key->co, vertco, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) ||
key_test_depth(data, key->co) == 0)
if ((ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) ||
key_test_depth(data, key->co, screen_co) == 0)
{
x0= (float)vertco[0];
x1= (float)vertco[1];
x0 = (float)screen_co[0];
x1 = (float)screen_co[1];
xo0= x0 - o0;
xo1= x1 - o1;
continue;
}
v0= (float)vertco[0] - x0;
v1= (float)vertco[1] - x1;
v0 = (float)screen_co[0] - x0;
v1 = (float)screen_co[1] - x1;
dv= v0*v0 + v1*v1;
@ -2862,8 +2859,8 @@ static void brush_cut(PEData *data, int pa_index)
}
}
x0= (float)vertco[0];
x1= (float)vertco[1];
x0 = (float)screen_co[0];
x1 = (float)screen_co[1];
xo0= x0 - o0;
xo1= x1 - o1;

@ -1877,16 +1877,16 @@ 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];
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) {
if (ED_view3d_project_short_object(vc->ar, dl ? co : bp->vec, s,
V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
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, s[0], s[1]);
func(userData, bp, screen_co[0], screen_co[1]);
}
}
}
@ -1992,13 +1992,13 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const flo
const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_OFF) ?
V3D_PROJ_TEST_NOP :
V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN;
short s[2];
int screen_co[2];
if (ED_view3d_project_short_object(data->vc.ar, co, s, flag) != V3D_PROJ_RET_SUCCESS) {
if (ED_view3d_project_int_object(data->vc.ar, co, screen_co, flag) != V3D_PROJ_RET_SUCCESS) {
return;
}
data->func(data->userData, eve, s[0], s[1], index);
data->func(data->userData, eve, screen_co[0], screen_co[1], index);
}
}
@ -2059,16 +2059,17 @@ 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_short_object(data->vc.ar, v0co, s[0], flag) != V3D_PROJ_RET_SUCCESS) {
if (ED_view3d_project_int_object(data->vc.ar, v0co, screen_co_a, flag) != V3D_PROJ_RET_SUCCESS) {
return;
}
if (ED_view3d_project_short_object(data->vc.ar, v1co, s[1], flag) != V3D_PROJ_RET_SUCCESS) {
if (ED_view3d_project_int_object(data->vc.ar, v1co, screen_co_b, flag) != V3D_PROJ_RET_SUCCESS) {
return;
}
@ -2077,16 +2078,15 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const flo
}
else {
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);
}
}
@ -2125,16 +2125,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];
/* TODO, use ED_view3d_project_short_object */
mul_v3_m4v3(cent2, data->vc.obedit->obmat, cent);
if (ED_view3d_project_short_global(data->vc.ar, cent2, s,
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, s[0], s[1], index);
data->func(data->userData, efa, screen_co[0], screen_co[1], index);
}
}
}
@ -2151,8 +2146,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);
@ -2167,7 +2161,6 @@ void nurbs_foreachScreenVert(
void *userData)
{
Curve *cu = vc->obedit->data;
short s[2];
Nurb *nu;
int i;
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
@ -2180,29 +2173,30 @@ 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_short_object(vc->ar, bezt->vec[1], s,
V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
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, s[0], s[1]);
func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]);
}
}
else {
if (ED_view3d_project_short_object(vc->ar, bezt->vec[0], s,
V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
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, s[0], s[1]);
func(userData, nu, NULL, bezt, 0, screen_co[0], screen_co[1]);
}
if (ED_view3d_project_short_object(vc->ar, bezt->vec[1], s,
V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
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, s[0], s[1]);
func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]);
}
if (ED_view3d_project_short_object(vc->ar, bezt->vec[2], s,
V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
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, s[0], s[1]);
func(userData, nu, NULL, bezt, 2, screen_co[0], screen_co[1]);
}
}
}
@ -2213,10 +2207,11 @@ void nurbs_foreachScreenVert(
BPoint *bp = &nu->bp[i];
if (bp->hide == 0) {
if (ED_view3d_project_short_object(vc->ar, bp->vec, s,
V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
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, s[0], s[1]);
func(userData, nu, bp, NULL, -1, screen_co[0], screen_co[1]);
}
}
}