Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add position to StylusState in preparation #135

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions ink_stroke_modeler/internal/internal_types.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ std::string ToFormattedString(const TipState &tip_state) {

std::string ToFormattedString(const StylusState &stylus_state) {
return absl::StrFormat(
"<StylusState: pressure: %v, tilt: %v, orientation: %v>",
stylus_state.pressure, stylus_state.tilt, stylus_state.orientation);
"<StylusState: pressure: %v, tilt: %v, orientation: %v, "
"projected_position: %v>",
stylus_state.pressure, stylus_state.tilt, stylus_state.orientation,
stylus_state.projected_position);
}

} // namespace stroke_model
Expand Down
4 changes: 3 additions & 1 deletion ink_stroke_modeler/internal/internal_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct StylusState {
float pressure = -1;
float tilt = -1;
float orientation = -1;
Vec2 projected_position = {0, 0};
};

bool operator==(const StylusState& lhs, const StylusState& rhs);
Expand All @@ -62,7 +63,8 @@ void AbslStringify(Sink& sink, const StylusState& stylus_state) {

inline bool operator==(const StylusState& lhs, const StylusState& rhs) {
return lhs.pressure == rhs.pressure && lhs.tilt == rhs.tilt &&
lhs.orientation == rhs.orientation;
lhs.orientation == rhs.orientation &&
lhs.projected_position == rhs.projected_position;
}

} // namespace stroke_model
Expand Down
11 changes: 7 additions & 4 deletions ink_stroke_modeler/internal/internal_types_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ TEST(InternalTypesTest, TipStateString) {
}

TEST(InternalTypesTest, StylusStateEquals) {
EXPECT_EQ((StylusState{0.1, 0.2, 0.3}), (StylusState{0.1, 0.2, 0.3}));
EXPECT_FALSE((StylusState{0.1, 0.2, 0.3}) == (StylusState{0.1, 0.02, 0.3}));
EXPECT_EQ((StylusState{0.1, 0.2, 0.3, {1, 2}}),
(StylusState{0.1, 0.2, 0.3, {1, 2}}));
EXPECT_FALSE((StylusState{0.1, 0.2, 0.3, {1, 2}}) ==
(StylusState{0.1, 0.02, 0.3, {1, 2}}));
}

