aboutsummaryrefslogtreecommitdiff
path: root/ink_stroke_modeler/internal/stylus_state_modeler.h
diff options
context:
space:
mode:
Diffstat (limited to 'ink_stroke_modeler/internal/stylus_state_modeler.h')
-rw-r--r--ink_stroke_modeler/internal/stylus_state_modeler.h82
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 &params);
+
+ // 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_