[Bf-blender-cvs] [37f4660] master: Fix T44344: paint bleed fails in perspective view

Campbell Barton noreply at git.blender.org
Thu Sep 10 18:39:26 CEST 2015


Commit: 37f46606374f37dbe73c3555dc04c96a56e90bf3
Author: Campbell Barton
Date:   Fri Sep 11 02:15:07 2015 +1000
Branches: master
https://developer.blender.org/rB37f46606374f37dbe73c3555dc04c96a56e90bf3

Fix T44344: paint bleed fails in perspective view

===================================================================

M	source/blender/editors/sculpt_paint/paint_image_proj.c

===================================================================

diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index cf13c9c..7108b2b 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -298,6 +298,7 @@ typedef struct ProjPaintState {
 	float cloneOffset[2];
 
 	float projectMat[4][4];     /* Projection matrix, use for getting screen coords */
+	float projectMatInv[4][4];  /* inverse of projectMat */
 	float viewDir[3];           /* View vector, use for do_backfacecull and for ray casting with an ortho viewport  */
 	float viewPos[3];           /* View location in object relative 3D space, so can compare to verts  */
 	float clipsta, clipend;
@@ -1247,6 +1248,55 @@ static void screen_px_from_persp(
 }
 
 
+/**
+ * Set a direction vector based on a screen location.
+ * (use for perspective view, else we can simply use `ps->viewDir`)
+ *
+ * Similar functionality to #ED_view3d_win_to_vector
+ *
+ * \param r_dir: Resulting direction (length is undefined).
+ */
+static void screen_px_to_vector_persp(
+        int winx, int winy, const float projmat_inv[4][4], const float view_pos[3],
+        const float co_px[2],
+        float r_dir[3])
+{
+	r_dir[0] = 2.0f * (co_px[0] / winx) - 1.0f;
+	r_dir[1] = 2.0f * (co_px[1] / winy) - 1.0f;
+	r_dir[2] = -0.5f;
+	mul_project_m4_v3((float(*)[4])projmat_inv, r_dir);
+	sub_v3_v3(r_dir, view_pos);
+}
+
+/**
+ * Special function to return the factor fo a point along a line in pixel space.
+ *
+ * This is needed since we can't use #line_point_factor_v2 for perspective screen-space coords.
+ *
+ * \param p: 2D screen-space location.
+ * \param v1, v2: 3D object-space locations.
+ */
+static float screen_px_line_point_factor_v2_persp(
+        const ProjPaintState *ps,
+        const float p[2],
+        const float v1[3], const float v2[3])
+{
+	const float zero[3] = {0};
+	float v1_proj[3], v2_proj[3];
+	float dir[3];
+
+	screen_px_to_vector_persp(ps->winx, ps->winy, ps->projectMatInv, ps->viewPos, p, dir);
+
+	sub_v3_v3v3(v1_proj, v1, ps->viewPos);
+	sub_v3_v3v3(v2_proj, v2, ps->viewPos);
+
+	project_plane_v3_v3v3(v1_proj, v1_proj, dir);
+	project_plane_v3_v3v3(v2_proj, v2_proj, dir);
+
+	return line_point_factor_v2(zero, v1_proj, v2_proj);
+}
+
+
 static void project_face_pixel(
         const float *lt_tri_uv[3], ImBuf *ibuf_other, const float w[3],
         unsigned char rgba_ub[4], float rgba_f[4])
@@ -2680,8 +2730,15 @@ static void project_paint_face_init(
 				    line_clip_rect2f(clip_rect, bucket_bounds, vCoSS[fidx1], vCoSS[fidx2], bucket_clip_edges[0], bucket_clip_edges[1]))
 				{
 					if (len_squared_v2v2(vCoSS[fidx1], vCoSS[fidx2]) > FLT_EPSILON) { /* avoid div by zero */
-						fac1 = line_point_factor_v2(bucket_clip_edges[0], vCoSS[fidx1], vCoSS[fidx2]);
-						fac2 = line_point_factor_v2(bucket_clip_edges[1], vCoSS[fidx1], vCoSS[fidx2]);
+
+						if (is_ortho) {
+							fac1 = line_point_factor_v2(bucket_clip_edges[0], vCoSS[fidx1], vCoSS[fidx2]);
+							fac2 = line_point_factor_v2(bucket_clip_edges[1], vCoSS[fidx1], vCoSS[fidx2]);
+						}
+						else {
+							fac1 = screen_px_line_point_factor_v2_persp(ps, bucket_clip_edges[0], vCo[fidx1], vCo[fidx2]);
+							fac2 = screen_px_line_point_factor_v2_persp(ps, bucket_clip_edges[1], vCo[fidx1], vCo[fidx2]);
+						}
 
 						interp_v2_v2v2(seam_subsection[0], lt_uv_pxoffset[fidx1], lt_uv_pxoffset[fidx2], fac1);
 						interp_v2_v2v2(seam_subsection[1], lt_uv_pxoffset[fidx1], lt_uv_pxoffset[fidx2], fac2);
@@ -3104,6 +3161,7 @@ static void proj_paint_state_viewport_init(
 		mul_m4_m4m4(ps->projectMat, winmat, vmat);
 	}
 
+	invert_m4_m4(ps->projectMatInv, ps->projectMat);
 
 	/* viewDir - object relative */
 	copy_m3_m4(mat, viewinv);




More information about the Bf-blender-cvs mailing list