diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2013-04-22 14:46:01 +0400 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2013-04-22 14:46:01 +0400 |
commit | c0eadedb7061ac9f69b3f8ecf5fd675d6a22221c (patch) | |
tree | 90000d4bf57d3e687cbe7548a374d17dfeb78fce /source/blender/blenkernel/intern/brush.c | |
parent | 53479be58105155c319b7862c0e2c2d45415846d (diff) |
Support more mapping modes for alpha masks. Tiled, stencil and random
Diffstat (limited to 'source/blender/blenkernel/intern/brush.c')
-rw-r--r-- | source/blender/blenkernel/intern/brush.c | 124 |
1 files changed, 92 insertions, 32 deletions
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index dd299be9764..064e902f831 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -560,11 +560,11 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br, x /= (br->stencil_dimension[0]); y /= (br->stencil_dimension[1]); - x *= br->mtex.size[0]; - y *= br->mtex.size[1]; + x *= mtex->size[0]; + y *= mtex->size[1]; - co[0] = x + br->mtex.ofs[0]; - co[1] = y + br->mtex.ofs[1]; + co[0] = x + mtex->ofs[0]; + co[1] = y + mtex->ofs[1]; co[2] = 0.0f; hasrgb = externtex(mtex, co, &intensity, @@ -620,11 +620,11 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br, y = flen * sinf(angle); } - x *= br->mtex.size[0]; - y *= br->mtex.size[1]; + x *= mtex->size[0]; + y *= mtex->size[1]; - co[0] = x + br->mtex.ofs[0]; - co[1] = y + br->mtex.ofs[1]; + co[0] = x + mtex->ofs[0]; + co[1] = y + mtex->ofs[1]; co[2] = 0.0f; hasrgb = externtex(mtex, co, &intensity, @@ -650,26 +650,83 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br, { UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; MTex *mtex = &br->mask_mtex; + float rgba[4], intensity; - if (mtex && mtex->tex) { + if (!mtex->tex) { + return 1.0f; + } + if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) { float rotation = -mtex->rot; float point_2d[2] = {point[0], point[1]}; float x = 0.0f, y = 0.0f; /* Quite warnings */ - float radius = 1.0f; /* Quite warnings */ float co[3]; - float rgba[4], intensity = 1.0; - point_2d[0] -= ups->tex_mouse[0]; - point_2d[1] -= ups->tex_mouse[1]; + x = point_2d[0] - br->stencil_pos[0]; + y = point_2d[1] - br->stencil_pos[1]; - /* use pressure adjusted size for fixed mode */ - radius = ups->pixel_radius; + if (rotation > 0.001f || rotation < -0.001f) { + const float angle = atan2f(y, x) + rotation; + const float flen = sqrtf(x * x + y * y); - x = point_2d[0]; - y = point_2d[1]; + x = flen * cosf(angle); + y = flen * sinf(angle); + } - x /= radius; - y /= radius; + if (fabsf(x) > br->stencil_dimension[0] || fabsf(y) > br->stencil_dimension[1]) { + zero_v4(rgba); + return 0.0f; + } + x /= (br->stencil_dimension[0]); + y /= (br->stencil_dimension[1]); + + x *= mtex->size[0]; + y *= mtex->size[1]; + + co[0] = x + mtex->ofs[0]; + co[1] = y + mtex->ofs[1]; + co[2] = 0.0f; + + externtex(mtex, co, &intensity, + rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool); + } + else { + float rotation = -mtex->rot; + float point_2d[2] = {point[0], point[1]}; + float x = 0.0f, y = 0.0f; /* Quite warnings */ + float invradius = 1.0f; /* Quite warnings */ + float co[3]; + + if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) { + /* keep coordinates relative to mouse */ + + rotation += ups->brush_rotation; + + x = point_2d[0] - ups->mask_tex_mouse[0]; + y = point_2d[1] - ups->mask_tex_mouse[1]; + + /* use pressure adjusted size for fixed mode */ + invradius = 1.0f / ups->pixel_radius; + } + else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) { + /* leave the coordinates relative to the screen */ + + /* use unadjusted size for tiled mode */ + invradius = 1.0f / BKE_brush_size_get(scene, br); + + x = point_2d[0]; + y = point_2d[1]; + } + else if (mtex->brush_map_mode == MTEX_MAP_MODE_RANDOM) { + rotation += ups->brush_rotation; + /* these contain a random coordinate */ + x = point_2d[0] - ups->mask_tex_mouse[0]; + y = point_2d[1] - ups->mask_tex_mouse[1]; + + invradius = 1.0f / ups->pixel_radius; + } + + x *= invradius; + y *= invradius; /* it is probably worth optimizing for those cases where * the texture is not rotated by skipping the calls to @@ -682,21 +739,18 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br, y = flen * sinf(angle); } - x *= br->mask_mtex.size[0]; - y *= br->mask_mtex.size[1]; + x *= mtex->size[0]; + y *= mtex->size[1]; - co[0] = x + br->mask_mtex.ofs[0]; - co[1] = y + br->mask_mtex.ofs[1]; + co[0] = x + mtex->ofs[0]; + co[1] = y + mtex->ofs[1]; co[2] = 0.0f; externtex(mtex, co, &intensity, - rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool); - - return intensity; - } - else { - return 1.0f; + rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool); } + + return intensity; } /* Brush Sampling for 2D brushes. when we unify the brush systems this will be necessarily a separate function */ @@ -1044,12 +1098,18 @@ void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2], } } -void BKE_brush_randomize_texture_coordinates(UnifiedPaintSettings *ups) +void BKE_brush_randomize_texture_coordinates(UnifiedPaintSettings *ups, bool mask) { /* we multiply with brush radius as an optimization for the brush * texture sampling functions */ - ups->tex_mouse[0] = BLI_rng_get_float(brush_rng) * ups->pixel_radius; - ups->tex_mouse[1] = BLI_rng_get_float(brush_rng) * ups->pixel_radius; + if (mask) { + ups->mask_tex_mouse[0] = BLI_rng_get_float(brush_rng) * ups->pixel_radius; + ups->mask_tex_mouse[1] = BLI_rng_get_float(brush_rng) * ups->pixel_radius; + } + else { + ups->tex_mouse[0] = BLI_rng_get_float(brush_rng) * ups->pixel_radius; + ups->tex_mouse[1] = BLI_rng_get_float(brush_rng) * ups->pixel_radius; + } } /* Uses the brush curve control to find a strength value between 0 and 1 */ |