diff --git a/ink_stroke_modeler/internal/wobble_smoother.cc b/ink_stroke_modeler/internal/wobble_smoother.cc index 7ae11fb..53fcc2d 100644 --- a/ink_stroke_modeler/internal/wobble_smoother.cc +++ b/ink_stroke_modeler/internal/wobble_smoother.cc @@ -14,8 +14,6 @@ #include "ink_stroke_modeler/internal/wobble_smoother.h" -#include - #include "ink_stroke_modeler/internal/utils.h" #include "ink_stroke_modeler/params.h" #include "ink_stroke_modeler/types.h" @@ -37,6 +35,8 @@ void WobbleSmoother::Reset(const WobbleSmootherParams& params, Vec2 position, } Vec2 WobbleSmoother::Update(Vec2 position, Time time) { + if (!params_.is_enabled) return position; + // The moving average acts as a low-pass signal filter, removing // high-frequency fluctuations in the position caused by the discrete nature // of the touch digitizer. To compensate for the distance between the average diff --git a/ink_stroke_modeler/internal/wobble_smoother_test.cc b/ink_stroke_modeler/internal/wobble_smoother_test.cc index dd39521..4bfeea7 100644 --- a/ink_stroke_modeler/internal/wobble_smoother_test.cc +++ b/ink_stroke_modeler/internal/wobble_smoother_test.cc @@ -108,6 +108,19 @@ TEST(WobbleSmootherTest, FastZigZag) { Vec2Eq({7.048, 3.048})); } +TEST(WobbleSmootherTest, NoOpIfNotEnabled) { + WobbleSmoother smoother; + smoother.Reset({.is_enabled = false, + .timeout = Duration(10), + .speed_floor = 1, + .speed_ceiling = 5}, + {0, 0}, Time(0)); + EXPECT_THAT(smoother.Update({.1, 0}, Time(1)), Vec2Eq({.1, 0})); + EXPECT_THAT(smoother.Update({.2, 0}, Time(2)), Vec2Eq({.2, 0})); + EXPECT_THAT(smoother.Update({.3, 0}, Time(3)), Vec2Eq({.3, 0})); + EXPECT_THAT(smoother.Update({.4, 0}, Time(4)), Vec2Eq({.4, 0})); +} + TEST(WobbleSmootherTest, SaveAndRestore) { WobbleSmoother filter; filter.Reset(kDefaultParams, {1, 2}, Time{5}); diff --git a/ink_stroke_modeler/params.cc b/ink_stroke_modeler/params.cc index 925ffc6..ee3b2df 100644 --- a/ink_stroke_modeler/params.cc +++ b/ink_stroke_modeler/params.cc @@ -87,6 +87,8 @@ absl::Status ValidateStylusStateModelerParams( } absl::Status ValidateWobbleSmootherParams(const WobbleSmootherParams& params) { + if (!params.is_enabled) return absl::OkStatus(); + RETURN_IF_ERROR(ValidateGreaterThanOrEqualToZero( params.timeout.Value(), "WobbleSmootherParams::timeout")); RETURN_IF_ERROR(ValidateGreaterThanOrEqualToZero( diff --git a/ink_stroke_modeler/params.h b/ink_stroke_modeler/params.h index c988018..d5006ba 100644 --- a/ink_stroke_modeler/params.h +++ b/ink_stroke_modeler/params.h @@ -99,6 +99,11 @@ struct StylusStateModelerParams { // These parameters are used for applying smoothing to the input to reduce // wobble in the prediction. struct WobbleSmootherParams { + // If true, the wobble smoothing will be applied to the stroke. If false, the + // wobble smoothing step will be skipped, and the remainder of the parameters + // in the struct will be ignored. + bool is_enabled = true; + // The length of the window over which the moving average of speed and // position are calculated. // diff --git a/ink_stroke_modeler/params_test.cc b/ink_stroke_modeler/params_test.cc index 74c3c49..3036bdc 100644 --- a/ink_stroke_modeler/params_test.cc +++ b/ink_stroke_modeler/params_test.cc @@ -134,6 +134,14 @@ TEST(ParamsTest, ValidateWobbleSmootherParams) { {.timeout = Duration(0), .speed_floor = 0, .speed_ceiling = 0}) .ok()); + // This is valid because `is_enabled` is false; otherwise, this would not be a + // valid configuration. + EXPECT_TRUE(ValidateWobbleSmootherParams({.is_enabled = false, + .timeout = Duration(-5), + .speed_floor = -3, + .speed_ceiling = -4}) + .ok()); + EXPECT_EQ(ValidateWobbleSmootherParams( {.timeout = Duration(-1), .speed_floor = 2, .speed_ceiling = 5}) .code(), diff --git a/ink_stroke_modeler/stroke_modeler_fuzz_test.cc b/ink_stroke_modeler/stroke_modeler_fuzz_test.cc index 067613d..b8d2384 100644 --- a/ink_stroke_modeler/stroke_modeler_fuzz_test.cc +++ b/ink_stroke_modeler/stroke_modeler_fuzz_test.cc @@ -23,9 +23,9 @@ fuzztest::Domain