static void calc_ray_shift(rcti *rect, float x, float y, const float source[2], float ray_length) { float co[2] = {(float)x, (float)y}; float dir[2], dist; /* move (x,y) vector toward the source by ray_length distance */ sub_v2_v2v2(dir, co, source); dist = normalize_v2(dir); mul_v2_fl(dir, min_ff(dist, ray_length)); sub_v2_v2(co, dir); int ico[2] = {(int)co[0], (int)co[1]}; BLI_rcti_do_minmax_v(rect, ico); }
/* Convert the object-space axis-aligned bounding box (expressed as * its minimum and maximum corners) into a screen-space rectangle, * returns zero if the result is empty */ bool paint_convert_bb_to_rect(rcti *rect, const float bb_min[3], const float bb_max[3], const ARegion *ar, RegionView3D *rv3d, Object *ob) { float projection_mat[4][4]; int i, j, k; BLI_rcti_init_minmax(rect); /* return zero if the bounding box has non-positive volume */ if (bb_min[0] > bb_max[0] || bb_min[1] > bb_max[1] || bb_min[2] > bb_max[2]) return 0; ED_view3d_ob_project_mat_get(rv3d, ob, projection_mat); for (i = 0; i < 2; ++i) { for (j = 0; j < 2; ++j) { for (k = 0; k < 2; ++k) { float vec[3], proj[2]; int proj_i[2]; vec[0] = i ? bb_min[0] : bb_max[0]; vec[1] = j ? bb_min[1] : bb_max[1]; vec[2] = k ? bb_min[2] : bb_max[2]; /* convert corner to screen space */ ED_view3d_project_float_v2_m4(ar, vec, proj, projection_mat); /* expand 2D rectangle */ /* we could project directly to int? */ proj_i[0] = proj[0]; proj_i[1] = proj[1]; BLI_rcti_do_minmax_v(rect, proj_i); } } } /* return false if the rectangle has non-positive area */ return rect->xmin < rect->xmax && rect->ymin < rect->ymax; }