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-01-21 01:32:14 +0400
committerAntony Riakiotakis <kalast@gmail.com>2013-01-21 01:32:14 +0400
commite6f82619899af71b823e58812b231599d4dd46e2 (patch)
tree02410f8a066eed56cb5806f351b0e661358884ec /source/blender/editors/sculpt_paint
parent952c83cb621b97789ca5436390f28309c38ab0ff (diff)
3D mapping for projective texture painting (only for draw brush). Useful
to draw with procedural textures on surface of object. 2D painting will still paint as if tiled. When we unify the paint systems, the texture sampling functions will need to be changed. Sculpt uses a slightly different system that passes both screen and 3d coordinates to the sampling function. This commit however is not too disrupting for that however so it can go in now.
Diffstat (limited to 'source/blender/editors/sculpt_paint')
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c45
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c9
2 files changed, 35 insertions, 19 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index b9e5a082ff8..40311658ed4 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -355,7 +355,7 @@ typedef union pixelStore {
typedef struct ProjPixel {
float projCoSS[2]; /* the floating point screen projection of this pixel */
-
+ float worldCoSS[3];
/* Only used when the airbrush is disabled.
* Store the max mask value to avoid painting over an area with a lower opacity
* with an advantage that we can avoid touching the pixel at all, if the
@@ -1526,6 +1526,11 @@ static int project_paint_pixel_sizeof(const short tool)
}
}
+static bool project_paint_supports_3d_mapping(Brush *brush)
+{
+ return (brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) && (brush->imagepaint_tool == PAINT_TOOL_DRAW);
+}
+
/* run this function when we know a bucket's, face's pixel can be initialized,
* return the ProjPixel which is added to 'ps->bucketRect[bucket_index]' */
static ProjPixel *project_paint_uvpixel_init(
@@ -1537,6 +1542,7 @@ static ProjPixel *project_paint_uvpixel_init(
const int face_index,
const int image_index,
const float pixelScreenCo[4],
+ const float world_spaceCo[3],
const int side,
const float w[3])
{
@@ -1565,6 +1571,9 @@ static ProjPixel *project_paint_uvpixel_init(
}
/* screenspace unclamped, we could keep its z and w values but don't need them at the moment */
+ if(project_paint_supports_3d_mapping(ps->brush))
+ copy_v3_v3(projPixel->worldCoSS, world_spaceCo);
+
copy_v2_v2(projPixel->projCoSS, pixelScreenCo);
projPixel->x_px = x_px;
@@ -2374,6 +2383,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
float *uv1co, *uv2co, *uv3co; /* for convenience only, these will be assigned to tf->uv[0],1,2 or tf->uv[0],2,3 */
float pixelScreenCo[4];
+ bool do_3d_mapping = project_paint_supports_3d_mapping(ps->brush);
rcti bounds_px; /* ispace bounds */
/* vars for getting uvspace bounds */
@@ -2449,7 +2459,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
v1coSS = ps->screenCoords[(*(&mf->v1 + i1))];
v2coSS = ps->screenCoords[(*(&mf->v1 + i2))];
v3coSS = ps->screenCoords[(*(&mf->v1 + i3))];
-
+
/* This funtion gives is a concave polyline in UV space from the clipped quad and tri*/
project_bucket_clip_face(
is_ortho, bucket_bounds,
@@ -2501,9 +2511,9 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
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) {
+ if (do_clip || do_3d_mapping) {
interp_v3_v3v3v3(wco, ps->dm_mvert[(*(&mf->v1 + i1))].co, ps->dm_mvert[(*(&mf->v1 + i2))].co, ps->dm_mvert[(*(&mf->v1 + i3))].co, w);
- if (ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
+ if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
continue; /* Watch out that no code below this needs to run */
}
}
@@ -2520,9 +2530,10 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
if (mask > 0.0f) {
BLI_linklist_prepend_arena(
bucketPixelNodes,
- project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index, image_index, pixelScreenCo, side, w),
- arena
- );
+ project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index,
+ image_index, pixelScreenCo, wco, side, w),
+ arena
+ );
}
}
@@ -2725,11 +2736,11 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
}
/* a pity we need to get the worldspace pixel location here */
- if (do_clip) {
+ if (do_clip || do_3d_mapping) {
if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
- if (ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
+ if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
continue; /* Watch out that no code below this needs to run */
}
}
@@ -2739,7 +2750,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
if (mask > 0.0f) {
BLI_linklist_prepend_arena(
bucketPixelNodes,
- project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index, image_index, pixelScreenCo, side, w),
+ project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index, image_index, pixelScreenCo, wco, side, w),
arena
);
}
@@ -4105,7 +4116,7 @@ static void *do_projectpaint_thread(void *ph_v)
/*if (dist < radius) {*/ /* correct but uses a sqrtf */
if (dist_nosqrt <= radius_squared) {
- float samplecos[2];
+ float samplecos[3];
dist = sqrtf(dist_nosqrt);
falloff = BKE_brush_curve_strength_clamp(ps->brush, dist, radius);
@@ -4114,9 +4125,11 @@ static void *do_projectpaint_thread(void *ph_v)
if (ps->brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
sub_v2_v2v2(samplecos, projPixel->projCoSS, pos);
}
- else {
- copy_v2_v2(samplecos, projPixel->projCoSS);
- }
+ /* taking 3d copy to account for 3D mapping too. It gets concatenated during sampling */
+ else if (project_paint_supports_3d_mapping(ps->brush))
+ copy_v3_v3(samplecos, projPixel->worldCoSS);
+ else
+ copy_v3_v3(samplecos, projPixel->projCoSS);
}
if (falloff > 0.0f) {
@@ -5008,7 +5021,9 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps)
ps->pixel_sizeof = project_paint_pixel_sizeof(ps->tool);
BLI_assert(ps->pixel_sizeof >= sizeof(ProjPixel));
- ps->do_masking = (brush->flag & BRUSH_AIRBRUSH || brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) ? false : true;
+ /* disable for 3d mapping also because painting on mirrored mesh can create "stripes" */
+ ps->do_masking = (brush->flag & BRUSH_AIRBRUSH || brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW ||
+ project_paint_supports_3d_mapping(brush)) ? false : true;
ps->is_texbrush = (brush->mtex.tex) ? 1 : 0;
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index 9965727ed79..c8cd38045bd 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -205,7 +205,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
xy[0] = x + xoff;
xy[1] = y + yoff;
- BKE_brush_sample_tex(scene, brush, xy, tf, 0);
+ BKE_brush_sample_tex_2D(scene, brush, xy, tf, 0);
}
bf[0] = tf[0] * mf[0];
@@ -236,7 +236,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
xy[0] = x + xoff;
xy[1] = y + yoff;
- BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
+ BKE_brush_sample_tex_2D(scene, brush, xy, rgba, 0);
rgba_float_to_uchar(t, rgba);
}
@@ -314,6 +314,7 @@ static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2
short flt;
const int diameter = 2 * BKE_brush_size_get(scene, brush);
const float alpha = BKE_brush_alpha_get(scene, brush);
+ const bool do_tiled = ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_TILED, MTEX_MAP_MODE_3D);
if (diameter != cache->lastsize ||
alpha != cache->lastalpha ||
@@ -331,7 +332,7 @@ static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2
flt = cache->flt;
size = (cache->size) ? cache->size : diameter;
- if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) {
+ if (do_tiled) {
BKE_brush_imbuf_new(scene, brush, flt, 3, size, &cache->maskibuf, use_color_correction);
brush_painter_fixed_tex_partial_update(painter, pos);
}
@@ -342,7 +343,7 @@ static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2
cache->lastalpha = alpha;
cache->lastjitter = brush->jitter;
}
- else if ((brush->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) && mtex && mtex->tex) {
+ else if (do_tiled && mtex && mtex->tex) {
int dx = (int)painter->lastpaintpos[0] - (int)pos[0];
int dy = (int)painter->lastpaintpos[1] - (int)pos[1];