TEST(InternalTypesTest, StylusStateString) {
EXPECT_EQ(absl::StrFormat("%v", StylusState{0.1, 0.2, 0.3}),
"<StylusState: pressure: 0.1, tilt: 0.2, orientation: 0.3>");
EXPECT_EQ(absl::StrFormat("%v", StylusState{0.1, 0.2, 0.3, {1, 2}}),
"<StylusState: pressure: 0.1, tilt: 0.2, orientation: 0.3, "
"projected_position: (1, 2)>");
}

} // namespace
Expand Down
47 changes: 22 additions & 25 deletions ink_stroke_modeler/internal/stylus_state_modeler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
namespace ink {
namespace stroke_model {

void StylusStateModeler::Update(Vec2 position, const StylusState &state) {
void StylusStateModeler::Update(const StylusState &state) {
// Possibly NaN should be prohibited in ValidateInput, but due to current
// consumers, that can't be tightened for these values currently.
if (state.pressure < 0 || std::isnan(state.pressure)) {
Expand All @@ -38,24 +38,17 @@ void StylusStateModeler::Update(Vec2 position, const StylusState &state) {
state_.received_unknown_orientation = true;
}

if (state_.received_unknown_pressure && state_.received_unknown_tilt &&
state_.received_unknown_orientation) {
// We've stopped tracking all fields, so there's no need to keep updating.
state_.positions_and_stylus_states.clear();
return;
}

state_.positions_and_stylus_states.push_back({position, state});
state_.stylus_states.push_back(state);

if (params_.max_input_samples < 0 ||
state_.positions_and_stylus_states.size() >
state_.stylus_states.size() >
static_cast<unsigned int>(params_.max_input_samples)) {
state_.positions_and_stylus_states.pop_front();
state_.stylus_states.pop_front();
}
}

void StylusStateModeler::Reset(const StylusStateModelerParams &params) {
state_.positions_and_stylus_states.clear();
state_.stylus_states.clear();
state_.received_unknown_pressure = false;
state_.received_unknown_tilt = false;
state_.received_unknown_orientation = false;
Expand All @@ -64,16 +57,19 @@ void StylusStateModeler::Reset(const StylusStateModelerParams &params) {
}

StylusState StylusStateModeler::Query(Vec2 position) const {
if (state_.positions_and_stylus_states.empty())
return {.pressure = -1, .tilt = -1, .orientation = -1};
if (state_.stylus_states.empty())
return {.pressure = -1,
.tilt = -1,
.orientation = -1,
.projected_position = {0, 0}};

int closest_segment_index = -1;
float min_distance = std::numeric_limits<float>::infinity();
float interp_value = 0;
for (decltype(state_.positions_and_stylus_states.size()) i = 0;
i < state_.positions_and_stylus_states.size() - 1; ++i) {
const Vec2 segment_start = state_.positions_and_stylus_states[i].position;
const Vec2 segment_end = state_.positions_and_stylus_states[i + 1].position;
for (decltype(state_.stylus_states.size()) i = 0;
i < state_.stylus_states.size() - 1; ++i) {
const Vec2 segment_start = state_.stylus_states[i].projected_position;
const Vec2 segment_end = state_.stylus_states[i + 1].projected_position;
float param = NearestPointOnSegment(segment_start, segment_end, position);
float distance =
Distance(position, Interp(segment_start, segment_end, param));
Expand All @@ -85,17 +81,16 @@ StylusState StylusStateModeler::Query(Vec2 position) const {
}

if (closest_segment_index < 0) {
const auto &state = state_.positions_and_stylus_states.front().state;
const auto &state = state_.stylus_states.front();
return {.pressure = state_.received_unknown_pressure ? -1 : state.pressure,
.tilt = state_.received_unknown_tilt ? -1 : state.tilt,
.orientation =
state_.received_unknown_orientation ? -1 : state.orientation};
state_.received_unknown_orientation ? -1 : state.orientation,
.projected_position = state.projected_position};
}

auto from_state =
state_.positions_and_stylus_states[closest_segment_index].state;
auto to_state =
state_.positions_and_stylus_states[closest_segment_index + 1].state;
auto from_state = state_.stylus_states[closest_segment_index];
auto to_state = state_.stylus_states[closest_segment_index + 1];
return StylusState{
.pressure =
state_.received_unknown_pressure
Expand All @@ -107,7 +102,9 @@ StylusState StylusStateModeler::Query(Vec2 position) const {
.orientation = state_.received_unknown_orientation
? -1
: InterpAngle(from_state.orientation,
to_state.orientation, interp_value)};
to_state.orientation, interp_value),
.projected_position = Interp(from_state.projected_position,
to_state.projected_position, interp_value)};
}

void StylusStateModeler::Save() {
Expand Down
13 changes: 2 additions & 11 deletions ink_stroke_modeler/internal/stylus_state_modeler.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#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"
Expand Down Expand Up @@ -47,7 +46,7 @@ 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);
void Update(const StylusState &state);

// Clear the model and reset.
void Reset(const StylusStateModelerParams &params);
Expand All @@ -68,20 +67,12 @@ class StylusStateModeler {
void Restore();

private:
struct PositionAndStylusState {
Vec2 position{0};
StylusState state;

PositionAndStylusState(Vec2 position_in, const StylusState &state_in)
: position(position_in), state(state_in) {}
};

struct ModelerState {
bool received_unknown_pressure = false;
bool received_unknown_tilt = false;
bool received_unknown_orientation = false;

std::deque<PositionAndStylusState> positions_and_stylus_states;
std::deque<StylusState> stylus_states;
};

ModelerState state_;
Expand Down
Loading