transform tool wip

This commit is contained in:
2018-11-22 10:30:31 +01:00
parent 8f9422b6d6
commit 6f9b1b1c23
6 changed files with 267 additions and 154 deletions

View File

@@ -603,9 +603,9 @@ void CanvasModeMaskLine::leave()
{
if (m_points2d.size() > 3)
{
std::vector<std::shared_ptr<p2t::Point>> points;
std::vector<vertex_t> 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));
points.emplace_back(m_points2d[i]);
auto v = canvas->triangulate(points);
canvas->project2Dpoints(v);
LOG("%d points", (int)v.size());
@@ -844,6 +844,106 @@ 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();
m_xform = 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);
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;
midpoint = midpoint / (float)shape2d.size();
auto center3d = canvas->point_trace(midpoint);
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;
}
m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(midpoint), xyz(cam_up)));
shape3d = canvas->triangulate(shape3d);
m_shape.update_vertices(shape3d.data(), shape3d.size());
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();
}
void CanvasModeTransform::leave()
{
auto& layer = canvas->m_layers[canvas->m_current_layer_idx];
GLint vp[4];
glGetIntegerv(GL_VIEWPORT, vp);
glViewport(0, 0, layer.w, layer.h);
bool depth = glIsEnabled(GL_DEPTH_TEST);
bool blend = glIsEnabled(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glActiveTexture(GL_TEXTURE0);
//glm::perspective(glm::radians(m_canvas->m_cam_fov), box.z / box.w, 0.01f, 1000.f);
glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f);
for (int i = 0; i < 6; i++)
{
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();
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();
layer.m_rtt[i].unbindFramebuffer();
}
depth ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
glViewport(vp[0], vp[1], vp[2], vp[3]);
}
void CanvasModeTransform::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
@@ -860,33 +960,39 @@ void CanvasModeTransform::on_Draw(const glm::mat4& ortho, const glm::mat4& proj,
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 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();
//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();
}
auto face = canvas->face_to_shape2D(0);
auto shape = poly_intersect(m->m_points2d, face);
ui::ShaderManager::use(ui::kShader::StrokePreview);
ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0);
ui::ShaderManager::u_float(ui::kShaderUniform::Alpha, canvas->m_current_brush.m_tip_flow);
auto tip_color = glm::vec4(glm::vec3(canvas->m_current_brush.m_tip_color), 1);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, tip_color);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, ortho);
// 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);
auto& tex = TextureManager::get(canvas->m_current_brush.m_tex_id);
tex.bind();
m_tex.bind();
canvas->m_sampler.bind(0);
m_shape.draw_fill();
tex.unbind();
m_tex.unbind();
if (depth) glEnable(GL_DEPTH_TEST);
}
@@ -896,86 +1002,39 @@ void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
switch (me->m_type)
{
case kEventType::MouseDownR:
//m_origin = canvas->project2Dpoint(loc);
{
auto p = loc;
// flip the y coordinate to match opengl Y up
p.y = canvas->m_box.w - loc.y - 1;
//LOG("loc %f %f", p.x, p.y);
auto ln = (p / zw(canvas->m_box)) * 2.f - 1.f;
glm::vec3 ro, rd, hit_o, hit_d;
glm::vec2 hit_fb;
canvas->point_trace_plane(loc, ro , rd, hit_o, hit_d, hit_fb, 0);
//LOG("hit plane %f %f %f", hit_o.x, hit_o.y, hit_o.z);
auto plane2cam = canvas->m_proj * canvas->m_mv * canvas->m_plane_transform[0] * glm::vec4(hit_o, 1);
plane2cam = plane2cam / plane2cam.w;
auto p3d_back = glm::inverse(canvas->m_proj * canvas->m_mv * canvas->m_plane_transform[0]) * plane2cam;
p3d_back = p3d_back / p3d_back.w;
//LOG("\nloc nor %f %f", ln.x, ln.y);
//LOG("plane2cam %f %f %f %f", plane2cam.x, plane2cam.y, plane2cam.z, plane2cam.w);
//LOG("\ncam2plane inv %f %f %f %f", p3d_back.x, p3d_back.y, p3d_back.z, p3d_back.w);
auto loc_back = glm::inverse(canvas->m_proj * canvas->m_mv * canvas->m_plane_transform[0]) * glm::vec4(ln, 1, 1);
loc_back = loc_back / loc_back.z;
//LOG("loc inv %f %f %f %f", loc_back.x, loc_back.y, loc_back.z, loc_back.w);
auto p2d = (xy(plane2cam) * 0.5f + 0.5f) * zw(canvas->m_box);
p2d.y = canvas->m_box.w - p2d.y - 1;
//LOG("vp %f %f", p2d.x, p2d.y);
auto loc_vp = (xy(loc_back) * glm::vec2(-1, -1) * 0.5f + 0.5f) * glm::vec2(canvas->m_width, canvas->m_height);
LOG("trc fb %f %f", hit_fb.x, hit_fb.y);
LOG("prj vp %f %f", loc_vp.x, loc_vp.y);
LOG("trc dir %f %f %f", hit_d.x, hit_d.y, hit_d.z);
LOG("prj dir %f %f %f", canvas->m_plane_dir[0].x, canvas->m_plane_dir[0].y, canvas->m_plane_dir[0].z);
LOG("------------------------------------------");
// convert to normalized cube space
//auto p3d = glm::vec4((p / zw(canvas->m_box)) * 2.f - 1.f, 1, 1);
//auto m = glm::inverse(canvas->m_proj * canvas->m_mv * canvas->m_plane_transform[0]);
//p3d = p3d * m;
//p3d = p3d / p3d.w;
//auto p3d = glm::unProject(glm::vec3(loc, 1), canvas->m_mv * canvas->m_plane_transform[0], canvas->m_proj, canvas->m_vp);
//p3d = p3d / p3d.z;
/*
{
double sum = 0;
auto start = std::chrono::steady_clock::now();
for (int i = 0; i < 10000000; i++)
{
glm::vec3 ro, rd, hit_o, hit_d;
glm::vec2 hit_fb;
canvas->point_trace_plane(loc, ro, rd, hit_o, hit_d, hit_fb, 0);
sum += hit_fb.x;
}
auto t1 = std::chrono::steady_clock::now();
auto m = glm::inverse(canvas->m_proj * canvas->m_mv * canvas->m_plane_transform[0]);
for (int i = 0; i < 10000000; i++)
{
auto loc_back = m * glm::vec4(ln, 1, 1);
loc_back = loc_back / loc_back.z;
//auto loc_vp = (xy(loc_back) * glm::vec2(-1, -1) * 0.5f + 0.5f) * glm::vec2(canvas->m_width, canvas->m_height);
sum += loc_back.x;
}
auto t2 = std::chrono::steady_clock::now();
LOG("t1 %d", (int)std::chrono::duration_cast<std::chrono::milliseconds>(t1 - start).count());
LOG("t2 %d", (int)std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count());
LOG("sum %f", sum);
}
*/
}
break;
case kEventType::MouseUpL:
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 }));
break;
case kEventType::MouseMove:
case kEventType::MouseUpL:
case kEventType::MouseDownL:
{
if (m_dragging)
{
//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)));
}
{
auto p2d = loc;
//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[0] * glm::vec4(p2d_clip, 0, 1);
auto p2d_plane = -p3d_plane / p3d_plane.z;
// auto p3d_world = canvas->m_plane_transform[0] * glm::vec4(p2d_plane, -1, 1);
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);
@@ -997,7 +1056,6 @@ void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
m_points2d.clear();
if (!poly.empty())
{
//LOG("size %d", (int)is.size());
std::vector<std::shared_ptr<p2t::Point>> points;
for (auto& v : poly)
{
@@ -1005,8 +1063,8 @@ void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
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());
auto vert = canvas->triangulate(poly);
//m_shape.update_vertices(vert.data(), vert.size());
}
}