blob: a25b971dc74a76c0919760ce820139f00375c1ed [file] [log] [blame]
/*
* 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_