diff options
Diffstat (limited to 'ink_stroke_modeler/internal/stylus_state_modeler.h')
-rw-r--r-- | ink_stroke_modeler/internal/stylus_state_modeler.h | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/ink_stroke_modeler/internal/stylus_state_modeler.h b/ink_stroke_modeler/internal/stylus_state_modeler.h new file mode 100644 index 0000000..a5b925f --- /dev/null +++ b/ink_stroke_modeler/internal/stylus_state_modeler.h @@ -0,0 +1,82 @@ +/* + * 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_INTERNAL_STYLUS_STATE_MODELER_H_ +#define INK_STROKE_MODELER_INTERNAL_STYLUS_STATE_MODELER_H_ + +#include <deque> +#include <ostream> + +#include "ink_stroke_modeler/internal/internal_types.h" +#include "ink_stroke_modeler/params.h" +#include "ink_stroke_modeler/types.h" + +namespace ink { +namespace stroke_model { + +// This class is used to model the state of the stylus for a given position, +// based on the state of the stylus at the original input points. +// +// The stylus is modeled by storing the last max_input_samples positions and +// states received via Update(); when queried, it treats the stored positions as +// a polyline, and finds the closest segment. The returned stylus state is a +// linear interpolation between the states associated with the endpoints of the +// segment, correcting angles to account for the "wraparound" that occurs at 0 +// and 2π. The value used for interpolation is based on how far along the +// segment the closest point lies. +// +// If Update() is called with a state in which a field (i.e. pressure, tilt, or +// orientation) has a negative value (indicating no information), then the +// results of Query() will be -1 for that field until Reset() is called. This is +// tracked independently for each field; e.g., if you pass in tilt = -1, then +// pressure and orientation will continue to be interpolated normally. +class StylusStateModeler { + public: + // Adds a position and state pair to the model. During stroke modeling, these + // values will be taken from the raw input. + void Update(Vec2 position, const StylusState &state); + + // Clear the model and reset. + void Reset(const StylusStateModelerParams ¶ms); + + // Query the model for the state at the given position. During stroke + // modeling, the position will be taken from the modeled input. + // + // If no Update() calls have been received since the last Reset(), this will + // return {.pressure = -1, .tilt = -1, .orientation = -1}. + StylusState Query(Vec2 position) const; + + private: + struct PositionAndState { + Vec2 position{0}; + StylusState state; + + PositionAndState(Vec2 position_in, const StylusState &state_in) + : position(position_in), state(state_in) {} + }; + + bool received_unknown_pressure_ = false; + bool received_unknown_tilt_ = false; + bool received_unknown_orientation_ = false; + + std::deque<PositionAndState> positions_and_states_; + StylusStateModelerParams params_; +}; + +} // namespace stroke_model +} // namespace ink + +#endif // INK_STROKE_MODELER_INTERNAL_STYLUS_STATE_MODELER_H_ |