bool view3d_get_view_aligned_coordinate(ARegion *ar, float fp[3], const int mval[2], const bool do_fallback) { RegionView3D *rv3d = ar->regiondata; float dvec[3]; int mval_cpy[2]; eV3DProjStatus ret; ret = ED_view3d_project_int_global(ar, fp, mval_cpy, V3D_PROJ_TEST_NOP); if (ret == V3D_PROJ_RET_OK) { const float mval_f[2] = {(float)(mval_cpy[0] - mval[0]), (float)(mval_cpy[1] - mval[1])}; const float zfac = ED_view3d_calc_zfac(rv3d, fp, NULL); ED_view3d_win_to_delta(ar, mval_f, dvec, zfac); sub_v3_v3(fp, dvec); return true; } else { /* fallback to the view center */ if (do_fallback) { negate_v3_v3(fp, rv3d->ofs); return view3d_get_view_aligned_coordinate(ar, fp, mval, false); } else { return false; } } }
/* Convert Grease Pencil points to screen-space values * WARNING: This assumes that the caller has already checked whether the stroke in question can be drawn */ void gp_point_to_xy(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt, int *r_x, int *r_y) { ARegion *ar = gsc->ar; View2D *v2d = gsc->v2d; rctf *subrect = gsc->subrect; int xyval[2]; /* sanity checks */ BLI_assert(!(gps->flag & GP_STROKE_3DSPACE) || (gsc->sa->spacetype == SPACE_VIEW3D)); BLI_assert(!(gps->flag & GP_STROKE_2DSPACE) || (gsc->sa->spacetype != SPACE_VIEW3D)); if (gps->flag & GP_STROKE_3DSPACE) { if (ED_view3d_project_int_global(ar, &pt->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { *r_x = xyval[0]; *r_y = xyval[1]; } else { *r_x = V2D_IS_CLIPPED; *r_y = V2D_IS_CLIPPED; } } else if (gps->flag & GP_STROKE_2DSPACE) { float vec[3] = {pt->x, pt->y, 0.0f}; mul_m4_v3(gsc->mat, vec); UI_view2d_view_to_region_clip(v2d, vec[0], vec[1], r_x, r_y); } else { if (subrect == NULL) { /* normal 3D view (or view space) */ *r_x = (int)(pt->x / 100 * ar->winx); *r_y = (int)(pt->y / 100 * ar->winy); } else { /* camera view, use subrect */ *r_x = (int)((pt->x / 100) * BLI_rctf_size_x(subrect)) + subrect->xmin; *r_y = (int)((pt->y / 100) * BLI_rctf_size_y(subrect)) + subrect->ymin; } } }
void DRW_draw_cursor(void) { const DRWContextState *draw_ctx = DRW_context_state_get(); ARegion *ar = draw_ctx->ar; Scene *scene = draw_ctx->scene; ViewLayer *view_layer = draw_ctx->view_layer; glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); if (is_cursor_visible(draw_ctx, scene, view_layer)) { int co[2]; /* Get cursor data into quaternion form */ const View3DCursor *cursor = &scene->cursor; if (ED_view3d_project_int_global( ar, cursor->location, co, V3D_PROJ_TEST_NOP | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) { RegionView3D *rv3d = ar->regiondata; float cursor_quat[4]; BKE_scene_cursor_rot_to_quat(cursor, cursor_quat); /* Draw nice Anti Aliased cursor. */ GPU_line_width(1.0f); GPU_blend(true); GPU_line_smooth(true); float eps = 1e-5f; rv3d->viewquat[0] = -rv3d->viewquat[0]; bool is_aligned = compare_v4v4(cursor_quat, rv3d->viewquat, eps); if (is_aligned == false) { float tquat[4]; rotation_between_quats_to_quat(tquat, rv3d->viewquat, cursor_quat); is_aligned = tquat[0] - eps < -1.0f; } rv3d->viewquat[0] = -rv3d->viewquat[0]; /* Draw lines */ if (is_aligned == false) { uint pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformThemeColor3(TH_VIEW_OVERLAY); immBegin(GPU_PRIM_LINES, 12); const float scale = ED_view3d_pixel_size_no_ui_scale(rv3d, cursor->location) * U.widget_unit; #define CURSOR_VERT(axis_vec, axis, fac) \ immVertex3f(pos, \ cursor->location[0] + axis_vec[0] * (fac), \ cursor->location[1] + axis_vec[1] * (fac), \ cursor->location[2] + axis_vec[2] * (fac)) #define CURSOR_EDGE(axis_vec, axis, sign) \ { \ CURSOR_VERT(axis_vec, axis, sign 1.0f); \ CURSOR_VERT(axis_vec, axis, sign 0.25f); \ } \ ((void)0) for (int axis = 0; axis < 3; axis++) { float axis_vec[3] = {0}; axis_vec[axis] = scale; mul_qt_v3(cursor_quat, axis_vec); CURSOR_EDGE(axis_vec, axis, +); CURSOR_EDGE(axis_vec, axis, -); } #undef CURSOR_VERT #undef CURSOR_EDGE immEnd(); immUnbindProgram(); } float original_proj[4][4]; GPU_matrix_projection_get(original_proj); GPU_matrix_push(); ED_region_pixelspace(ar); GPU_matrix_translate_2f(co[0] + 0.5f, co[1] + 0.5f); GPU_matrix_scale_2f(U.widget_unit, U.widget_unit); GPUBatch *cursor_batch = DRW_cache_cursor_get(is_aligned); GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR); GPU_batch_program_set( cursor_batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader)); GPU_batch_draw(cursor_batch); GPU_blend(false); GPU_line_smooth(false); GPU_matrix_pop(); GPU_matrix_projection_set(original_proj); }