Fix #124297: GPv3: Build modifier natural drawing speed fix #124350

Merged
Falk David merged 6 commits from ChengduLittleA/blender:fix-124297 into main 2024-07-16 10:26:50 +02:00
Showing only changes of commit 1a4e25616a - Show all commits

View File

@ -472,31 +472,30 @@ static float get_factor_from_draw_speed(const bke::CurvesGeometry &curves,
const VArray<float> delta_times = *attributes.lookup_or_default<float>(
"delta_time", bke::AttrDomain::Point, 0.0f);
Array<float> times(curves.points_num());
float previous_end_time = init_times[0];
float accumulated_delta_time = 0;
/* For the first stroke, the start time is 0. */
for (const int point : points_by_curve[0]) {
times[point] = delta_times[point];
}
accumulated_delta_time += times[points_by_curve[0].last()];
Array<float> start_times(curves.curves_num());
start_times[0] = 0;
filedescriptor marked this conversation as resolved Outdated

I think it's better if we pre-compute the start times (accounting for the maximum gap) for each curve first, and then go over the points.

Array<float> start_times(curves.curves_num());
start_times[0] = init_times[0];
float accumulated_shift_delta_time = 0.0f;
for (const int curve : curves.curves_range().drop_front(1)) {
    const float previous_start_time = start_times[curve - 1];
    const float previous_delta_time = delta_times[points_by_curve[curve - 1].last()];
    const float previous_end_time = previous_start_time + previous_delta_time;

    const float shifted_start_time = init_times[curve] - accumulated_shift_delta_time;
    const float gap_delta_time = math::min(shifted_start_time - previous_end_time, max_gap);

    start_times[curve] = previous_end_time + gap_delta_time;
    accumulated_shift_delta_time += math::max(shifted_start_time - start_times[curve], 0.0f);
}

The second loop then becomes much simpler. We can even return from there directly:

const float limit = time_elapsed * speed_fac;
for (const int curve : curves.curves_range()) {
    const float start_time = start_times[curve];
	for (const int point : points_by_curve[curve]) {
        if (start_time + delta_times[point] >= limit) {
            return math::clamp(float(point) / float(curves.points_num()), 0.0f, 1.0f);
        }
    }
}
    
I think it's better if we pre-compute the start times (accounting for the maximum gap) for each curve first, and then go over the points. ```cpp Array<float> start_times(curves.curves_num()); start_times[0] = init_times[0]; float accumulated_shift_delta_time = 0.0f; for (const int curve : curves.curves_range().drop_front(1)) { const float previous_start_time = start_times[curve - 1]; const float previous_delta_time = delta_times[points_by_curve[curve - 1].last()]; const float previous_end_time = previous_start_time + previous_delta_time; const float shifted_start_time = init_times[curve] - accumulated_shift_delta_time; const float gap_delta_time = math::min(shifted_start_time - previous_end_time, max_gap); start_times[curve] = previous_end_time + gap_delta_time; accumulated_shift_delta_time += math::max(shifted_start_time - start_times[curve], 0.0f); } ``` The second loop then becomes much simpler. We can even return from there directly: ```cpp const float limit = time_elapsed * speed_fac; for (const int curve : curves.curves_range()) { const float start_time = start_times[curve]; for (const int point : points_by_curve[curve]) { if (start_time + delta_times[point] >= limit) { return math::clamp(float(point) / float(curves.points_num()), 0.0f, 1.0f); } } } ```

Thanks for the suggestion. Let me see if I could make this work :D

Thanks for the suggestion. Let me see if I could make this work :D

start_times[0] needs to be 0 obviously and otherwise it seems to be working fine taking into account of gap limit. Thanks!

`start_times[0]` needs to be 0 obviously and otherwise it seems to be working fine taking into account of gap limit. Thanks!

Hm if start_times[0] = 0 then you need to set float accumulated_shift_delta_time = init_times[0]; so that all the strokes after are also shifted relative to the first stroke start time.

Hm if `start_times[0] = 0` then you need to set `float accumulated_shift_delta_time = init_times[0];` so that all the strokes after are also shifted relative to the first stroke start time.

Ah yes, this way the first stroke won't have a gap time

Ah yes, this way the first stroke won't have a gap time
float accumulated_shift_delta_time = 0.0f;
for (const int curve : curves.curves_range().drop_front(1)) {
const float start_time = math::min(init_times[curve] - previous_end_time, max_gap) +
accumulated_delta_time;
const float previous_start_time = start_times[curve - 1];
const float previous_delta_time = delta_times[points_by_curve[curve - 1].last()];
const float previous_end_time = previous_start_time + previous_delta_time;
const float shifted_start_time = init_times[curve] - accumulated_shift_delta_time;
const float gap_delta_time = math::min(shifted_start_time - previous_end_time, max_gap);
start_times[curve] = previous_end_time + gap_delta_time;
accumulated_shift_delta_time += math::max(shifted_start_time - start_times[curve], 0.0f);
}
const float limit = time_elapsed * speed_fac;
for (const int curve : curves.curves_range()) {
const float start_time = start_times[curve];
for (const int point : points_by_curve[curve]) {
times[point] = start_time + delta_times[point];
}
const float this_delta_time = delta_times[points_by_curve[curve].last()];
previous_end_time = init_times[curve] + this_delta_time;
accumulated_delta_time += this_delta_time;
}
for (const int point : curves.points_range()) {
const float limit = time_elapsed * speed_fac;
if (times[point] >= limit) {
return math::clamp(float(point) / float(curves.points_num()), 0.0f, 1.0f);
if (start_time + delta_times[point] >= limit) {
return math::clamp(float(point) / float(curves.points_num()), 0.0f, 1.0f);
}
}
}
return 1.0f;
}