From f71cf996165a81030a92e3e26610bf2e6fa2fc44 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 1 Jun 2021 12:49:20 +1000 Subject: GPU: add 2D projection function When projecting into screen space Z value isn't always needed. Add 2D projection functions, renaming them to avoid accidents happening again. - Add GPU_matrix_project_2fv - Add ED_view3d_project_v2 - Rename ED_view3d_project to ED_view3d_project_v3 - Use the 2D versions of these functions when the Z value isn't used. --- source/blender/editors/curve/editcurve_paint.c | 2 +- source/blender/editors/include/ED_view3d.h | 17 +++++--- source/blender/editors/mesh/editmesh_knife.c | 6 +-- source/blender/editors/object/object_remesh.c | 4 +- source/blender/editors/object/object_transform.c | 4 +- source/blender/editors/physics/particle_edit.c | 2 +- source/blender/editors/sculpt_paint/paint_cursor.c | 2 +- source/blender/editors/sculpt_paint/paint_stroke.c | 8 ++-- source/blender/editors/space_view3d/view3d_edit.c | 7 ++-- .../space_view3d/view3d_gizmo_preselect_type.c | 4 +- .../blender/editors/space_view3d/view3d_project.c | 15 +++++-- source/blender/editors/space_view3d/view3d_utils.c | 20 ++++----- source/blender/gpu/GPU_matrix.h | 36 ++++++++++------- source/blender/gpu/intern/gpu_matrix.cc | 47 +++++++++++++++------- .../windowmanager/gizmo/intern/wm_gizmo_map.c | 4 +- 15 files changed, 108 insertions(+), 70 deletions(-) diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index 8842274e017..e4f2de1f741 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -210,7 +210,7 @@ static bool stroke_elem_project(const struct CurveDrawData *cdd, ED_view3d_depth_read_cached(depths, mval_i, 0, &depth_fl); const double depth = (double)depth_fl; if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) { - if (ED_view3d_depth_unproject(region, mval_i, depth, r_location_world)) { + if (ED_view3d_depth_unproject_v3(region, mval_i, depth, r_location_world)) { is_location_world_set = true; if (r_normal_world) { zero_v3(r_normal_world); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 66ec57c8a31..52d69d12253 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -162,10 +162,10 @@ bool ED_view3d_depth_read_cached(const ViewDepths *vd, bool ED_view3d_depth_read_cached_normal(const ViewContext *vc, const int mval[2], float r_normal[3]); -bool ED_view3d_depth_unproject(const struct ARegion *region, - const int mval[2], - const double depth, - float r_location_world[3]); +bool ED_view3d_depth_unproject_v3(const struct ARegion *region, + const int mval[2], + const double depth, + float r_location_world[3]); void ED_view3d_depth_tag_update(struct RegionView3D *rv3d); /* Projection */ @@ -410,8 +410,13 @@ void ED_view3d_ob_project_mat_get_from_obmat(const struct RegionView3D *rv3d, const float obmat[4][4], float r_pmat[4][4]); -void ED_view3d_project(const struct ARegion *region, const float world[3], float r_region_co[3]); -bool ED_view3d_unproject( +void ED_view3d_project_v3(const struct ARegion *region, + const float world[3], + float r_region_co[3]); +void ED_view3d_project_v2(const struct ARegion *region, + const float world[3], + float r_region_co[2]); +bool ED_view3d_unproject_v3( const struct ARegion *region, float regionx, float regiony, float regionz, float world[3]); /* end */ diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index b5cd9c7f60d..825b7d11aef 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -578,8 +578,8 @@ static void knife_input_ray_segment(KnifeTool_OpData *kcd, float r_origin_ofs[3]) { /* unproject to find view ray */ - ED_view3d_unproject(kcd->vc.region, mval[0], mval[1], 0.0f, r_origin); - ED_view3d_unproject(kcd->vc.region, mval[0], mval[1], ofs, r_origin_ofs); + ED_view3d_unproject_v3(kcd->vc.region, mval[0], mval[1], 0.0f, r_origin); + ED_view3d_unproject_v3(kcd->vc.region, mval[0], mval[1], ofs, r_origin_ofs); /* transform into object space */ mul_m4_v3(kcd->ob_imat, r_origin); @@ -1745,7 +1745,7 @@ static bool point_is_visible(KnifeTool_OpData *kcd, float view[3], p_ofs[3]; /* TODO: I think there's a simpler way to get the required raycast ray */ - ED_view3d_unproject(kcd->vc.region, s[0], s[1], 0.0f, view); + ED_view3d_unproject_v3(kcd->vc.region, s[0], s[1], 0.0f, view); mul_m4_v3(kcd->ob_imat, view); diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c index 9ef2cce875f..1ff576504ce 100644 --- a/source/blender/editors/object/object_remesh.c +++ b/source/blender/editors/object/object_remesh.c @@ -525,7 +525,7 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev float d_a[3], d_b[3]; float d_a_proj[2], d_b_proj[2]; - float preview_plane_proj[4][3]; + float preview_plane_proj[4][2]; const float y_axis_proj[2] = {0.0f, 1.0f}; mid_v3_v3v3(text_pos, cd->preview_plane[0], cd->preview_plane[2]); @@ -534,7 +534,7 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev for (int i = 0; i < 4; i++) { float preview_plane_world_space[3]; mul_v3_m4v3(preview_plane_world_space, active_object->obmat, cd->preview_plane[i]); - ED_view3d_project(region, preview_plane_world_space, preview_plane_proj[i]); + ED_view3d_project_v2(region, preview_plane_world_space, preview_plane_proj[i]); } /* Get the initial X and Y axis of the basis from the edges of the Bounding Box face. */ diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index a87b5054efa..b9a3bc87e19 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -1654,7 +1654,7 @@ static void object_transform_axis_target_calc_depth_init(struct XFormAxisData *x if (center_tot) { mul_v3_fl(center, 1.0f / center_tot); float center_proj[3]; - ED_view3d_project(xfd->vc.region, center, center_proj); + ED_view3d_project_v3(xfd->vc.region, center, center_proj); xfd->prev.depth = center_proj[2]; xfd->prev.is_depth_valid = true; } @@ -1890,7 +1890,7 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) { xfd->prev.depth = depth_fl; xfd->prev.is_depth_valid = true; - if (ED_view3d_depth_unproject(region, event->mval, depth, location_world)) { + if (ED_view3d_depth_unproject_v3(region, event->mval, depth, location_world)) { if (is_translate) { float normal[3]; diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 5b545784e5b..97994b65f40 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -609,7 +609,7 @@ static bool key_test_depth(const PEData *data, const float co[3], const int scre } float win[3]; - ED_view3d_project(data->vc.region, co, win); + ED_view3d_project_v3(data->vc.region, co, win); if (win[2] - 0.00001f > depth) { return 0; diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 3829aeebbeb..7e111905883 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -1039,7 +1039,7 @@ static void cursor_draw_point_screen_space(const uint gpuattr, float translation_vertex_cursor[3], location[3]; copy_v3_v3(location, true_location); mul_m4_v3(obmat, location); - ED_view3d_project(region, location, translation_vertex_cursor); + ED_view3d_project_v3(region, location, translation_vertex_cursor); /* Do not draw points behind the view. Z [near, far] is mapped to [-1, 1]. */ if (translation_vertex_cursor[2] <= 1.0f) { imm_draw_circle_fill_3d( diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 3f1fed5e5ea..59a5ad63f0e 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -846,7 +846,7 @@ static int paint_space_stroke(bContext *C, while (length > 0.0f) { float spacing = paint_space_stroke_spacing_variable( C, scene, stroke, pressure, dpressure, length); - float mouse[3]; + float mouse[2]; if (length >= spacing) { if (use_scene_spacing) { @@ -856,7 +856,7 @@ static int paint_space_stroke(bContext *C, add_v3_v3v3(final_world_space_position, stroke->last_world_space_position, final_world_space_position); - ED_view3d_project(region, final_world_space_position, mouse); + ED_view3d_project_v2(region, final_world_space_position, mouse); } else { mouse[0] = stroke->last_mouse_position[0] + dmouse[0] * spacing; @@ -1191,7 +1191,7 @@ static void paint_line_strokes_spacing(bContext *C, const bool use_scene_spacing = paint_stroke_use_scene_spacing(brush, mode); - float mouse[3], dmouse[2]; + float mouse[2], dmouse[2]; float length; float d_world_space_position[3] = {0.0f}; float world_space_position_old[3], world_space_position_new[3]; @@ -1240,7 +1240,7 @@ static void paint_line_strokes_spacing(bContext *C, mul_v3_v3fl(final_world_space_position, d_world_space_position, spacing_final); add_v3_v3v3( final_world_space_position, world_space_position_old, final_world_space_position); - ED_view3d_project(region, final_world_space_position, mouse); + ED_view3d_project_v2(region, final_world_space_position, mouse); } else { mouse[0] = stroke->last_mouse_position[0] + dmouse[0] * spacing_final; diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 967ad966320..8b6d0e9ee04 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -3666,8 +3666,8 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } /* convert border to 3d coordinates */ - if ((!ED_view3d_unproject(region, cent[0], cent[1], depth_close, p)) || - (!ED_view3d_unproject(region, rect.xmin, rect.ymin, depth_close, p_corner))) { + if ((!ED_view3d_unproject_v3(region, cent[0], cent[1], depth_close, p)) || + (!ED_view3d_unproject_v3(region, rect.xmin, rect.ymin, depth_close, p_corner))) { return OPERATOR_CANCELLED; } @@ -3690,7 +3690,8 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) new_dist = rv3d->dist; /* convert the drawn rectangle into 3d space */ - if (depth_close != FLT_MAX && ED_view3d_unproject(region, cent[0], cent[1], depth_close, p)) { + if (depth_close != FLT_MAX && + ED_view3d_unproject_v3(region, cent[0], cent[1], depth_close, p)) { negate_v3_v3(new_ofs, p); } else { diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c index 298a2a7a824..07c3b6bd1d8 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c @@ -154,10 +154,10 @@ static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int * Only pre-select a vertex when the cursor is really close to it. */ if (eve_test) { BMVert *vert = (BMVert *)eve_test; - float vert_p_co[3], vert_co[3]; + float vert_p_co[2], vert_co[3]; const float mval_f[2] = {UNPACK2(vc.mval)}; mul_v3_m4v3(vert_co, gz_ele->bases[base_index_vert]->object->obmat, vert->co); - ED_view3d_project(vc.region, vert_co, vert_p_co); + ED_view3d_project_v2(vc.region, vert_co, vert_p_co); float len = len_v2v2(vert_p_co, mval_f); if (len < 35) { best.ele = (BMElem *)eve_test; diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c index 24d34e514c5..7547f8ee434 100644 --- a/source/blender/editors/space_view3d/view3d_project.c +++ b/source/blender/editors/space_view3d/view3d_project.c @@ -809,23 +809,30 @@ void ED_view3d_ob_project_mat_get_from_obmat(const RegionView3D *rv3d, /** * Convert between region relative coordinates (x,y) and depth component z and * a point in world space. */ -void ED_view3d_project(const struct ARegion *region, const float world[3], float r_region_co[3]) +void ED_view3d_project_v3(const struct ARegion *region, const float world[3], float r_region_co[3]) { /* Viewport is set up to make coordinates relative to the region, not window. */ RegionView3D *rv3d = region->regiondata; const int viewport[4] = {0, 0, region->winx, region->winy}; + GPU_matrix_project_3fv(world, rv3d->viewmat, rv3d->winmat, viewport, r_region_co); +} - GPU_matrix_project(world, rv3d->viewmat, rv3d->winmat, viewport, r_region_co); +void ED_view3d_project_v2(const struct ARegion *region, const float world[3], float r_region_co[2]) +{ + /* Viewport is set up to make coordinates relative to the region, not window. */ + RegionView3D *rv3d = region->regiondata; + const int viewport[4] = {0, 0, region->winx, region->winy}; + GPU_matrix_project_2fv(world, rv3d->viewmat, rv3d->winmat, viewport, r_region_co); } -bool ED_view3d_unproject( +bool ED_view3d_unproject_v3( const struct ARegion *region, float regionx, float regiony, float regionz, float world[3]) { RegionView3D *rv3d = region->regiondata; const int viewport[4] = {0, 0, region->winx, region->winy}; const float region_co[3] = {regionx, regiony, regionz}; - return GPU_matrix_unproject(region_co, rv3d->viewmat, rv3d->winmat, viewport, world); + return GPU_matrix_unproject_3fv(region_co, rv3d->viewmat, rv3d->winmat, viewport, world); } /** \} */ diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c index f96c17d7cff..8ae5d4a29e9 100644 --- a/source/blender/editors/space_view3d/view3d_utils.c +++ b/source/blender/editors/space_view3d/view3d_utils.c @@ -299,8 +299,8 @@ void ED_view3d_clipping_calc( float xs = (ELEM(val, 0, 3)) ? rect->xmin : rect->xmax; float ys = (ELEM(val, 0, 1)) ? rect->ymin : rect->ymax; - ED_view3d_unproject(region, xs, ys, 0.0, bb->vec[val]); - ED_view3d_unproject(region, xs, ys, 1.0, bb->vec[4 + val]); + ED_view3d_unproject_v3(region, xs, ys, 0.0, bb->vec[val]); + ED_view3d_unproject_v3(region, xs, ys, 1.0, bb->vec[4 + val]); } /* optionally transform to object space */ @@ -1057,7 +1057,7 @@ bool ED_view3d_autodist(Depsgraph *depsgraph, float centx = (float)mval[0] + 0.5f; float centy = (float)mval[1] + 0.5f; - if (ED_view3d_unproject(region, centx, centy, depth_close, mouse_worldloc)) { + if (ED_view3d_unproject_v3(region, centx, centy, depth_close, mouse_worldloc)) { return true; } } @@ -1091,7 +1091,7 @@ bool ED_view3d_autodist_simple(ARegion *region, float centx = (float)mval[0] + 0.5f; float centy = (float)mval[1] + 0.5f; - return ED_view3d_unproject(region, centx, centy, depth, mouse_worldloc); + return ED_view3d_unproject_v3(region, centx, centy, depth, mouse_worldloc); } bool ED_view3d_autodist_depth(ARegion *region, const int mval[2], int margin, float *depth) @@ -1716,7 +1716,7 @@ bool ED_view3d_depth_read_cached_normal(const ViewContext *vc, ED_view3d_depth_read_cached(depths, mval_ofs, 0, &depth_fl); const double depth = (double)depth_fl; if ((depth > depths->depth_range[0]) && (depth < depths->depth_range[1])) { - if (ED_view3d_depth_unproject(region, mval_ofs, depth, coords[i])) { + if (ED_view3d_depth_unproject_v3(region, mval_ofs, depth, coords[i])) { depths_valid[i] = true; } } @@ -1751,14 +1751,14 @@ bool ED_view3d_depth_read_cached_normal(const ViewContext *vc, return false; } -bool ED_view3d_depth_unproject(const ARegion *region, - const int mval[2], - const double depth, - float r_location_world[3]) +bool ED_view3d_depth_unproject_v3(const ARegion *region, + const int mval[2], + const double depth, + float r_location_world[3]) { float centx = (float)mval[0] + 0.5f; float centy = (float)mval[1] + 0.5f; - return ED_view3d_unproject(region, centx, centy, depth, r_location_world); + return ED_view3d_unproject_v3(region, centx, centy, depth, r_location_world); } void ED_view3d_depth_tag_update(RegionView3D *rv3d) diff --git a/source/blender/gpu/GPU_matrix.h b/source/blender/gpu/GPU_matrix.h index aad6ae9e2ba..e073263f352 100644 --- a/source/blender/gpu/GPU_matrix.h +++ b/source/blender/gpu/GPU_matrix.h @@ -118,21 +118,27 @@ bool GPU_matrix_unproject_precalc(struct GPUMatrixUnproject_Precalc *unproj_prec const float proj[4][4], const int view[4]); -void GPU_matrix_project(const float world[3], - const float model[4][4], - const float proj[4][4], - const int view[4], - float r_win[3]); - -bool GPU_matrix_unproject(const float win[3], - const float model[4][4], - const float proj[4][4], - const int view[4], - float r_world[3]); - -void GPU_matrix_unproject_with_precalc(const struct GPUMatrixUnproject_Precalc *unproj_precalc, - const float win[3], - float r_world[3]); +void GPU_matrix_project_3fv(const float world[3], + const float model[4][4], + const float proj[4][4], + const int view[4], + float r_win[3]); + +void GPU_matrix_project_2fv(const float world[3], + const float model[4][4], + const float proj[4][4], + const int view[4], + float r_win[2]); + +bool GPU_matrix_unproject_3fv(const float win[3], + const float model[4][4], + const float proj[4][4], + const int view[4], + float r_world[3]); + +void GPU_matrix_unproject_3fv_with_precalc(const struct GPUMatrixUnproject_Precalc *unproj_precalc, + const float win[3], + float r_world[3]); /* 2D Projection Matrix */ diff --git a/source/blender/gpu/intern/gpu_matrix.cc b/source/blender/gpu/intern/gpu_matrix.cc index 569b51a407a..6eb9cb823d5 100644 --- a/source/blender/gpu/intern/gpu_matrix.cc +++ b/source/blender/gpu/intern/gpu_matrix.cc @@ -474,11 +474,11 @@ void GPU_matrix_look_at(float eyeX, GPU_matrix_translate_3f(-eyeX, -eyeY, -eyeZ); } -void GPU_matrix_project(const float world[3], - const float model[4][4], - const float proj[4][4], - const int view[4], - float win[3]) +void GPU_matrix_project_3fv(const float world[3], + const float model[4][4], + const float proj[4][4], + const int view[4], + float win[3]) { float v[4]; @@ -494,6 +494,25 @@ void GPU_matrix_project(const float world[3], win[2] = (v[2] + 1) * 0.5f; } +void GPU_matrix_project_2fv(const float world[3], + const float model[4][4], + const float proj[4][4], + const int view[4], + float win[2]) +{ + float v[4]; + + mul_v4_m4v3(v, model, world); + mul_m4_v4(proj, v); + + if (v[3] != 0.0f) { + mul_v2_fl(v, 1.0f / v[3]); + } + + win[0] = view[0] + (view[2] * (v[0] + 1)) * 0.5f; + win[1] = view[1] + (view[3] * (v[1] + 1)) * 0.5f; +} + /** * The same result could be obtained as follows: * @@ -556,9 +575,9 @@ bool GPU_matrix_unproject_precalc(struct GPUMatrixUnproject_Precalc *precalc, return true; } -void GPU_matrix_unproject_with_precalc(const struct GPUMatrixUnproject_Precalc *precalc, - const float win[3], - float r_world[3]) +void GPU_matrix_unproject_3fv_with_precalc(const struct GPUMatrixUnproject_Precalc *precalc, + const float win[3], + float r_world[3]) { float in[3] = { (win[0] - precalc->view[0]) / precalc->view[2], @@ -569,18 +588,18 @@ void GPU_matrix_unproject_with_precalc(const struct GPUMatrixUnproject_Precalc * mul_v3_m4v3(r_world, precalc->model_inverted, in); } -bool GPU_matrix_unproject(const float win[3], - const float model[4][4], - const float proj[4][4], - const int view[4], - float r_world[3]) +bool GPU_matrix_unproject_3fv(const float win[3], + const float model[4][4], + const float proj[4][4], + const int view[4], + float r_world[3]) { struct GPUMatrixUnproject_Precalc precalc; if (!GPU_matrix_unproject_precalc(&precalc, model, proj, view)) { zero_v3(r_world); return false; } - GPU_matrix_unproject_with_precalc(&precalc, win, r_world); + GPU_matrix_unproject_3fv_with_precalc(&precalc, win, r_world); return true; } diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c index 611a9cba000..2ffa04bd8ae 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c @@ -620,7 +620,7 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos, struct GPUMatrixUnproject_Precalc unproj_precalc; GPU_matrix_unproject_precalc(&unproj_precalc, rv3d->viewmat, rv3d->winmat, viewport); - GPU_matrix_unproject_with_precalc(&unproj_precalc, co_screen, co_3d_origin); + GPU_matrix_unproject_3fv_with_precalc(&unproj_precalc, co_screen, co_3d_origin); uint *buf_iter = buffer; int hit_found = -1; @@ -631,7 +631,7 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos, wmGizmo *gz = visible_gizmos[buf_iter[3] >> 8]; float co_3d[3]; co_screen[2] = int_as_float(buf_iter[1]); - GPU_matrix_unproject_with_precalc(&unproj_precalc, co_screen, co_3d); + GPU_matrix_unproject_3fv_with_precalc(&unproj_precalc, co_screen, co_3d); float select_bias = gz->select_bias; if ((gz->flag & WM_GIZMO_DRAW_NO_SCALE) == 0) { select_bias *= gz->scale_final; -- cgit v1.2.3