implement selection mask with lasso tool
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "shader.h"
|
||||
#include "node_canvas.h"
|
||||
#include "app.h"
|
||||
#include <poly2tri.h>
|
||||
|
||||
NodeCanvas* CanvasMode::node;
|
||||
ui::Canvas* CanvasMode::canvas;
|
||||
@@ -376,10 +377,14 @@ char get_line_intersection(float p0_x, float p0_y, float p1_x, float p1_y,
|
||||
|
||||
void CanvasModeFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
||||
{
|
||||
static glm::vec2 oldpos;
|
||||
static glm::vec2 oldvec;
|
||||
static float acc = 0.f;
|
||||
switch (me->m_type)
|
||||
{
|
||||
case kEventType::MouseDownR:
|
||||
{
|
||||
/*
|
||||
if (!m_points.empty())
|
||||
{
|
||||
auto drawer = [this](const glm::mat4& camera, const glm::mat4& proj) {
|
||||
@@ -400,59 +405,147 @@ void CanvasModeFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
||||
m_points.clear();
|
||||
m_dirty_planes.clear();
|
||||
}
|
||||
*/
|
||||
break;
|
||||
}
|
||||
case kEventType::MouseDownL:
|
||||
{
|
||||
node->mouse_capture();
|
||||
m_dragging = true;
|
||||
glm::vec3 ro, rd, hit_o, hit_d;
|
||||
glm::vec2 hit_fb;
|
||||
int plane_id;
|
||||
if (canvas->point_trace_plane(loc, ro, rd, hit_o, hit_d, hit_fb, 0))
|
||||
{
|
||||
m_dirty_planes[plane_id]++;
|
||||
ui::Shape::vertex_t v;
|
||||
v.pos = glm::vec4(hit_o, 1);
|
||||
v.uvs = glm::vec2(0);
|
||||
if (m_points.size() < 3)
|
||||
{
|
||||
m_points.push_back(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto last = m_points.back();
|
||||
m_points.push_back(m_points[0]);
|
||||
m_points.push_back(last);
|
||||
m_points.push_back(v);
|
||||
float isx, isy;
|
||||
if (get_line_intersection(m_points[0].pos.x, m_points[0].pos.y, v.pos.x, v.pos.y, 1, -1, 1, 1, &isx, &isy))
|
||||
{
|
||||
LOG("intersection in %f %f", isx, isy);
|
||||
}
|
||||
}
|
||||
m_shape.update_vertices(m_points.data(), m_points.size());
|
||||
}
|
||||
m_points2d.clear();
|
||||
m_points.clear();
|
||||
oldpos = loc;
|
||||
oldvec = {1.f, 0.f};
|
||||
acc = 0;
|
||||
ui::Shape::vertex_t vert;
|
||||
vert.pos = glm::vec4(loc, 0, 1);
|
||||
m_points2d.push_back(loc);
|
||||
m_points2d.push_back(loc);
|
||||
m_points.push_back(vert);
|
||||
m_points.push_back(vert);
|
||||
canvas->m_smask.clear({0, 0, 0, 0});
|
||||
canvas->m_smask_active = true;
|
||||
break;
|
||||
}
|
||||
case kEventType::MouseUpL:
|
||||
node->mouse_release();
|
||||
m_dragging = false;
|
||||
if (m_points2d.size() > 3)
|
||||
{
|
||||
std::vector<p2t::Point*> points;
|
||||
for (int i = 0; i < (int)m_points2d.size() - 1; i++)
|
||||
points.push_back(new p2t::Point(m_points2d[i].x, m_points2d[i].y));
|
||||
p2t::CDT cdt(points);
|
||||
cdt.Triangulate();
|
||||
auto triangles = cdt.GetTriangles();
|
||||
std::vector<ui::Shape::vertex_t> v;
|
||||
for (auto t : triangles)
|
||||
{
|
||||
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);
|
||||
v.push_back(vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_shape.update_vertices(v.data(), 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();
|
||||
};
|
||||
std::vector<int> planes;
|
||||
for (auto p : m_dirty_planes)
|
||||
{
|
||||
planes.push_back(p.first);
|
||||
canvas->m_dirty_face[p.first] = true;
|
||||
canvas->m_dirty_box[p.first] = { 0, 0, canvas->m_width, canvas->m_height };
|
||||
}
|
||||
canvas->snap_history(planes);
|
||||
canvas->draw_objects(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), canvas->m_smask);
|
||||
m_points.clear();
|
||||
m_dirty_planes.clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
canvas->m_smask_active = false;
|
||||
}
|
||||
break;
|
||||
case kEventType::MouseMove:
|
||||
{
|
||||
glm::vec3 ro, rd, hit_o, hit_d;
|
||||
glm::vec2 fb_pos;
|
||||
int plane_id;
|
||||
if (m_dragging && canvas->point_trace(loc, ro, rd, hit_o, fb_pos, hit_d, plane_id))
|
||||
if (m_dragging)
|
||||
{
|
||||
ui::Shape::vertex_t v;
|
||||
v.pos = glm::vec4(hit_o, 1);
|
||||
v.uvs = glm::vec2(0);
|
||||
m_points.back() = v;
|
||||
m_shape.update_vertices(m_points.data(), m_points.size());
|
||||
auto v = loc-oldpos;
|
||||
float len = glm::length(v);
|
||||
if (len > 5)
|
||||
{
|
||||
m_points.back().pos = glm::vec4(loc, 0, 1);
|
||||
m_points2d.back() = loc;
|
||||
|
||||
v = glm::normalize(v);
|
||||
float d = 1-glm::dot(v, oldvec);
|
||||
acc += d;
|
||||
oldpos = loc;
|
||||
oldvec = v;
|
||||
if (acc > 0.001) // angle change tollerance
|
||||
{
|
||||
LOG("d=%f acc=%f", d, acc);
|
||||
acc = 0;
|
||||
|
||||
m_points2d.push_back(loc);
|
||||
ui::Shape::vertex_t vert;
|
||||
vert.pos = glm::vec4(loc, 0, 1);
|
||||
m_points.push_back(vert);
|
||||
m_points.push_back(vert);
|
||||
}
|
||||
m_shape.update_vertices(m_points.data(), m_points.size());
|
||||
}
|
||||
}
|
||||
break;
|
||||
/*
|
||||
glm::vec3 ro, rd, hit_o, hit_d;
|
||||
glm::vec2 hit_fb;
|
||||
int plane_id;
|
||||
if (canvas->point_trace_plane(loc, ro, rd, hit_o, hit_d, hit_fb, 0))
|
||||
{
|
||||
m_dirty_planes[plane_id]++;
|
||||
ui::Shape::vertex_t v;
|
||||
v.pos = glm::vec4(hit_o, 1);
|
||||
v.uvs = glm::vec2(0);
|
||||
if (m_points.size() < 3)
|
||||
{
|
||||
m_points.push_back(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto last = m_points.back();
|
||||
m_points.push_back(m_points[0]);
|
||||
m_points.push_back(last);
|
||||
m_points.push_back(v);
|
||||
float isx, isy;
|
||||
if (get_line_intersection(m_points[0].pos.x, m_points[0].pos.y, v.pos.x, v.pos.y, 1, -1, 1, 1, &isx, &isy))
|
||||
{
|
||||
LOG("intersection in %f %f", isx, isy);
|
||||
}
|
||||
}
|
||||
m_shape.update_vertices(m_points.data(), m_points.size());
|
||||
}
|
||||
*/
|
||||
}
|
||||
case kEventType::MouseCancel:
|
||||
if (m_dragging)
|
||||
@@ -478,8 +571,8 @@ void CanvasModeFill::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, cons
|
||||
if (!m_points.empty())
|
||||
{
|
||||
ui::ShaderManager::use(ui::kShader::Color);
|
||||
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera);
|
||||
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, glm::scale(glm::vec3(1,-1,1)) * ortho);
|
||||
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { node->m_brush.m_tip_color.rgb(), node->m_brush.m_tip_opacity });
|
||||
m_shape.draw_fill();
|
||||
m_dragging ? m_shape.draw_stroke() : m_shape.draw_fill();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user