complete stroke direction fix

This commit is contained in:
2019-11-25 01:48:18 +01:00
parent 423df3b92d
commit 9be704a26f
2 changed files with 47 additions and 28 deletions

View File

@@ -55,30 +55,27 @@ std::vector<StrokeSample> Stroke::compute_samples()
{
std::vector<StrokeSample> samples;
auto dirs = m_interp_dir.compute();
m_dirs_cache.insert(m_dirs_cache.end(), dirs.begin(), dirs.end());
auto points = m_interp_main.compute();
//if (!dirs.empty() && !points.empty())
{
LOG("dirs %f - points %f", m_interp_dir.dist, m_interp_main.dist);
}
int dir_i = 0;
for (const auto& kp : points)
{
for (; m_dir_i < m_dirs_cache.size() && (kp.dist >= m_dirs_cache[m_dir_i].dist || !m_dir_valid); m_dir_i++)
for (; need_dir() && dir_i < dirs.size() && (kp.dist >= dirs[dir_i].dist || !m_dir_valid); dir_i++)
{
m_dir_angle = -glm::orientedAngle(-m_dirs_cache[m_dir_i].dir, m_dir_ref);
m_dir_angle = -glm::orientedAngle(-dirs[dir_i].dir, m_dir_ref);
if (m_dir_angle > glm::radians(120.f) || !m_dir_valid)
{
auto old_dir = m_dir_ref;
m_dir_ref = -m_dirs_cache[m_dir_i].dir;
m_dir_ref = -dirs[dir_i].dir;
m_dir_ref_angle = -glm::orientedAngle(m_dir_ref, { 1, 0 });
m_dir_angle = -glm::orientedAngle(-m_dirs_cache[m_dir_i].dir, m_dir_ref);
m_dir_angle = -glm::orientedAngle(-dirs[dir_i].dir, m_dir_ref);
auto angle_diff = -glm::orientedAngle(m_dir_ref, old_dir);
for (int i = 0; i < m_direction.m_count; i++)
m_direction.m_vec[i] -= angle_diff;
}
if (glm::abs(m_direction.average() - m_dir_angle) > glm::radians(120.f))
m_direction.clear();
if (!m_dir_valid)
m_dir_init = m_dir_angle + m_dir_ref_angle;
m_dir_valid = true;
}
auto s = randomize_sample(kp.pos, kp.pressure, m_dir_angle);
@@ -89,6 +86,10 @@ std::vector<StrokeSample> Stroke::compute_samples()
m_direction.add(m_dir_angle);
s.angle += m_direction.average() + m_dir_ref_angle;
}
else if (m_brush->m_tip_angle_init)
{
s.angle += m_dir_init;
}
m_prev_sample = s;
samples.push_back(s);
}
@@ -204,9 +205,14 @@ std::vector<StrokeSample> Stroke::compute_samples_old()
}
bool Stroke::has_sample()
{
//return m_keypoints.size() < 2 ? false : // no keypoints
// (m_keypoints.back().dist > (m_dist + m_step)); // check if next kp is closer than spacing
return m_interp_main.ready() && m_interp_dir.ready_first;
return m_interp_main.ready() && (m_interp_dir.ready_first || !need_dir());
}
bool Stroke::need_dir() const noexcept
{
return m_brush->m_tip_angle_follow ||
m_brush->m_tip_angle_init ||
m_brush->m_jitter_angle > 0;
}
void Stroke::reset(bool clear_keypoints /*= false*/)
@@ -217,8 +223,6 @@ void Stroke::reset(bool clear_keypoints /*= false*/)
m_dir_dist = 0;
m_last_kp = 0;
m_dist = 0.f;
m_dir_i = 0;
m_dirs_cache.clear();
if (clear_keypoints)
m_keypoints.clear();
m_interp_main.reset(clear_keypoints);
@@ -246,8 +250,6 @@ void Stroke::add_point(glm::vec3 pos, float pressure)
m_step = glm::max(0.5f, m_brush->m_tip_spacing * size * App::I->zoom * pressure);
}
float dist = m_keypoints.empty() ? m_step :
m_keypoints.back().dist + glm::distance(m_keypoints.back().pos, pos);
if (m_keypoints.empty())
m_prev_sample = randomize_sample(pos, pressure, 0);
else if (m_keypoints.back().pos == pos)
@@ -255,7 +257,7 @@ void Stroke::add_point(glm::vec3 pos, float pressure)
Keypoint kp;
kp.pos = pos;
kp.pressure = pressure;
kp.dist = dist;
kp.dist = 0;
m_keypoints.push_back(kp);
m_interp_main.add(kp);
@@ -263,8 +265,6 @@ void Stroke::add_point(glm::vec3 pos, float pressure)
}
void Stroke::start(const std::shared_ptr<Brush>& brush)
{
m_dir_i = 0;
m_dirs_cache.clear();
m_hold_points.clear();
m_curve = 0.f;
m_direction.clear();
@@ -295,8 +295,8 @@ void Stroke::start(const std::shared_ptr<Brush>& brush)
m_direction.resize(std::max<int>(1, m_brush->m_tip_angle_smooth * 200.f / m_step));
prng.seed(0);
m_interp_main = SamplesInterpolator(m_step);
m_interp_dir = SamplesInterpolator(std::max(4.f, m_step));
m_interp_main = SamplesInterpolator(m_step, false);
m_interp_dir = SamplesInterpolator(std::max(4.f, m_step), need_dir());
}
bool Brush::load_tip(const std::string& path, const std::string& thumb)
@@ -658,12 +658,14 @@ void Brush::write(BinaryStreamWriter& w) const
//////////////////////////////////////////////////////////////////////////
Stroke::SamplesInterpolator::SamplesInterpolator(float sp) noexcept
Stroke::SamplesInterpolator::SamplesInterpolator(float sp, bool compute_dir) noexcept
{
spacing = sp;
dist = 0;
first = true;
ready_first = false;
calc_dir = compute_dir;
initial_kp_done = false;
}
Stroke::SamplesInterpolator::SamplesInterpolator() noexcept
@@ -672,6 +674,8 @@ Stroke::SamplesInterpolator::SamplesInterpolator() noexcept
dist = 0;
first = true;
ready_first = false;
calc_dir = false;
initial_kp_done = false;
}
void Stroke::SamplesInterpolator::add(const Keypoint& p) noexcept
@@ -688,8 +692,8 @@ void Stroke::SamplesInterpolator::add(const Keypoint& p) noexcept
bool Stroke::SamplesInterpolator::ready() const noexcept
{
return keypoints.size() > 1 &&
glm::distance(last.pos, keypoints.back().pos) > spacing;
return keypoints.size() > 0 &&
(glm::distance(last.pos, keypoints.back().pos) > spacing || !calc_dir);
}
void Stroke::SamplesInterpolator::reset(bool clear_keypoints) noexcept
@@ -697,6 +701,7 @@ void Stroke::SamplesInterpolator::reset(bool clear_keypoints) noexcept
dist = 0;
if (clear_keypoints || keypoints.empty())
{
initial_kp_done = false;
ready_first = false;
first = true;
keypoints.clear();
@@ -710,6 +715,11 @@ void Stroke::SamplesInterpolator::reset(bool clear_keypoints) noexcept
std::vector<Stroke::Keypoint> Stroke::SamplesInterpolator::compute() noexcept
{
std::vector<Stroke::Keypoint> ret;
if (!calc_dir && last.dist == 0 && !initial_kp_done)
{
initial_kp_done = true;
ret.push_back(last);
}
for (const auto& kp : keypoints)
{
float d = glm::distance(last.pos, kp.pos);
@@ -729,8 +739,16 @@ std::vector<Stroke::Keypoint> Stroke::SamplesInterpolator::compute() noexcept
ret.push_back(p);
}
if (!ret.empty())
{
if (last.dist == 0 && calc_dir && !initial_kp_done)
{
last.dir = ret.front().dir;
ret.insert(ret.begin(), last);
initial_kp_done = true;
}
last = ret.back();
}
}
if (!ret.empty())
keypoints.clear();
return ret;

View File

@@ -157,12 +157,14 @@ public:
{
Keypoint last;
std::vector<Keypoint> keypoints;
bool initial_kp_done;
bool ready_first;
bool first;
float spacing;
float dist;
bool calc_dir;
SamplesInterpolator() noexcept;
SamplesInterpolator(float sp) noexcept;
SamplesInterpolator(float sp, bool compute_dir) noexcept;
void add(const Keypoint& p) noexcept;
bool ready() const noexcept;
void reset(bool clear_keypoints) noexcept;
@@ -171,8 +173,6 @@ public:
int m_layer = 0;
int m_dir_kp = 0;
bool m_dir_valid = false;
std::vector<Keypoint> m_dirs_cache;
int m_dir_i = 0;
glm::vec2 m_dir_ref = { 1, 0 };
float m_dir_ref_angle = 0;
float m_dir_dist = 0;
@@ -200,6 +200,7 @@ public:
void add_point(glm::vec3 pos, float pressure);
void reset(bool clear_keypoints = false);
bool has_sample();
bool need_dir() const noexcept;
std::vector<StrokeSample> compute_samples();
std::vector<StrokeSample> compute_samples_old();
StrokeSample randomize_sample(const glm::vec3& pos, float pressure, float curve_angle);