add wet parameter, fix selection mask modes

This commit is contained in:
2017-10-27 00:47:48 +01:00
parent b40a5b656b
commit c8e115774f
12 changed files with 336 additions and 156 deletions

View File

@@ -6,6 +6,7 @@
#include "shader.h"
#include "node_canvas.h"
#include "app.h"
#include "util.h"
NodeCanvas* CanvasMode::node;
ui::Canvas* CanvasMode::canvas;
@@ -378,145 +379,6 @@ void CanvasModeMaskFree::leave()
// m_points.clear();
}
int SegmentCount = 0;
std::vector<ui::Shape::vertex_t> CanvasModeMaskFree::triangulate(const std::vector<std::shared_ptr<p2t::Point>>& points)
{
struct Segment
{
std::shared_ptr<p2t::Point> a = nullptr;
std::shared_ptr<p2t::Point> b = nullptr;
Segment* prev = nullptr;
std::shared_ptr<Segment> next = nullptr;
bool end = false;
Segment()
{
SegmentCount++;
}
~Segment()
{
SegmentCount--;
}
};
std::shared_ptr<Segment> root = std::make_shared<Segment>();
std::shared_ptr<Segment> node = root;
for (int i = 0; i < points.size(); i++)
{
node->a = points[i];
if (i == points.size() - 1)
{
node->b = points[0];
node->next = root;
node->end = true;
root->prev = node.get();
}
else
{
node->b = points[i + 1];
node->next = std::make_shared<Segment>();
node->next->prev = node.get();
}
node = node->next;
}
node = root;
std::stack<std::shared_ptr<Segment>> todo;
std::vector<std::shared_ptr<Segment>> polys;
todo.push(root);
while (!todo.empty())
{
node = todo.top();
todo.pop();
polys.push_back(node);
while (node)
{
std::shared_ptr<Segment> other = node->next;
while (other)
{
if (*node->a == *other->a || *node->a == *other->b ||
*node->b == *other->a || *node->b == *other->b)
{
other = other->end ? nullptr : other->next;
continue;
}
glm::vec2 s0a(node->a->x, node->a->y);
glm::vec2 s0b(node->b->x, node->b->y);
glm::vec2 s1a(other->a->x, other->a->y);
glm::vec2 s1b(other->b->x, other->b->y);
glm::vec2 is;
if (segments_intersect(s0a, s0b, s1a, s1b, is))
{
auto p = std::make_shared<p2t::Point>(is.x, is.y);
auto poly_root = std::make_shared<Segment>();
poly_root->a = p;
poly_root->b = node->b;
poly_root->next = node->next;
todo.push(poly_root);
other->a = p;
node->b = p;
auto poly_end = std::make_shared<Segment>();
poly_end->a = other->prev->b;
poly_end->b = p;
poly_end->end = true;
poly_end->prev = other->prev;
other->prev->next = poly_end;
other->prev = node.get();
node->next = other;
break;
}
other = other->end ? nullptr : other->next;
}
node = node->end ? nullptr : node->next;
}
}
std::vector<ui::Shape::vertex_t> vertices;
for (auto poly : polys)
{
std::vector<p2t::Point*> outline;
node = poly;
while (node)
{
outline.push_back(new p2t::Point(*node->a));
auto current = node;
node = node->end ? nullptr : node->next;
current->next = nullptr;
}
LOG("poly %ld", outline.size());
if (outline.size() > 2)
{
p2t::CDT* cdt = new p2t::CDT(outline);
cdt->Triangulate();
auto tr = cdt->GetTriangles();
for (auto t : tr)
{
ui::Shape::vertex_t vertex;
for (int i = 0; i < 3; i++)
{
auto p = t->GetPoint(i);
glm::vec3 ro, rd, hit_o, hit_d;
glm::vec2 hit_fb;
int plane_id;
if (canvas->point_trace({p->x, p->y}, ro, rd, hit_o, hit_fb, hit_d, plane_id))
{
m_dirty_planes[plane_id]++;
vertex.pos = glm::vec4(hit_o, 1);
vertices.push_back(vertex);
}
}
}
delete cdt;
}
for (auto p : outline)
delete p;
}
return vertices;
}
void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
{
static glm::vec2 oldpos;
@@ -551,8 +413,8 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
std::vector<std::shared_ptr<p2t::Point>> points;
for (int i = 0; i < (int)m_points2d.size() - 1; i++)
points.emplace_back(std::make_shared<p2t::Point>(m_points2d[i].x, m_points2d[i].y));
auto v = triangulate(points);
LOG("leaked segments: %d", SegmentCount);
auto v = canvas->triangulate(points);
canvas->project2Dpoints(v);
LOG("%d points", (int)v.size());
m_shape.update_vertices(v.data(), (int)v.size());
@@ -567,7 +429,14 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
m_shape.draw_fill();
};
canvas->draw_objects(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), canvas->m_smask);
m_points.clear();
//m_points.clear();
// close the path
m_points.push_back(m_points[m_points.size() - 2]);
m_points.push_back(m_points.front());
canvas->project2Dpoints(m_points);
// reset m_shape to contour rendering
m_shape.update_vertices(m_points.data(), (int)m_points.size());
}
}
else
@@ -593,7 +462,7 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
oldvec = v;
if (acc > 0.001) // angle change tollerance
{
LOG("d=%f acc=%f", d, acc);
//LOG("d=%f acc=%f", d, acc);
acc = 0;
m_points2d.push_back(loc);
@@ -630,14 +499,157 @@ void CanvasModeMaskFree::on_Draw(const glm::mat4& ortho, const glm::mat4& proj,
{
if (!m_points.empty())
{
ui::ShaderManager::use(ui::kShader::Color);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, glm::scale(glm::vec3(1,-1,1)) * ortho);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, 1 });
m_dragging ? m_shape.draw_stroke() : m_shape.draw_fill();
if (m_dragging)
{
ui::ShaderManager::use(ui::kShader::Color);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, glm::scale(glm::vec3(1,-1,1)) * ortho);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, 1 });
//m_dragging ? m_shape.draw_stroke() : m_shape.draw_fill();
m_shape.draw_stroke();
}
else
{
ui::ShaderManager::use(ui::kShader::Color);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, 1 });
m_shape.draw_stroke();
}
}
}
////////////////////////////////////////////////////////////////////
void CanvasModeMaskLine::init()
{
m_shape.create();
}
void CanvasModeMaskLine::leave()
{
if (m_points2d.size() > 3)
{
std::vector<std::shared_ptr<p2t::Point>> points;
for (int i = 0; i < (int)m_points2d.size(); i++)
points.emplace_back(std::make_shared<p2t::Point>(m_points2d[i].x, m_points2d[i].y));
auto v = canvas->triangulate(points);
canvas->project2Dpoints(v);
LOG("%d points", (int)v.size());
m_shape.update_vertices(v.data(), (int)v.size());
if (!m_points.empty())
{
auto drawer = [this](const glm::mat4& camera, const glm::mat4& proj) {
//glEnable(GL_BLEND);
ui::ShaderManager::use(ui::kShader::Color);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, {1, 1, 1, 1});
m_shape.draw_fill();
};
canvas->draw_objects(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), canvas->m_smask);
//m_points.clear();
// close the path
m_points.push_back(m_points.back());
m_points.push_back(m_points.back());
m_points.push_back(m_points.front());
canvas->project2Dpoints(m_points);
// reset m_shape to contour rendering
m_shape.update_vertices(m_points.data(), (int)m_points.size());
}
}
else
{
canvas->m_smask_active = false;
}
m_active_tool = false;
}
void CanvasModeMaskLine::enter()
{
m_points2d.clear();
m_points.clear();
canvas->m_smask.clear({0, 0, 0, 0});
canvas->m_smask_active = true;
m_active_tool = true;
}
void CanvasModeMaskLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
{
switch (me->m_type)
{
case kEventType::MouseDownL:
{
node->mouse_capture();
m_dragging = true;
m_points2d.push_back(loc);
ui::Shape::vertex_t vert;
vert.pos = glm::vec4(loc, 0, 1);
m_points.push_back(vert);
m_shape.update_vertices(m_points.data(), (int)m_points.size());
break;
}
case kEventType::MouseUpL:
node->mouse_release();
m_dragging = false;
if (m_points.size() > 1)
{
m_points.push_back(m_points.back());
m_shape.update_vertices(m_points.data(), (int)m_points.size());
}
break;
case kEventType::MouseMove:
{
if (m_dragging)
{
m_points.back().pos = glm::vec4(loc, 0, 1);
m_points2d.back() = loc;
m_shape.update_vertices(m_points.data(), (int)m_points.size());
}
break;
}
case kEventType::MouseCancel:
if (m_dragging)
{
m_points.pop_back();
m_shape.update_vertices(m_points.data(), (int)m_points.size());
}
m_dragging = false;
node->mouse_release();
if (m_points.size() < 4)
{
m_points.clear();
m_shape.update_vertices(m_points.data(), (int)m_points.size());
}
break;
default:
break;
}
}
void CanvasModeMaskLine::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
{
if (!m_points.empty())
{
if (m_active_tool)
{
ui::ShaderManager::use(ui::kShader::Color);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, glm::scale(glm::vec3(1,-1,1)) * ortho);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, 1 });
//m_dragging ? m_shape.draw_stroke() : m_shape.draw_fill();
m_shape.draw_stroke();
}
else
{
ui::ShaderManager::use(ui::kShader::Color);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, 1 });
m_shape.draw_stroke();
}
}
}
////////////////////////////////////////////////////////////////////
void CanvasModeFill::init()
@@ -743,6 +755,6 @@ void CanvasModeFill::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, cons
ui::ShaderManager::use(ui::kShader::Color);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, .25 });
m_shape.draw_fill();
m_dragging ? m_shape.draw_fill() : m_shape.draw_stroke();
}
}