17
17
#include < algorithm>
18
18
#include < cstddef>
19
19
#include < optional>
20
+ #include < type_traits>
20
21
#include < variant>
21
22
#include < vector>
22
23
23
24
#include " absl/cleanup/cleanup.h"
24
25
#include " absl/log/absl_check.h"
26
+ #include " absl/log/check.h"
25
27
#include " ink/brush/brush_family.h"
26
28
#include " ink/geometry/angle.h"
27
29
#include " ink/geometry/point.h"
@@ -67,41 +69,68 @@ void StrokeInputModeler::StartStroke(const BrushFamily::InputModel& input_model,
67
69
68
70
namespace {
69
71
72
+ // LINT.IfChange(input_model_types)
73
+
70
74
stroke_model::PositionModelerParams::LoopContractionMitigationParameters
71
- GetLoopContractionMitigationParameters (
75
+ MakeLoopContractionMitigationParameters (
72
76
const BrushFamily::InputModel& input_model, float stroke_unit_length) {
73
- stroke_model::PositionModelerParams::LoopContractionMitigationParameters
74
- params;
75
- if (std::holds_alternative<BrushFamily::SpringModelV2>(input_model)) {
76
- params.is_enabled = true ;
77
- params.speed_lower_bound =
78
- kDefaultLoopMitigationSpeedLowerBoundInCmPerSec / stroke_unit_length;
79
- params.speed_upper_bound =
80
- kDefaultLoopMitigationSpeedUpperBoundInCmPerSec / stroke_unit_length;
81
- params.interpolation_strength_at_speed_lower_bound =
82
- kDefaultLoopMitigationInterpolationStrengthAtSpeedLowerBound ;
83
- params.interpolation_strength_at_speed_upper_bound =
84
- kDefaultLoopMitigationInterpolationStrengthAtSpeedUpperBound ;
85
- params.min_speed_sampling_window =
86
- kDefaultLoopMitigationMinSpeedSamplingWindow ;
87
- params.min_discrete_speed_samples =
88
- kDefaultLoopMitigationMinDiscreteSpeedSamples ;
89
- } else if (std::holds_alternative<BrushFamily::SpringModelV1>(input_model)) {
90
- params.is_enabled = false ;
91
- }
92
- return params;
77
+ return std::visit (
78
+ [stroke_unit_length](auto && input_model)
79
+ // NOLINTNEXTLINE(whitespace/line_length)
80
+ -> stroke_model::PositionModelerParams::LoopContractionMitigationParameters {
81
+ using ModelType = std::decay_t <decltype (input_model)>;
82
+ if constexpr (std::is_same_v<ModelType, BrushFamily::SpringModelV2>) {
83
+ return {
84
+ .is_enabled = true ,
85
+ .speed_lower_bound =
86
+ kDefaultLoopMitigationSpeedLowerBoundInCmPerSec /
87
+ stroke_unit_length,
88
+ .speed_upper_bound =
89
+ kDefaultLoopMitigationSpeedUpperBoundInCmPerSec /
90
+ stroke_unit_length,
91
+ .interpolation_strength_at_speed_lower_bound =
92
+ kDefaultLoopMitigationInterpolationStrengthAtSpeedLowerBound ,
93
+ .interpolation_strength_at_speed_upper_bound =
94
+ kDefaultLoopMitigationInterpolationStrengthAtSpeedUpperBound ,
95
+ .min_speed_sampling_window =
96
+ kDefaultLoopMitigationMinSpeedSamplingWindow ,
97
+ .min_discrete_speed_samples =
98
+ kDefaultLoopMitigationMinDiscreteSpeedSamples };
99
+ } else if constexpr (std::is_same_v<ModelType,
100
+ BrushFamily::SpringModelV1>) {
101
+ return {.is_enabled = false };
102
+ }
103
+ },
104
+ input_model);
93
105
}
94
106
107
+ stroke_model::StylusStateModelerParams MakeStylusStateModelerParams (
108
+ const BrushFamily::InputModel& input_model) {
109
+ return std::visit (
110
+ [](auto && input_model) -> stroke_model::StylusStateModelerParams {
111
+ using ModelType = std::decay_t <decltype (input_model)>;
112
+ if constexpr (std::is_same_v<ModelType, BrushFamily::SpringModelV2>) {
113
+ return {.use_stroke_normal_projection = true ,
114
+ .min_input_samples = 10 ,
115
+ .min_sample_duration = stroke_model::Duration (0.04 )};
116
+ } else if constexpr (std::is_same_v<ModelType,
117
+ BrushFamily::SpringModelV1>) {
118
+ return {.max_input_samples = 10 ,
119
+ .use_stroke_normal_projection = false };
120
+ }
121
+ },
122
+ input_model);
123
+ }
124
+
125
+ // LINT.ThenChange(../../brush/brush_family.h:input_model_types)
126
+
95
127
void ResetStrokeModeler (stroke_model::StrokeModeler& stroke_modeler,
96
128
const BrushFamily::InputModel& input_model,
97
129
float brush_epsilon, float stroke_unit_length) {
98
130
// The minimum output rate was chosen to match legacy behavior, which was
99
131
// in turn chosen to upsample enough to produce relatively smooth-looking
100
132
// curves on 60 Hz touchscreens.
101
133
constexpr double kMinOutputRateHz = 180 ;
102
- stroke_model::PositionModelerParams::LoopContractionMitigationParameters
103
- loop_params = GetLoopContractionMitigationParameters (input_model,
104
- stroke_unit_length);
105
134
// We use the defaults for `PositionModelerParams` and
106
135
// `StylusStateModelerParams`.
107
136
ABSL_CHECK_OK (stroke_modeler.Reset (
@@ -112,15 +141,15 @@ void ResetStrokeModeler(stroke_model::StrokeModeler& stroke_modeler,
112
141
// We turn off loop contraction mitigation if the input model is not
113
142
// spring model v2.
114
143
.position_modeler_params = {.loop_contraction_mitigation_params =
115
- loop_params},
144
+ MakeLoopContractionMitigationParameters (
145
+ input_model, stroke_unit_length)},
116
146
// `brush_epsilon` is used for the stopping distance because once end of
117
147
// the stroke is with `brush_epsilon` of the final input, further changes
118
148
// are not considered visually distinct.
119
149
.sampling_params = {.min_output_rate = kMinOutputRateHz ,
120
150
.end_of_stroke_stopping_distance = brush_epsilon},
121
151
// If we use loop mitigation, we need to use the new projection method.
122
- .stylus_state_modeler_params = {.use_stroke_normal_projection =
123
- loop_params.is_enabled },
152
+ .stylus_state_modeler_params = MakeStylusStateModelerParams (input_model),
124
153
// We disable the internal predictor on the `StrokeModeler`,
125
154
// because it performs prediction after modeling. We wish to
126
155
// accept external un-modeled prediction, as in the case of
0 commit comments