rename jitter spread to scatter, dual brush scatter mode single and both axis, fix scatter to follow the direction
This commit is contained in:
@@ -126,7 +126,7 @@ bool BrushMesh::create()
|
||||
|
||||
return true;
|
||||
}
|
||||
StrokeSample Stroke::randomize_sample(const glm::vec3& pos, float pressure, float curve_angle)
|
||||
StrokeSample Stroke::randomize_sample(const glm::vec3& pos, float pressure, float dir_angle)
|
||||
{
|
||||
auto rnd_nor = [&] { return float((double)prng() / (double)prng.max()); }; // normalized [0, +1]
|
||||
auto rnd_neg = [&] { return float((double)prng() / (double)prng.max() * 2.0 - 1.0); }; // normalized [-1, +1]
|
||||
@@ -140,6 +140,8 @@ StrokeSample Stroke::randomize_sample(const glm::vec3& pos, float pressure, floa
|
||||
float size = glm::min(m_brush->m_tip_size / glm::tan(glm::radians(m_camera.fov * 0.5f)), m_max_size);
|
||||
float randflipx = m_brush->m_tip_randflipx ? rnd_bneg() : 1.f;
|
||||
float randflipy = m_brush->m_tip_randflipy ? rnd_bneg() : 1.f;
|
||||
glm::vec2 scatter_axis = m_brush->m_jitter_scatter_bothaxis ? glm::vec2(1.f, 1.f) : glm::vec2(0.f, 1.f);
|
||||
auto scatter_scale = glm::vec3(scatter_axis * glm::orientate2(-dir_angle), 1.f);
|
||||
|
||||
StrokeSample s;
|
||||
s.scale.x = m_brush->m_tip_scale.x * randflipx * (m_brush->m_tip_flipx ? -1.f : 1.f) *
|
||||
@@ -147,9 +149,9 @@ StrokeSample Stroke::randomize_sample(const glm::vec3& pos, float pressure, floa
|
||||
s.scale.y = m_brush->m_tip_scale.y * randflipy * (m_brush->m_tip_flipy ? -1.f : 1.f) *
|
||||
(m_brush->m_tip_aspect > 0.5 ? 1.f - (m_brush->m_tip_aspect - .5f) * 2.f : 1.f);
|
||||
s.origin = pos;
|
||||
s.angle = -curve_angle + (m_brush->m_tip_angle + rnd_neg() * m_brush->m_jitter_angle) * (float)(M_PI * 2.0);
|
||||
s.angle = (m_brush->m_tip_angle + rnd_neg() * m_brush->m_jitter_angle) * (float)(M_PI * 2.0);
|
||||
s.size = size * (1.f - rnd_nor() * m_brush->m_jitter_scale) * size_dyn;
|
||||
s.pos = pos + (rnd_vec() * m_brush->m_jitter_spread * s.size);
|
||||
s.pos = pos + (scatter_scale * rnd_vec() * m_brush->m_jitter_scatter * s.size);
|
||||
s.flow = m_brush->m_tip_flow * (1.f - rnd_nor() * m_brush->m_jitter_flow) * flow_dyn;
|
||||
s.opacity = m_brush->m_tip_opacity * (1.f - rnd_nor() * m_brush->m_jitter_opacity) * opacity_dyn;
|
||||
auto hsv = convert_rgb2hsv(m_brush->m_tip_color);
|
||||
@@ -179,43 +181,49 @@ std::vector<StrokeSample> Stroke::compute_samples()
|
||||
auto pos = glm::lerp(A.pos, B.pos, t);
|
||||
float pressure = glm::lerp(A.pressure, B.pressure, t);
|
||||
|
||||
auto s = randomize_sample(pos, pressure, 0);
|
||||
if (m_dir_dist > m_dir_step && m_last_kp != m_dir_kp)
|
||||
{
|
||||
glm::vec2 v = glm::normalize(m_keypoints[m_last_kp].pos - m_keypoints[m_dir_kp].pos);
|
||||
m_dir_angle = -glm::orientedAngle(v, m_dir_ref);
|
||||
if (m_brush->m_tip_angle_smooth > 0 && (glm::abs(m_dir_angle) > glm::radians(30.f) || !m_dir_valid))
|
||||
{
|
||||
if (glm::abs(m_dir_angle) > glm::radians(100.f))
|
||||
{
|
||||
//LOG("BIG ANGLE");
|
||||
m_direction.clear();
|
||||
}
|
||||
|
||||
auto old_dir = m_dir_ref;
|
||||
m_dir_ref = v;
|
||||
m_dir_ref_angle = -glm::orientedAngle(m_dir_ref, { 1, 0 });
|
||||
m_dir_angle = 0;
|
||||
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;
|
||||
}
|
||||
m_dir_kp = m_last_kp;
|
||||
m_dir_dist = 0;
|
||||
m_dir_valid = true;
|
||||
}
|
||||
|
||||
bool need_dir = false;
|
||||
need_dir |= m_brush->m_tip_angle_follow;
|
||||
need_dir |= m_brush->m_tip_angle_init;
|
||||
need_dir |= m_brush->m_jitter_angle > 0;
|
||||
|
||||
// angle is not ready yet
|
||||
if (need_dir && !m_dir_valid)
|
||||
continue;
|
||||
|
||||
auto s = randomize_sample(pos, pressure, m_dir_angle + m_dir_ref_angle);
|
||||
if (s.valid())
|
||||
{
|
||||
if (m_brush->m_tip_angle_follow || (!m_dir_valid && m_brush->m_tip_angle_init))
|
||||
{
|
||||
if (m_dir_dist > m_dir_step && m_last_kp != m_dir_kp)
|
||||
{
|
||||
glm::vec2 v = glm::normalize(m_keypoints[m_last_kp].pos - m_keypoints[m_dir_kp].pos);
|
||||
m_dir_angle = -glm::orientedAngle(v, m_dir_ref);
|
||||
if (m_brush->m_tip_angle_smooth > 0 && (glm::abs(m_dir_angle) > glm::radians(30.f) || !m_dir_valid))
|
||||
{
|
||||
if (glm::abs(m_dir_angle) > glm::radians(100.f))
|
||||
{
|
||||
//LOG("BIG ANGLE");
|
||||
m_direction.clear();
|
||||
}
|
||||
|
||||
auto old_dir = m_dir_ref;
|
||||
m_dir_ref = v;
|
||||
m_dir_ref_angle = -glm::orientedAngle(m_dir_ref, { 1, 0 });
|
||||
m_dir_angle = 0;
|
||||
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;
|
||||
}
|
||||
m_dir_kp = m_last_kp;
|
||||
m_dir_dist = 0;
|
||||
m_dir_valid = true;
|
||||
}
|
||||
|
||||
if (m_dir_valid)
|
||||
{
|
||||
m_direction.add(m_dir_angle);
|
||||
s.angle += m_direction.average() + m_dir_ref_angle;
|
||||
m_prev_sample = s;
|
||||
samples.push_back(s);
|
||||
}
|
||||
m_direction.add(m_dir_angle);
|
||||
s.angle += m_direction.average() + m_dir_ref_angle;
|
||||
m_prev_sample = s;
|
||||
samples.push_back(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user