Fix: GPv3: Draw Tool: First point too large when using angle factor
The first point was always set to the brush radius, even when the angle setting was used. Additionally, the approximation for the pen direction started at (0, 0). This fixes the issue by overwriting the radius of the first point once we get the first extension sample and with that the first approximation of the pen direction. The pen direction is also set to the initial direction from the first to the second point.
This commit is contained in:
@@ -733,18 +733,25 @@ struct PaintOperationExecutor {
|
||||
const int last_active_point = curve_points.last();
|
||||
|
||||
const float2 prev_coords = self.screen_space_coords_orig_.last();
|
||||
const float prev_radius = drawing_->radii()[last_active_point];
|
||||
float prev_radius = drawing_->radii()[last_active_point];
|
||||
const float prev_opacity = drawing_->opacities()[last_active_point];
|
||||
const ColorGeometry4f prev_vertex_color = drawing_->vertex_colors()[last_active_point];
|
||||
|
||||
/* Use the vector from the previous to the next point and then interpolate it with the previous
|
||||
* direction to get a smoothed value over time. */
|
||||
self.smoothed_pen_direction_ = math::interpolate(
|
||||
self.smoothed_pen_direction_, coords - self.screen_space_coords_orig_.last(), 0.1f);
|
||||
const bool is_first_sample = (curve_points.size() == 1);
|
||||
|
||||
const float distance_px = math::distance(coords, prev_coords);
|
||||
/* Use the vector from the previous to the next point. Set the direction based on the first two
|
||||
* samples. For subsuquent samples, interpolate with the previous direction to get a smoothed
|
||||
* value over time. */
|
||||
if (is_first_sample) {
|
||||
self.smoothed_pen_direction_ = self.screen_space_coords_orig_.last() - coords;
|
||||
}
|
||||
else {
|
||||
self.smoothed_pen_direction_ = math::interpolate(
|
||||
self.smoothed_pen_direction_, self.screen_space_coords_orig_.last() - coords, 0.1f);
|
||||
}
|
||||
|
||||
/* Approximate brush with non-circular shape by changing the radius based on the angle. */
|
||||
float radius_factor = 1.0f;
|
||||
if (settings_->draw_angle_factor > 0.0f) {
|
||||
const float angle = settings_->draw_angle;
|
||||
const float2 angle_vec = float2(math::cos(angle), math::sin(angle));
|
||||
@@ -754,15 +761,13 @@ struct PaintOperationExecutor {
|
||||
1.0f - math::abs(math::dot(angle_vec, math::normalize(self.smoothed_pen_direction_)));
|
||||
|
||||
/* Influence is controlled by `draw_angle_factor`. */
|
||||
const float radius_factor = math::interpolate(
|
||||
1.0f, angle_factor, settings_->draw_angle_factor);
|
||||
radius_factor = math::interpolate(1.0f, angle_factor, settings_->draw_angle_factor);
|
||||
radius *= radius_factor;
|
||||
}
|
||||
|
||||
/* Overwrite last point if it's very close. */
|
||||
const bool is_first_sample = (curve_points.size() == 1);
|
||||
const float distance_px = math::distance(coords, prev_coords);
|
||||
constexpr float point_override_threshold_px = 2.0f;
|
||||
|
||||
if (distance_px < point_override_threshold_px) {
|
||||
self.accum_distance_ += distance_px;
|
||||
/* Don't move the first point of the stroke. */
|
||||
@@ -781,6 +786,12 @@ struct PaintOperationExecutor {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Adjust the first points radius based on the computed angle. */
|
||||
if (is_first_sample && settings_->draw_angle_factor > 0.0f) {
|
||||
drawing_->radii_for_write()[last_active_point] *= radius_factor;
|
||||
prev_radius = drawing_->radii()[last_active_point];
|
||||
}
|
||||
|
||||
/* Clamp the number of points within a pixel in screen space. */
|
||||
constexpr int max_points_per_pixel = 4;
|
||||
/* The value `brush_->spacing` is a percentage of the brush radius in pixels. */
|
||||
|
||||
Reference in New Issue
Block a user