transform tool wip
This commit is contained in:
150
src/canvas.cpp
150
src/canvas.cpp
@@ -374,6 +374,23 @@ void ui::Canvas::stroke_draw()
|
||||
stroke_draw_mix(bb_min, bb_sz);
|
||||
}
|
||||
|
||||
// P is the initial square centered at the cursor location
|
||||
glm::vec2 dx(s.size * 0.5f, 0), dy(0, s.size * 0.5f);
|
||||
glm::vec2 off[4] = {
|
||||
-dx - dy, // A - bottom-left
|
||||
-dx + dy, // B - top-left
|
||||
+dx + dy, // C - top-right
|
||||
+dx - dy, // D - bottom-right
|
||||
};
|
||||
std::vector<vertex_t> B{
|
||||
vertex_t{ {0, 0, 1, 1}, {0, 0}, {0, 0} },
|
||||
vertex_t{ {0, 0, 1, 1}, {0, 1}, {0, 1} },
|
||||
vertex_t{ {0, 0, 1, 1}, {1, 1}, {1, 1} },
|
||||
vertex_t{ {0, 0, 1, 1}, {1, 0}, {1, 0} },
|
||||
};
|
||||
for (int j = 0; j < 4; j++)
|
||||
B[j].pos = glm::vec4(xy(s.pos) + off[j] * glm::orientate2(-s.angle), 1, 1);
|
||||
|
||||
glViewport(0, 0, m_width, m_height);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
@@ -414,31 +431,13 @@ void ui::Canvas::stroke_draw()
|
||||
// some trigonometric shit, tangent and stuff
|
||||
// if (dot < -0.3f)
|
||||
// continue;
|
||||
|
||||
|
||||
glm::vec2 dx(s.size * 0.5f, 0), dy(0, s.size * 0.5f);
|
||||
glm::vec2 off[4] = {
|
||||
- dx - dy, // A - bottom-left
|
||||
- dx + dy, // B - top-left
|
||||
+ dx + dy, // C - top-right
|
||||
+ dx - dy, // D - bottom-right
|
||||
};
|
||||
int intersected = 0;
|
||||
int inside = 0;
|
||||
|
||||
// face is the 2d shape of the cube plane i projected onto the window space
|
||||
auto face = face_to_shape2D(i);
|
||||
// P is the initial square centered at the cursor location
|
||||
std::vector<vertex_t> P{
|
||||
vertex_t{ {0, 0, 1, 1}, {0, 0}, {0, 0} },
|
||||
vertex_t{ {0, 0, 1, 1}, {0, 1}, {0, 1} },
|
||||
vertex_t{ {0, 0, 1, 1}, {1, 1}, {1, 1} },
|
||||
vertex_t{ {0, 0, 1, 1}, {1, 0}, {1, 0} },
|
||||
};
|
||||
for (int j = 0; j < 4; j++)
|
||||
P[j].pos = glm::vec4(xy(s.pos) + off[j] * glm::orientate2(-s.angle), 1, 1);
|
||||
// intersect P with the current face to clip diverging points from the plane
|
||||
P = poly_intersect(P, face);
|
||||
auto P = poly_intersect(B, face);
|
||||
|
||||
for (int j = 0; j < P.size(); j++)
|
||||
{
|
||||
@@ -475,7 +474,8 @@ void ui::Canvas::stroke_draw()
|
||||
// we need to imitate the same perspective as the once in the camera
|
||||
// see: https://www.scratchapixel.com/lessons/3d-basic-rendering/rasterization-practical-implementation/perspective-correct-interpolation-vertex-attributes
|
||||
auto hit_cam = m_mv * glm::vec4(hit, 1);
|
||||
P[j].pos.z = hit_cam.z;
|
||||
P[j].pos.z = 0;
|
||||
P[j].pos.w = hit_cam.z;
|
||||
P[j].uvs *= hit_cam.z;
|
||||
P[j].uvs2 *= hit_cam.z;
|
||||
|
||||
@@ -617,9 +617,31 @@ bool ui::Canvas::point_trace(glm::vec2 loc, glm::vec3& ray_origin, glm::vec3& ra
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
bool ui::Canvas::point_trace_plane(glm::vec2 loc, glm::vec3& hit_pos, glm::vec2& hit_fb_pos, int plane_id)
|
||||
{
|
||||
auto ln = (loc / zw(m_box)) * 2.f - 1.f;
|
||||
auto p = m_plane_unproject[plane_id] * glm::vec4(ln, 1, 1);
|
||||
if (p.w <= 0)
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
bool ui::Canvas::point_trace_plane(glm::vec2 loc, glm::vec3& ray_origin, glm::vec3& ray_dir,
|
||||
glm::vec3& hit_pos, glm::vec3& hit_normal, glm::vec2& hit_fb_pos, int plane_id)
|
||||
{
|
||||
/*
|
||||
auto ln = (loc / zw(m_box)) * 2.f - 1.f;
|
||||
auto p = m_plane_unproject[plane_id] * glm::vec4(ln, 1, 1);
|
||||
if (p.w <= 0)
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
point_unproject(loc, { 0, 0, zw(m_box) }, m_mv, m_proj, ray_origin, ray_dir);
|
||||
glm::vec3 hit;
|
||||
glm::vec2 fb_pos;
|
||||
@@ -655,7 +677,19 @@ void ui::Canvas::point_unproject(glm::vec2 loc, glm::vec3& out_origin, glm::vec3
|
||||
auto wp1 = inv * glm::vec4(clip_space, .5, 1);
|
||||
out_origin = xyz(wp0 / wp0.w);
|
||||
out_dir = glm::normalize(xyz(wp1 / wp1.w) - out_origin);
|
||||
};
|
||||
}
|
||||
glm::vec3 ui::Canvas::point_trace(glm::vec2 loc)
|
||||
{
|
||||
glm::vec3 ray_origin;
|
||||
glm::vec3 ray_dir;
|
||||
glm::vec3 hit_pos;
|
||||
glm::vec3 hit_normal;
|
||||
glm::vec2 fb_pos;
|
||||
int plane_id;
|
||||
if (point_trace(loc, ray_origin, ray_dir, hit_pos, fb_pos, hit_normal, plane_id))
|
||||
return hit_pos;
|
||||
return glm::vec3(0);
|
||||
}
|
||||
void ui::Canvas::stroke_commit()
|
||||
{
|
||||
if (!m_dirty || m_layers.empty())
|
||||
@@ -962,6 +996,7 @@ void ui::Canvas::resize(int width, int height)
|
||||
{
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_size = { width, height };
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
#if defined(__IOS__) || defined(__ANDROID__)
|
||||
@@ -982,6 +1017,7 @@ bool ui::Canvas::create(int width, int height)
|
||||
{
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_size = { width, height };
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
#if defined(__IOS__) || defined(__ANDROID__)
|
||||
@@ -2018,7 +2054,7 @@ void ui::Canvas::draw_objects(std::function<void(const glm::mat4& camera, const
|
||||
glViewport(0, 0, layer.w, layer.h);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .1f, 100.f);
|
||||
glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .1f, 1000.f);
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), m_plane_origin[i], m_plane_tangent[i]);
|
||||
@@ -2129,38 +2165,38 @@ std::vector<vertex_t> ui::Canvas::triangulate_simple(const std::vector<vertex_t>
|
||||
|
||||
std::vector<vertex_t> ui::Canvas::triangulate(const std::vector<glm::vec2>& points)
|
||||
{
|
||||
std::vector<std::shared_ptr<p2t::Point>> tmp;
|
||||
std::vector<vertex_t> tmp;
|
||||
for (auto pt : points)
|
||||
tmp.push_back(std::make_shared<p2t::Point>(pt.x, pt.y));
|
||||
tmp.push_back(pt);
|
||||
return triangulate(tmp);
|
||||
}
|
||||
|
||||
std::vector<vertex_t> ui::Canvas::triangulate(const std::vector<std::shared_ptr<p2t::Point>>& points)
|
||||
std::vector<vertex_t> ui::Canvas::triangulate(const std::vector<vertex_t>& points)
|
||||
{
|
||||
struct Segment
|
||||
{
|
||||
std::shared_ptr<p2t::Point> a = nullptr;
|
||||
std::shared_ptr<p2t::Point> b = nullptr;
|
||||
const vertex_t* a = nullptr;
|
||||
const vertex_t* b = nullptr;
|
||||
Segment* prev = nullptr;
|
||||
std::shared_ptr<Segment> next = nullptr;
|
||||
bool end = false;
|
||||
};
|
||||
|
||||
std::vector<std::shared_ptr<vertex_t>> new_points;
|
||||
std::shared_ptr<Segment> root = std::make_shared<Segment>();
|
||||
std::shared_ptr<Segment> node = root;
|
||||
for (int i = 0; i < points.size(); i++)
|
||||
{
|
||||
node->a = points[i];
|
||||
node->a = &points[i];
|
||||
if (i == points.size() - 1)
|
||||
{
|
||||
node->b = points[0];
|
||||
node->b = &points[0];
|
||||
node->next = root;
|
||||
node->end = true;
|
||||
root->prev = node.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
node->b = points[i + 1];
|
||||
node->b = &points[i + 1];
|
||||
node->next = std::make_shared<Segment>();
|
||||
node->next->prev = node.get();
|
||||
}
|
||||
@@ -2181,21 +2217,25 @@ std::vector<vertex_t> ui::Canvas::triangulate(const std::vector<std::shared_ptr<
|
||||
std::shared_ptr<Segment> other = node->next;
|
||||
while (other)
|
||||
{
|
||||
if (*node->a == *other->a || *node->a == *other->b ||
|
||||
*node->b == *other->a || *node->b == *other->b)
|
||||
if (node->a->pos == other->a->pos || node->a->pos == other->b->pos ||
|
||||
node->b->pos == other->a->pos || node->b->pos == other->b->pos)
|
||||
{
|
||||
other = other->end ? nullptr : other->next;
|
||||
continue;
|
||||
}
|
||||
glm::vec2 s0a(node->a->x, node->a->y);
|
||||
glm::vec2 s0b(node->b->x, node->b->y);
|
||||
glm::vec2 s1a(other->a->x, other->a->y);
|
||||
glm::vec2 s1b(other->b->x, other->b->y);
|
||||
glm::vec2 s0a(node->a->pos);
|
||||
glm::vec2 s0b(node->b->pos);
|
||||
glm::vec2 s1a(other->a->pos);
|
||||
glm::vec2 s1b(other->b->pos);
|
||||
glm::vec2 hit_uv;
|
||||
glm::vec2 is;
|
||||
if (segments_intersect(s0a, s0b, s1a, s1b, is, hit_uv))
|
||||
{
|
||||
auto p = std::make_shared<p2t::Point>(is.x, is.y);
|
||||
new_points.push_back(std::make_unique<vertex_t>());
|
||||
auto p = new_points.back().get();
|
||||
p->pos = glm::lerp(node->a->pos, node->b->pos, hit_uv.x);
|
||||
p->uvs = glm::lerp(node->a->uvs, node->b->uvs, hit_uv.x);
|
||||
p->uvs2 = glm::lerp(node->a->uvs2, node->b->uvs2, hit_uv.x);
|
||||
auto poly_root = std::make_shared<Segment>();
|
||||
poly_root->a = p;
|
||||
poly_root->b = node->b;
|
||||
@@ -2219,43 +2259,49 @@ std::vector<vertex_t> ui::Canvas::triangulate(const std::vector<std::shared_ptr<
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<vertex_t> vertices;
|
||||
std::vector<vertex_t> ret;
|
||||
for (auto poly : polys)
|
||||
{
|
||||
std::vector<p2t::Point*> outline;
|
||||
std::vector<const vertex_t*> outline;
|
||||
node = poly;
|
||||
while (node)
|
||||
{
|
||||
outline.push_back(new p2t::Point(*node->a));
|
||||
if (outline.empty() || // if empty insert right away
|
||||
outline.back() != node->a && // insert only if different than the last post
|
||||
(outline.front() != node->a || !node->end)) // if is the end check against the first one
|
||||
{
|
||||
outline.push_back(node->a);
|
||||
}
|
||||
auto current = node;
|
||||
node = node->end ? nullptr : node->next;
|
||||
current->next = nullptr;
|
||||
}
|
||||
//LOG("poly %zu", outline.size());
|
||||
|
||||
if (outline.size() > 2)
|
||||
{
|
||||
p2t::CDT* cdt = new p2t::CDT(outline);
|
||||
std::vector<p2t::Point> points(outline.size());
|
||||
std::vector<p2t::Point*> points_ptr(outline.size());
|
||||
for (size_t i = 0; i < outline.size(); i++)
|
||||
{
|
||||
points[i] = { outline[i]->pos.x, outline[i]->pos.y };
|
||||
points_ptr[i] = &points[i];
|
||||
}
|
||||
|
||||
p2t::CDT* cdt = new p2t::CDT(points_ptr); // TODO: remove duplicates
|
||||
cdt->Triangulate();
|
||||
auto tr = cdt->GetTriangles();
|
||||
for (auto t : tr)
|
||||
{
|
||||
vertex_t vertex;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
auto p = t->GetPoint(i);
|
||||
vertex.pos = glm::vec4(p->x, p->y, 0, 1);
|
||||
vertices.push_back(vertex);
|
||||
auto index = std::distance(points.data(), t->GetPoint(i));
|
||||
ret.push_back(*outline[index]);
|
||||
}
|
||||
}
|
||||
|
||||
delete cdt;
|
||||
}
|
||||
for (auto p : outline)
|
||||
delete p;
|
||||
}
|
||||
|
||||
return vertices;
|
||||
return ret;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user