diff options
-rw-r--r-- | source/blender/blenlib/BLI_math_geom.h | 8 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_geom.c | 43 |
2 files changed, 51 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index d5485765844..5ac4ce8be0b 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -635,6 +635,14 @@ void projmat_dimensions(const float projmat[4][4], float *r_near, float *r_far); +void projmat_from_subregion(const float projmat[4][4], + const int win_size[2], + const int x_min, + const int x_max, + const int y_min, + const int y_max, + float r_projmat[4][4]); + int box_clip_bounds_m4(float boundbox[2][3], const float bounds[4], float winmat[4][4]); void box_minmax_bounds_m4(float min[3], float max[3], float boundbox[2][3], float mat[4][4]); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 7cdac6b1497..6f71551d4a0 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -4481,6 +4481,49 @@ void projmat_dimensions(const float projmat[4][4], } } +/* Creates a projection matrix for a small region of the viewport. + * + * \param projmat: Projection Matrix. + * \param win_size: Viewport Size. + * \param x_min, x_max, y_min, y_max: Coordinates of the subregion. + * \return r_projmat: Resulting Projection Matrix. + */ +void projmat_from_subregion(const float projmat[4][4], + const int win_size[2], + const int x_min, + const int x_max, + const int y_min, + const int y_max, + float r_projmat[4][4]) +{ + float rect_width = (float)(x_max - x_min); + float rect_height = (float)(y_max - y_min); + + float x_fac = ((x_min + x_max) - win_size[0]) / rect_width; + float y_fac = ((y_min + y_max) - win_size[1]) / rect_height; + + copy_m4_m4(r_projmat, projmat); + r_projmat[0][0] *= (win_size[0] / rect_width); + r_projmat[1][1] *= (win_size[1] / rect_height); + +#if 0 /* TODO: check if this is more efficient. */ + r_projmat[2][0] -= x_fac * r_projmat[2][3]; + r_projmat[2][1] -= y_fac * r_projmat[2][3]; + + r_projmat[3][0] -= x_fac * r_projmat[3][3]; + r_projmat[3][1] -= y_fac * r_projmat[3][3]; +#else + if (projmat[3][3] == 0.0f) { + r_projmat[2][0] += x_fac; + r_projmat[2][1] += y_fac; + } + else { + r_projmat[3][0] -= x_fac; + r_projmat[3][1] -= y_fac; + } +#endif +} + static void i_multmatrix(float icand[4][4], float Vm[4][4]) { int row, col; |