implement simple brush projection on single cube face, add camera rotation instead of pan

This commit is contained in:
2017-04-26 23:51:05 +01:00
parent 874176c19a
commit e6332322b3
4 changed files with 141 additions and 19 deletions

View File

@@ -72,8 +72,46 @@ void ui::Canvas::stroke_draw()
ShaderManager::u_vec2(kShaderUniform::Resolution, { m_width, m_height });
for (const auto& s : samples)
{
auto unproject = [](glm::vec2 loc, glm::vec4 vp, glm::mat4 camera, glm::mat4 proj, glm::vec3& out_origin, glm::vec3& out_dir) {
auto clip_space = glm::vec2(loc.x, vp.w - loc.y - 1.f) / vp.zw() * 2.f - 1.f;
auto inv = glm::inverse(proj * camera);
auto wp0 = inv * glm::vec4(clip_space, 0, 1);
auto wp1 = inv * glm::vec4(clip_space, .5, 1);
out_origin = (wp0 / wp0.w).xyz();
out_dir = glm::normalize((wp1 / wp1.w).xyz() - out_origin);
};
auto intersect = [](glm::vec3 ray_origin, glm::vec3 ray_dir, glm::vec3 plane_origin, glm::vec3 plane_normal, glm::vec3& out_hit) {
float den = glm::dot(ray_dir, plane_normal);
if (den == 0)
return false; // no intersection
float num = glm::dot(plane_origin - ray_origin, plane_normal);
float t = num / den;
if (t > 0)
out_hit = ray_origin + ray_dir * t;
else
// negative intersection
return false;
return true;
};
glm::vec3 ray_origin, ray_dir;
unproject(s.pos, { 0, 0, m_box.zw }, m_mv, m_proj, ray_origin, ray_dir);
glm::vec3 plane_origin{ 0, 0, -1 }, plane_dir{ 0, 0, 1 };
glm::vec3 hit;
glm::vec2 fb_pos;
if (intersect(ray_origin, ray_dir, plane_origin, plane_dir, hit))
{
glm::mat4 plane_camera = glm::lookAt(plane_origin, plane_dir, { 0, 1, 0 });
glm::vec4 plane_local = plane_camera * glm::vec4(hit, 1);
if (glm::abs(plane_local.x) < 0.5f && glm::abs(plane_local.y) < 0.5f)
{
fb_pos.x = -(plane_local.x - 0.5f) * m_width;
fb_pos.y = (plane_local.y + 0.5f) * m_height;
LOG("draw %f %f", fb_pos.x, fb_pos.y);
}
}
auto mvp = proj *
glm::translate(glm::vec3(s.pos, 0)) *
glm::translate(glm::vec3(fb_pos, 0)) *
glm::scale(glm::vec3(s.size, s.size, 1)) *
glm::eulerAngleZ(s.angle);
@@ -112,10 +150,10 @@ void ui::Canvas::stroke_draw()
m_box.xy = glm::min(m_box.xy(), (glm::vec2)tex_pos);
m_box.zw = glm::max(m_box.zw(), (glm::vec2)(tex_pos + tex_sz));
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
ShaderManager::u_mat4(kShaderUniform::MVP, glm::mat4());
ShaderManager::u_float(kShaderUniform::Alpha, s.flow);
//m_plane.update_vertices(P);
m_plane.draw_fill();
m_plane_brush.update_vertices(P);
m_plane_brush.draw_fill();
}
}
@@ -206,6 +244,7 @@ void ui::Canvas::stroke_update(glm::vec2 point, float pressure)
void ui::Canvas::stroke_start(glm::vec2 point, float pressure, const ui::Brush& brush)
{
m_current_stroke = std::make_unique<Stroke>();
m_current_stroke->m_camera = { m_cam_rot, m_cam_fov };
m_current_stroke->start(brush);
m_current_stroke->add_point(point, pressure);
@@ -260,6 +299,7 @@ bool ui::Canvas::create(int width, int height)
m_sampler.create();
m_sampler_bg.create();
m_plane.create<1>(1, 1);
m_plane_brush.create<1>(1, 1);
m_mesh.create();
return true;
}