/* * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INK_STROKE_MODELER_STROKE_MODELER_H_ #define INK_STROKE_MODELER_STROKE_MODELER_H_ #include <memory> #include <vector> #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/types/optional.h" #include "ink_stroke_modeler/internal/position_modeler.h" #include "ink_stroke_modeler/internal/prediction/input_predictor.h" #include "ink_stroke_modeler/internal/stylus_state_modeler.h" #include "ink_stroke_modeler/internal/wobble_smoother.h" #include "ink_stroke_modeler/params.h" #include "ink_stroke_modeler/types.h" namespace ink { namespace stroke_model { // This class models a stroke from a raw input stream. The modeling is performed // in several stages, which are delegated to component classes: // - Wobble Smoothing: Dampens high-frequency noise from quantization error. // - Position Modeling: Models the pen tip as a mass, connected by a spring, to // a moving anchor. // - Stylus State Modeling: Constructs stylus states for modeled positions by // interpolating over the raw input. // // Additionally, this class provides prediction of the modeled stroke. // // StrokeModeler is completely unit-agnostic. That is, it doesn't matter what // units or coordinate-system the input is given in; the output will be given in // the same coordinate-system and units. class StrokeModeler { public: // Clears any in-progress stroke, and initializes (or re-initializes) the // model with the given parameters. Returns an error if the parameters are // invalid. absl::Status Reset(const StrokeModelParams &stroke_model_params); // Updates the model with a raw input, returning the generated results. Any // previously generated results are stable, i.e. any previously returned // Results are still valid. // // Returns an error if the the model has not yet been initialized (via Reset) // or if the input stream is malformed (e.g decreasing time, Up event before // Down event). // // If this does not return an error, the result will contain at least one // Result, and potentially more than one if the inputs are slower than // the minimum output rate. absl::StatusOr<std::vector<Result>> Update(const Input &input); // Model the given input prediction without changing the internal model state. // // Returns an error if the the model has not yet been initialized (via Reset), // or if there is no stroke in progress. The output is limited to results // where the predictor has sufficient confidence, absl::StatusOr<std::vector<Result>> Predict() const; private: absl::StatusOr<std::vector<Result>> ProcessDownEvent(const Input &input); absl::StatusOr<std::vector<Result>> ProcessMoveEvent(const Input &input); absl::StatusOr<std::vector<Result>> ProcessUpEvent(const Input &input); std::unique_ptr<InputPredictor> predictor_; absl::optional<StrokeModelParams> stroke_model_params_; WobbleSmoother wobble_smoother_; PositionModeler position_modeler_; StylusStateModeler stylus_state_modeler_; struct InputAndCorrectedPosition { Input input; Vec2 corrected_position{0}; }; absl::optional<InputAndCorrectedPosition> last_input_; }; } // namespace stroke_model } // namespace ink #endif // INK_STROKE_MODELER_STROKE_MODELER_H_