Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Riakiotakis <kalast@gmail.com>2013-06-26 18:28:39 +0400
committerAntony Riakiotakis <kalast@gmail.com>2013-06-26 18:28:39 +0400
commit3b0328436f039a2274caf9c58588b3318a0eed44 (patch)
tree1f216ca5d82c1d5bd594151b274a514cbe22000f /source/blender/editors/sculpt_paint
parent42940807ee47cf27fc1b88e28b52439ff9488a25 (diff)
Fix #35365 Texture cloning not behaving correctly in perspective view
This issue was caused by doing pespective interpolation of clone uv coordinates in perspective view. To fix this we need to use perspective correction for screen coordinates, but return regular barycentric weights back for clone layer uv coordinate interpolation.
Diffstat (limited to 'source/blender/editors/sculpt_paint')
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index a24ee13e3bf..553a5cbe9ac 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -1121,6 +1121,44 @@ static void screen_px_from_persp(
interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w);
}
+
+/* same as screen_px_from_persp except we return ortho weights back to the caller.
+ * These weights will be used to determine correct interpolation of uvs in cloned uv layer */
+static void screen_px_from_persp_ortho_weights(
+ float uv[2],
+ float v1co[4], float v2co[4], float v3co[4], /* screenspace coords */
+ float uv1co[2], float uv2co[2], float uv3co[2],
+ float pixelScreenCo[4],
+ float w[3])
+{
+ float w_int[3];
+ float wtot_inv, wtot;
+ barycentric_weights_v2(uv1co, uv2co, uv3co, uv, w);
+
+ /* re-weight from the 4th coord of each screen vert */
+ w_int[0] = w[0] * v1co[3];
+ w_int[1] = w[1] * v2co[3];
+ w_int[2] = w[2] * v3co[3];
+
+ wtot = w_int[0] + w_int[1] + w_int[2];
+
+ if (wtot > 0.0f) {
+ wtot_inv = 1.0f / wtot;
+ w_int[0] *= wtot_inv;
+ w_int[1] *= wtot_inv;
+ w_int[2] *= wtot_inv;
+ }
+ else {
+ w[0] = w[1] = w[2] =
+ w_int[0] = w_int[1] = w_int[2] = 1.0f / 3.0f; /* dummy values for zero area face */
+ }
+ /* done re-weighting */
+
+ /* do interpolation based on projected weight */
+ interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w_int);
+}
+
+
static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const float w[3],
int side, unsigned char rgba_ub[4], float rgba_f[4])
{
@@ -2168,6 +2206,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
float uv_clip[8][2];
int uv_clip_tot;
const short is_ortho = ps->is_ortho;
+ const short is_clone_other = ((ps->brush->imagepaint_tool == PAINT_TOOL_CLONE) && ps->dm_mtface_clone);
const short do_backfacecull = ps->do_backfacecull;
const short do_clip = ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0;
@@ -2191,8 +2230,6 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
* but since the first thing most people try is painting onto a quad- better make it work.
*/
-
-
tf_uv_pxoffset[0][0] = tf->uv[0][0] - xhalfpx;
tf_uv_pxoffset[0][1] = tf->uv[0][1] - yhalfpx;
@@ -2277,7 +2314,8 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
has_x_isect = has_isect = 1;
if (is_ortho) screen_px_from_ortho(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
- else screen_px_from_persp(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
+ else if (is_clone_other) screen_px_from_persp_ortho_weights(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
+ else screen_px_from_persp(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
/* a pity we need to get the worldspace pixel location here */
if (do_clip || do_3d_mapping) {