Sculpt: Drag dot fixes
* Drag dot now uses anchored's method of calculating brush rake angle, this is much more usable and less numerically unstable. * There is now an option ("Smooth Raking" to smooth rake angles during brushes. This was a failed effort at fixing drag dot raking that turned out to be useful for other things. * Drag dot no longer requests subspacing events from the brush system. This made a huge difference in performance and is now on par with anchored mode.
This commit is contained in:
parent
189d32823a
commit
d02b557f10
|
@ -847,6 +847,13 @@ class StrokePanel(BrushPanel):
|
|||
row.prop(brush, "spacing", text="Spacing")
|
||||
row.prop(brush, "use_pressure_spacing", toggle=True, text="")
|
||||
|
||||
UnifiedPaintPanel.channel_unified(
|
||||
col,
|
||||
context,
|
||||
brush,
|
||||
"use_smoothed_rake"
|
||||
)
|
||||
|
||||
if brush.use_line or brush.use_curve:
|
||||
row = col.row(align=True)
|
||||
if mode == 'SCULPT':
|
||||
|
|
|
@ -210,7 +210,8 @@ void BKE_paint_face_set_overlay_color_get(const int face_set, const int seed, uc
|
|||
/* stroke related */
|
||||
bool paint_calculate_rake_rotation(struct UnifiedPaintSettings *ups,
|
||||
struct Brush *brush,
|
||||
const float mouse_pos[2]);
|
||||
const float mouse_pos[2],
|
||||
const float initial_mouse_pos[2]);
|
||||
void paint_update_brush_rake_rotation(struct UnifiedPaintSettings *ups,
|
||||
struct Brush *brush,
|
||||
float rotation);
|
||||
|
|
|
@ -438,7 +438,7 @@ MAKE_FLOAT(pose_offset, "Pose Origin Offset", "Offset of the pose origin in rela
|
|||
MAKE_FLOAT(disconnected_distance_max, "Max Element Distance",
|
||||
"Maximum distance to search for disconnected loose parts in the mesh", 0.1f, 0.0f, 10.0f)
|
||||
MAKE_INT(pose_smooth_iterations, "Smooth Iterations",
|
||||
"Smooth iterations applied after calculating the pose factor of each vertex", 4.0f, 0.0f, 100.0f)
|
||||
"Smooth iterations applied after calculating the pose factor of each vertex", 4, 0.0f, 100.0f)
|
||||
MAKE_INT(pose_ik_segments, "Pose IK Segments",
|
||||
"Number of segments of the inverse kinematics chain that will deform the mesh", 1, 1, 20)
|
||||
MAKE_FLOAT(surface_smooth_shape_preservation, "Shape Preservation", "How much of the original shape is preserved when smoothing", 0.5f, 0.0f, 1.0f)
|
||||
|
@ -524,6 +524,8 @@ MAKE_ENUM(elastic_deform_type, "Deformation", "Deformation type that is used in
|
|||
})
|
||||
MAKE_BOOL(use_ctrl_invert, "Use Ctrl Invert", "Take brush addition or subtraction mode into account", true)
|
||||
|
||||
MAKE_BOOL(use_smoothed_rake, "Smooth Raking", "Smooth angles of clay strips brush and raked textures", false)
|
||||
|
||||
//MAKE_FLOAT3_EX
|
||||
/* clang-format on */
|
||||
#if defined(BRUSH_CHANNEL_DEFINE_TYPES) || defined(BRUSH_CHANNEL_DEFINE_EXTERNAL)
|
||||
|
|
|
@ -47,6 +47,12 @@
|
|||
# pragma warning(error : 4033) /* 'function' must return a value */
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
struct {
|
||||
char t1[32], t2[32], t3[32], t4[32];
|
||||
} test[1] = {{1, 1, 1, 1}};
|
||||
#endif
|
||||
|
||||
static bool check_builtin_init();
|
||||
|
||||
#if 1
|
||||
|
@ -247,6 +253,7 @@ static bool check_builtin_init()
|
|||
SETCAT(tip_scale_x, "Basic");
|
||||
SETCAT(tip_roundness, "Basic");
|
||||
SETCAT(normal_radius_factor, "Basic");
|
||||
SETCAT(use_smoothed_rake, "Basic");
|
||||
|
||||
SETCAT(plane_offset, "Clay");
|
||||
SETCAT(plane_trim, "Clay");
|
||||
|
@ -925,6 +932,15 @@ void BKE_brush_builtin_patch(Brush *brush, int tool)
|
|||
ADDCH(radius_unit);
|
||||
ADDCH(unprojected_radius);
|
||||
|
||||
if (!BRUSHSET_LOOKUP(chset, use_smoothed_rake)) {
|
||||
BrushChannel *ch = ADDCH(use_smoothed_rake);
|
||||
|
||||
if (tool == SCULPT_TOOL_CLAY_STRIPS) {
|
||||
ch->flag |= BRUSH_CHANNEL_SHOW_IN_WORKSPACE;
|
||||
ch->flag |= BRUSH_CHANNEL_SHOW_IN_CONTEXT_MENU;
|
||||
}
|
||||
}
|
||||
|
||||
ADDCH(plane_offset);
|
||||
ADDCH(plane_trim);
|
||||
ADDCH(use_plane_trim);
|
||||
|
@ -1218,6 +1234,9 @@ void BKE_brush_channelset_ui_init(Brush *brush, int tool)
|
|||
SHOWWRK(tip_roundness);
|
||||
SHOWWRK(use_plane_trim);
|
||||
|
||||
SHOWWRK(use_smoothed_rake);
|
||||
SHOWCTX(use_smoothed_rake);
|
||||
|
||||
SHOWCTX(autosmooth);
|
||||
SHOWCTX(plane_offset);
|
||||
SHOWCTX(plane_trim);
|
||||
|
|
|
@ -1309,7 +1309,8 @@ void paint_update_brush_rake_rotation(UnifiedPaintSettings *ups, Brush *brush, f
|
|||
|
||||
bool paint_calculate_rake_rotation(UnifiedPaintSettings *ups,
|
||||
Brush *brush,
|
||||
const float mouse_pos[2])
|
||||
const float mouse_pos[2],
|
||||
const float initial_mouse_pos[2])
|
||||
{
|
||||
bool ok = false;
|
||||
if ((brush->mtex.brush_angle_mode & MTEX_ANGLE_RAKE) ||
|
||||
|
@ -1317,6 +1318,19 @@ bool paint_calculate_rake_rotation(UnifiedPaintSettings *ups,
|
|||
const float r = RAKE_THRESHHOLD;
|
||||
float rotation;
|
||||
|
||||
if (brush->flag & BRUSH_DRAG_DOT) {
|
||||
const float dx = mouse_pos[0] - initial_mouse_pos[0];
|
||||
const float dy = mouse_pos[1] - initial_mouse_pos[1];
|
||||
|
||||
if (dx * dx + dy * dy > 0.5f) {
|
||||
ups->brush_rotation = ups->brush_rotation_sec = atan2f(dx, dy) + (float)M_PI;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
float dpos[2];
|
||||
sub_v2_v2v2(dpos, ups->last_rake, mouse_pos);
|
||||
|
||||
|
|
|
@ -926,10 +926,46 @@ static float dist_Minkovsky(float x, float y, float z, float e)
|
|||
return powf(powf(fabsf(x), e) + powf(fabsf(y), e) + powf(fabsf(z), e), 1.0f / e);
|
||||
}
|
||||
|
||||
BLI_INLINE float calc_voronoi_dist(int dtype, float x, float y, float z, float e)
|
||||
{
|
||||
switch (dtype) {
|
||||
case 1:
|
||||
return (x * x + y * y + z * z);
|
||||
break;
|
||||
case 2:
|
||||
return fabsf(x) + fabsf(y) + fabsf(z);
|
||||
break;
|
||||
case 3: {
|
||||
x = fabsf(x);
|
||||
y = fabsf(y);
|
||||
z = fabsf(z);
|
||||
|
||||
float t = (x > y) ? x : y;
|
||||
return ((z > t) ? z : t);
|
||||
}
|
||||
case 4: {
|
||||
float d = sqrtf(fabsf(x)) + sqrtf(fabsf(y)) + sqrtf(fabsf(z));
|
||||
return (d * d);
|
||||
}
|
||||
case 5: {
|
||||
x *= x;
|
||||
y *= y;
|
||||
z *= z;
|
||||
return sqrtf(sqrtf(x * x + y * y + z * z));
|
||||
}
|
||||
case 6: {
|
||||
return powf(powf(fabsf(x), e) + powf(fabsf(y), e) + powf(fabsf(z), e), 1.0f / e);
|
||||
}
|
||||
case 0:
|
||||
default:
|
||||
return sqrtf(x * x + y * y + z * z);
|
||||
}
|
||||
}
|
||||
/* Not 'pure' Worley, but the results are virtually the same.
|
||||
* Returns distances in da and point coords in pa */
|
||||
void BLI_noise_voronoi(float x, float y, float z, float *da, float *pa, float me, int dtype)
|
||||
{
|
||||
#if 1
|
||||
float (*distfunc)(float, float, float, float);
|
||||
switch (dtype) {
|
||||
case 1:
|
||||
|
@ -955,6 +991,7 @@ void BLI_noise_voronoi(float x, float y, float z, float *da, float *pa, float me
|
|||
distfunc = dist_Real;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
int xi = (int)(floor(x));
|
||||
int yi = (int)(floor(y));
|
||||
|
|
|
@ -1996,7 +1996,8 @@ static void paint_cursor_update_rake_rotation(PaintCursorContext *pcontext)
|
|||
* and we may get interference with the stroke itself.
|
||||
* For line strokes, such interference is visible. */
|
||||
if (!pcontext->ups->stroke_active) {
|
||||
paint_calculate_rake_rotation(pcontext->ups, pcontext->brush, pcontext->translation);
|
||||
paint_calculate_rake_rotation(
|
||||
pcontext->ups, pcontext->brush, pcontext->translation, pcontext->translation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ static bool paint_stroke_use_scene_spacing(Brush *brush, ePaintMode mode)
|
|||
|
||||
static bool paint_tool_require_inbetween_mouse_events(Brush *brush, ePaintMode mode)
|
||||
{
|
||||
if (brush->flag & BRUSH_ANCHORED) {
|
||||
if (brush->flag & (BRUSH_ANCHORED|BRUSH_DRAG_DOT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -400,7 +400,7 @@ static bool paint_brush_update(bContext *C,
|
|||
}
|
||||
/* curve strokes do their own rake calculation */
|
||||
else if (!(brush->flag & BRUSH_CURVE)) {
|
||||
if (!paint_calculate_rake_rotation(ups, brush, mouse_init)) {
|
||||
if (!paint_calculate_rake_rotation(ups, brush, mouse_init, stroke->initial_mouse)) {
|
||||
/* Not enough motion to define an angle. */
|
||||
if (!stroke->rake_started) {
|
||||
is_dry_run = true;
|
||||
|
@ -1574,7 +1574,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
(br->mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE)) {
|
||||
copy_v2_v2(stroke->ups->last_rake, stroke->last_mouse_position);
|
||||
}
|
||||
paint_calculate_rake_rotation(stroke->ups, br, mouse);
|
||||
paint_calculate_rake_rotation(stroke->ups, br, mouse, stroke->initial_mouse);
|
||||
}
|
||||
}
|
||||
else if (first_modal ||
|
||||
|
|
|
@ -10720,13 +10720,34 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
|
|||
add_v3_v3(cache->grab_delta, delta);
|
||||
}
|
||||
else if (sculpt_needs_delta_for_tip_orientation(brush)) {
|
||||
if (brush->flag & BRUSH_ANCHORED) {
|
||||
if (brush->flag & (BRUSH_ANCHORED | BRUSH_DRAG_DOT)) {
|
||||
float orig[3];
|
||||
mul_v3_m4v3(orig, ob->obmat, cache->orig_grab_location);
|
||||
sub_v3_v3v3(cache->grab_delta, grab_location, orig);
|
||||
}
|
||||
else {
|
||||
sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
|
||||
if (SCULPT_get_int(ss, use_smoothed_rake, NULL, brush)) {
|
||||
float tmp1[3];
|
||||
float tmp2[3];
|
||||
|
||||
sub_v3_v3v3(tmp1, grab_location, cache->old_grab_location);
|
||||
copy_v3_v3(tmp2, ss->cache->grab_delta);
|
||||
|
||||
normalize_v3(tmp1);
|
||||
normalize_v3(tmp2);
|
||||
|
||||
bool bad = len_v3v3(grab_location, cache->old_grab_location) < 0.0001f;
|
||||
bad = bad || saacos(dot_v3v3(tmp1, tmp2) > 0.35f);
|
||||
|
||||
float t = bad ? 0.1f : 0.5f;
|
||||
|
||||
sub_v3_v3v3(tmp1, grab_location, cache->old_grab_location);
|
||||
interp_v3_v3v3(cache->grab_delta, cache->grab_delta, tmp1, t);
|
||||
}
|
||||
else {
|
||||
sub_v3_v3v3(ss->cache->grab_delta, grab_location, cache->old_grab_location);
|
||||
}
|
||||
// cache->grab_delta
|
||||
}
|
||||
invert_m4_m4(imat, ob->obmat);
|
||||
mul_mat3_m4_v3(imat, cache->grab_delta);
|
||||
|
|
Loading…
Reference in New Issue