add transform mode and tollbar button, implement polygon clipping with uvs interpolation and cube faces projection with near plane clipping, add duplicate points removal template function, implement Spere mesh surface section creation.

This commit is contained in:
2018-11-12 18:19:03 +01:00
parent eb1c8d6b7a
commit 18067726b5
12 changed files with 512 additions and 81 deletions

View File

@@ -471,7 +471,7 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
oldpos = loc;
oldvec = {1.f, 0.f};
acc = 0;
ui::Shape::vertex_t vert;
vertex_t vert;
vert.pos = glm::vec4(loc, 0, 1);
m_points2d.push_back(loc);
m_points2d.push_back(loc);
@@ -486,17 +486,10 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
m_dragging = false;
if (m_points2d.size() > 3)
{
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 = 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())
{
//m_points2d = poly_intersect(poly_remove_duplicate(m_points2d), canvas->face_to_shape2D(0));
auto drawer = [this](const glm::mat4& camera, const glm::mat4& proj) {
//glEnable(GL_BLEND);
ui::ShaderManager::use(ui::kShader::Color);
@@ -504,14 +497,16 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, {1, 1, 1, 1});
m_shape.draw_fill();
};
// use m_shape to render the mask polygon
auto v = canvas->triangulate(poly_remove_duplicate(m_points2d));
canvas->project2Dpoints(v);
m_shape.update_vertices(v.data(), (int)v.size());
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[m_points.size() - 2]);
// close the path and reset m_shape to contour rendering
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());
}
}
@@ -524,7 +519,7 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
{
if (m_dragging)
{
auto v = loc-oldpos;
auto v = loc - oldpos;
float len = glm::length(v);
if (len > 5)
{
@@ -532,7 +527,7 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
m_points2d.back() = loc;
v = glm::normalize(v);
float d = 1-glm::dot(v, oldvec);
float d = 1.f - glm::dot(v, oldvec);
acc += d;
oldpos = loc;
oldvec = v;
@@ -542,7 +537,7 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
acc = 0;
m_points2d.push_back(loc);
ui::Shape::vertex_t vert;
vertex_t vert;
vert.pos = glm::vec4(loc, 0, 1);
m_points.push_back(vert);
m_points.push_back(vert);
@@ -573,6 +568,8 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
void CanvasModeMaskFree::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
{
bool depth = glIsEnabled(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST);
if (m_points.size() > 3)
{
if (m_dragging)
@@ -591,6 +588,7 @@ void CanvasModeMaskFree::on_Draw(const glm::mat4& ortho, const glm::mat4& proj,
m_shape.draw_stroke();
}
}
if (depth) glEnable(GL_DEPTH_TEST);
}
@@ -662,7 +660,7 @@ void CanvasModeMaskLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
node->mouse_capture();
m_dragging = true;
m_points2d.push_back(loc);
ui::Shape::vertex_t vert;
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());
@@ -771,7 +769,7 @@ void CanvasModeFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
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;
vertex_t v;
v.pos = glm::vec4(hit_o, 1);
v.uvs = glm::vec2(0);
if (m_points.size() < 3)
@@ -801,7 +799,7 @@ void CanvasModeFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
int plane_id;
if (m_dragging && canvas->point_trace(loc, ro, rd, hit_o, fb_pos, hit_d, plane_id))
{
ui::Shape::vertex_t v;
vertex_t v;
v.pos = glm::vec4(hit_o, 1);
v.uvs = glm::vec2(0);
m_points.back() = v;
@@ -838,3 +836,99 @@ void CanvasModeFill::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, cons
m_dragging ? m_shape.draw_fill() : m_shape.draw_stroke();
}
}
////////////////////////////////////////////////////////////////////
void CanvasModeTransform::init()
{
m_sphere.create(1.f, glm::radians(-10.f), glm::radians(10.f), glm::radians(-10.f), glm::radians(10.f), 1.f);
m_circle.create<16>(1.f);
m_shape.create();
}
void CanvasModeTransform::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
{
static float theta = 0;
theta += glm::radians(1.f);
bool depth = glIsEnabled(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST);
auto uv = m_center_point_uv;
float x = glm::sin(uv.x) * glm::cos(uv.y);
float y = glm::sin(uv.x) * glm::sin(uv.y);
float z = glm::cos(uv.x);
auto p = glm::vec3(x, y, z);
//auto m = glm::inverse(glm::lookAt({ 0, 0, 0 }, m_center_pos, { 0, 1, 0 }));
//auto m = static_cast<CanvasModeMaskFree*>(canvas->modes[(int)ui::Canvas::kCanvasMode::MaskFree][0]);
auto rot = glm::inverse(glm::lookAt(glm::vec3(0), m_origin, { 0, 1, 0 }));
ui::ShaderManager::use(ui::kShader::Color);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera * rot);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, 1 });
m_sphere.draw_fill();
for (auto pt : m_points2d)
{
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, ortho * glm::translate(glm::vec3(pt, 0)) * glm::scale(glm::vec3(5.f)));
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 1, 1, 1 });
m_circle.draw_fill();
}
ui::ShaderManager::use(ui::kShader::UVs);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, ortho);
m_shape.draw_fill();
if (depth) glEnable(GL_DEPTH_TEST);
}
void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
{
switch (me->m_type)
{
case kEventType::MouseDownR:
//m_origin = canvas->project2Dpoint(loc);
break;
case kEventType::MouseMove:
case kEventType::MouseUpL:
case kEventType::MouseDownL:
{
auto m = glm::lookAt(glm::vec3(0), m_origin, { 0, 1, 0 });
m_center_point = m * glm::vec4(canvas->project2Dpoint(loc), 1);
float r = glm::length(m_center_point);
float lat = glm::acos(m_center_point.z / r);
float lon = glm::atan(m_center_point.y, m_center_point.x);
m_center_point_uv = { lat, lon };
//LOG("pt lat-lon %f %f", lat, lon);
auto face = canvas->face_to_shape2D(0);
if (face.size() > 2)
{
std::vector<vertex_t> quad{
vertex_t{{200, 200}, {0, 0}},
vertex_t{{200, 400}, {0, 1}},
vertex_t{{400, 400}, {1, 1}},
vertex_t{{400, 200}, {1, 0}},
};
auto poly = poly_intersect(quad, face);
m_points2d.clear();
if (!poly.empty())
{
//LOG("size %d", (int)is.size());
std::vector<std::shared_ptr<p2t::Point>> points;
for (auto& v : poly)
{
v.pos.y = canvas->m_box.w - v.pos.y - 1;
m_points2d.push_back(v.pos);
points.push_back(std::make_shared<p2t::Point>(v.pos.x, v.pos.y));
}
auto vert = canvas->triangulate_simple(poly);
m_shape.update_vertices(vert.data(), vert.size());
}
}
}
break;
default:
break;
}
}