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.
This commit is contained in:
parent
c145cb7998
commit
f71cf99616
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(world, rv3d->viewmat, rv3d->winmat, viewport, r_region_co);
|
||||
GPU_matrix_project_3fv(world, rv3d->viewmat, rv3d->winmat, viewport, r_region_co);
|
||||
}
|
||||
|
||||
bool ED_view3d_unproject(
|
||||
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_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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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]);
|
||||
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]);
|
||||
|
||||
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_project_2fv(const float world[3],
|
||||
const float model[4][4],
|
||||
const float proj[4][4],
|
||||
const int view[4],
|
||||
float r_win[2]);
|
||||
|
||||
void GPU_matrix_unproject_with_precalc(const struct GPUMatrixUnproject_Precalc *unproj_precalc,
|
||||
const float win[3],
|
||||
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]);
|
||||
|
||||
void GPU_matrix_unproject_3fv_with_precalc(const struct GPUMatrixUnproject_Precalc *unproj_precalc,
|
||||
const float win[3],
|
||||
float r_world[3]);
|
||||
|
||||
/* 2D Projection Matrix */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue