disable exceptions in visual studio, use xK notation for resolution, upgrade up to 32K resolution, mask resolution not doubled anymore, transform interactive controls to move, scale and rotate the selection

This commit is contained in:
2018-11-22 19:07:14 +01:00
parent 6f9b1b1c23
commit 86656cc7e3
12 changed files with 218 additions and 146 deletions

View File

@@ -449,7 +449,7 @@ void CanvasModeMaskFree::init()
void CanvasModeMaskFree::leave()
{
// canvas->draw_objects(std::bind(&CanvasModeFill::on_Draw, this, glm::mat4(), std::placeholders::_1, std::placeholders::_2));
// canvas->draw_objects(std::bind(&CanvasModeFill::on_Draw, this, glm::mat4(1), std::placeholders::_1, std::placeholders::_2));
// m_points.clear();
}
@@ -843,65 +843,91 @@ 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();
for (int i = 0; i < 6; i++)
m_shape[i].create();
m_xform = glm::mat4(1);
m_xform_local = glm::mat4(1);
}
void CanvasModeTransform::enter()
{
auto m = static_cast<CanvasModeMaskFree*>(canvas->modes[(int)ui::Canvas::kCanvasMode::MaskFree][0]);
int plane = 0;
auto face = canvas->face_to_shape2D(plane);
auto shape2d = poly_intersect(m->m_points2d, face);
std::vector<vertex_t> shape3d;
shape3d.reserve(shape2d.size());
glm::vec2 bb_min(canvas->m_size);
glm::vec2 bb_max(0, 0);
glm::vec2 midpoint(0);
for (auto p2d : shape2d)
{
//p2d.y = canvas->m_box.w - p2d.y - 1;
auto p2d_clip = ((p2d / zw(canvas->m_box)) * 2.f - 1.f) * glm::vec2(1, -1);
auto p3d_plane = canvas->m_plane_unproject[plane] * glm::vec4(p2d_clip, 0, 1);
auto p2d_plane = (-xy(p3d_plane) / p3d_plane.z)/* * glm::vec2(-1, 1)*/;
auto p2d_plane_raster = (p2d_plane * 0.5f + 0.5f) * canvas->m_size;
auto p3d_world = canvas->m_plane_transform[plane] * glm::vec4(p2d_plane, -1, 1);
bb_min = glm::min(bb_min, p2d_plane_raster);
bb_max = glm::max(bb_max, p2d_plane_raster);
//p2d.y = canvas->m_box.w - p2d.y - 1;
midpoint += p2d;
glm::vec3 pt_o, pt_d;
canvas->point_unproject(p2d, pt_o, pt_d);
canvas->m_smask_active = false;
auto points = std::move(m->m_points2d);
vertex_t v;
v.pos = glm::vec4(xyz(p3d_world), 1);
v.uvs = p2d_plane_raster;
shape3d.push_back(v);
glm::vec2 bb_min(FLT_MAX);
glm::vec2 bb_max(-FLT_MAX);
for (auto p2d : points)
{
bb_min = glm::min(bb_min, p2d);
bb_max = glm::max(bb_max, p2d);
}
auto bb_sz = bb_max - bb_min;
auto bb_center = (bb_min + bb_max) * 0.5f;
midpoint = midpoint / (float)shape2d.size();
auto center3d = canvas->point_trace(midpoint);
glm::vec2 midpoint = (bb_min + bb_max) * 0.5f;
auto cam_up = glm::inverse(canvas->m_mv) * glm::vec4(0, 1, 0, 1);
m_xform = glm::lookAt({ 0, 0, 0 }, canvas->point_trace(midpoint), xyz(cam_up));
for (auto& v : shape3d)
{
v.uvs = (v.uvs - bb_min) / bb_sz;
v.pos = m_xform * v.pos;
}
auto center_mat = glm::lookAt({ 0, 0, 0 }, canvas->point_trace(midpoint), xyz(cam_up));
m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(midpoint), xyz(cam_up)));
m_xform_local = glm::mat4(1);
corners.clear();
corners.emplace_back(bb_min, 0);
corners.emplace_back(bb_max, 0);
corners.emplace_back(bb_max.x, bb_min.y, 0);
corners.emplace_back(bb_min.x, bb_max.y, 0);
corners.emplace_back(midpoint, 0);
corners.emplace_back(midpoint + (bb_max-bb_min) * glm::vec2(0.75f, 0), 0);
for (auto& c : corners)
c = center_mat * glm::vec4(canvas->point_trace(c), 1);
shape3d = canvas->triangulate(shape3d);
m_shape.update_vertices(shape3d.data(), shape3d.size());
for (int plane = 0; plane < 6; plane++)
{
auto face = canvas->face_to_shape2D(plane);
auto shape2d = poly_intersect(points, face);
if (shape2d.size() < 3)
{
m_shape[plane].update_vertices(nullptr, 0);
continue;
}
std::vector<vertex_t> shape3d;
shape3d.reserve(shape2d.size());
glm::vec2 bb_min(canvas->m_size);
glm::vec2 bb_max(0, 0);
for (auto p2d : shape2d)
{
p2d.y = canvas->m_box.w - p2d.y - 1;
auto p2d_clip = ((p2d / zw(canvas->m_box)) * 2.f - 1.f);
auto p3d_plane = canvas->m_plane_unproject[plane] * glm::vec4(p2d_clip, 0, 1);
auto p2d_plane = (-xy(p3d_plane) / p3d_plane.z);
auto p2d_plane_raster = (p2d_plane * 0.5f + 0.5f) * canvas->m_size;
auto p3d_world = canvas->m_plane_transform[plane] * glm::vec4(p2d_plane, -1, 1);
bb_min = glm::min(bb_min, p2d_plane_raster);
bb_max = glm::max(bb_max, p2d_plane_raster);
canvas->m_layers[canvas->m_current_layer_idx].m_rtt[plane].bindFramebuffer();
m_tex.create(bb_sz.x, bb_sz.y);
m_tex.bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bb_min.x, bb_min.y, bb_sz.x, bb_sz.y);
m_tex.unbind();
canvas->m_layers[canvas->m_current_layer_idx].m_rtt[plane].unbindFramebuffer();
//glm::vec3 pt_o, pt_d;
//canvas->point_unproject(p2d, pt_o, pt_d);
vertex_t v;
v.pos = glm::vec4(xyz(p3d_world), 1);
v.uvs = p2d_plane_raster;
shape3d.push_back(v);
}
auto bb_sz = bb_max - bb_min;
auto bb_center = (bb_min + bb_max) * 0.5f;
auto center3d = canvas->point_trace(midpoint);
for (auto& v : shape3d)
{
v.uvs = (v.uvs - bb_min) / bb_sz;
v.pos = center_mat * v.pos;
}
shape3d = canvas->triangulate(shape3d);
m_shape[plane].update_vertices(shape3d.data(), shape3d.size());
canvas->m_layers[canvas->m_current_layer_idx].m_rtt[plane].bindFramebuffer();
m_tex[plane].create(bb_sz.x, bb_sz.y);
m_tex[plane].bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bb_min.x, bb_min.y, bb_sz.x, bb_sz.y);
m_tex[plane].unbind();
canvas->m_layers[canvas->m_current_layer_idx].m_rtt[plane].unbindFramebuffer();
}
}
void CanvasModeTransform::leave()
@@ -926,18 +952,21 @@ void CanvasModeTransform::leave()
glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), canvas->m_plane_origin[i], canvas->m_plane_tangent[i]);
layer.m_rtt[i].bindFramebuffer();
ui::ShaderManager::use(ui::kShader::Color);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 1, 1, .1 });
m_shape.draw_fill();
for (int j = 0; j < 6; j++)
{
ui::ShaderManager::use(ui::kShader::Color);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform * m_xform_local);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 1, 1, .1 });
m_shape[j].draw_fill();
ui::ShaderManager::use(ui::kShader::Texture);
ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform);
m_tex.bind();
canvas->m_sampler.bind(0);
m_shape.draw_fill();
m_tex.unbind();
ui::ShaderManager::use(ui::kShader::Texture);
ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform * m_xform_local);
m_tex[j].bind();
canvas->m_sampler.bind(0);
m_shape[j].draw_fill();
m_tex[j].unbind();
}
layer.m_rtt[i].unbindFramebuffer();
}
@@ -971,34 +1000,42 @@ void CanvasModeTransform::on_Draw(const glm::mat4& ortho, const glm::mat4& proj,
auto face = canvas->face_to_shape2D(0);
auto shape = poly_intersect(m->m_points2d, face);
// for (auto pt : shape)
// {
// pt.y = canvas->m_box.w - pt.y - 1;
// 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, proj * camera * m_xform);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 1, 1, .1 });
m_shape.draw_fill();
glEnable(GL_BLEND);
ui::ShaderManager::use(ui::kShader::Texture);
ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera * m_xform);
glActiveTexture(GL_TEXTURE0);
m_tex.bind();
canvas->m_sampler.bind(0);
m_shape.draw_fill();
m_tex.unbind();
for (int i = 0; i < 6; i++)
{
//ui::ShaderManager::use(ui::kShader::UVs);
ui::ShaderManager::use(ui::kShader::Color);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera * m_xform * m_xform_local);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 1, 1, .1 });
m_shape[i].draw_fill();
ui::ShaderManager::use(ui::kShader::Texture);
ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera * m_xform * m_xform_local);
glActiveTexture(GL_TEXTURE0);
m_tex[i].bind();
canvas->m_sampler.bind(0);
m_shape[i].draw_fill();
m_tex[i].unbind();
}
auto m2d = canvas->m_proj * canvas->m_mv * m_xform * m_xform_local;
for (int i = 0; i < corners.size(); i++)
{
auto c = m2d * glm::vec4(corners[i], 1);
auto c2d = ((xy(c) / c.z) * 0.5f + 0.5f) * zw(canvas->m_box);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, ortho * glm::translate(glm::vec3(c2d, 0)) * glm::scale(glm::vec3(10.f)));
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, i == corner_hl ? 1.f : .5f });
m_circle.draw_fill();
}
if (depth) glEnable(GL_DEPTH_TEST);
}
void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
{
auto m2d = glm::scale(glm::vec3(1, -1, 1)) * canvas->m_proj * canvas->m_mv * m_xform * m_xform_local;
switch (me->m_type)
{
case kEventType::MouseDownR:
@@ -1009,21 +1046,57 @@ void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
m_dragging = false;
break;
case kEventType::MouseDownL:
m_dragging = true;
m_drag_start = loc;
m_drag_xform = m_xform;
//m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(loc), { 0, 1, 0 }));
if (corner_hl != -1)
{
m_dragging = true;
m_drag_start = loc;
m_drag_xform = m_xform;
m_drag_xform_local = m_xform_local;
m_drag_corner = corner_hl;
m_drag_corners2d = corners2d;
if (m_drag_corner < 4)
{
m_drag_diag = glm::distance(corners2d[4], corners2d[m_drag_corner]);
}
}
break;
case kEventType::MouseMove:
{
corner_hl = -1;
corners2d.resize(corners.size());
for (int i = 0; i < corners.size(); i++)
{
auto c = m2d * glm::vec4(corners[i], 1);
corners2d[i] = ((xy(c) / c.z) * 0.5f + 0.5f) * zw(canvas->m_box);
float d = glm::distance(corners2d[i], loc);
if (d < 10)
corner_hl = i;
}
if (m_dragging)
{
auto cam_up = glm::inverse(canvas->m_mv) * glm::vec4(0, 1, 0, 1);
//auto diff = glm::radians(loc - m_drag_start) * 0.1f;
//auto m = glm::eulerAngleXY(-diff.y, -diff.x);
//m_xform = m * m_drag_xform;
auto cam_up = glm::inverse(canvas->m_mv) * glm::vec4(0, 1, 0, 1);
m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(loc), xyz(cam_up)));
if (m_drag_corner > -1 && m_drag_corner < 4)
{
auto diag = glm::distance(corners2d[4], loc);
auto scale = diag / m_drag_diag;
m_xform_local = m_drag_xform_local * glm::scale(glm::vec3(scale, scale, 1));
}
if (m_drag_corner == 4)
{
m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(loc), xyz(cam_up)));
}
if (m_drag_corner == 5)
{
auto a = glm::normalize(m_drag_corners2d[m_drag_corner] - m_drag_corners2d[4]);
auto b = glm::normalize(loc - m_drag_corners2d[4]);
auto angle = glm::orientedAngle(a, b);
m_xform_local = m_drag_xform_local * glm::eulerAngleZ(-angle);
}
}
/*
{
auto p2d = loc;
//p2d.y = canvas->m_box.w - p2d.y - 1;
@@ -1034,39 +1107,7 @@ void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
int x = 0;
LOG("pt %f %f %f %f", p2d_plane.x, p2d_plane.y, p2d_plane.z, p2d_plane.w);
}
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())
{
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(poly);
//m_shape.update_vertices(vert.data(), vert.size());
}
}
*/
}
break;