Extract canvas projection helpers and thin preview and node loading

This commit is contained in:
2026-06-16 18:16:04 +02:00
parent 1442c13dd7
commit 8906756d12
11 changed files with 565 additions and 341 deletions

View File

@@ -10,6 +10,7 @@
#include "legacy_canvas_stroke_edge_services.h"
#include "legacy_canvas_stroke_execution_services.h"
#include "legacy_canvas_stroke_shader_services.h"
#include "legacy_canvas_projection_services.h"
#include "legacy_canvas_stroke_services.h"
#include "legacy_ui_gl_dispatch.h"
#include "legacy_ui_overlay_services.h"
@@ -2028,29 +2029,7 @@ void Canvas::stroke_draw()
bool Canvas::point_trace(glm::vec2 loc, glm::vec3& ray_origin, glm::vec3& ray_dir,
glm::vec3& hit_pos, glm::vec2& fb_pos, glm::vec3& hit_normal, int& out_plane_id)
{
point_unproject(loc, { 0, 0, zw(m_box) }, m_mv, m_proj, ray_origin, ray_dir);
glm::vec3 hit;
float hit_t;
for (int i = 0; i < 6; i++)
{
if (ray_intersect(ray_origin, ray_dir, m_plane_origin[i], m_plane_normal[i], m_plane_tangent[i], hit, hit_t))
{
glm::mat4 plane_camera = glm::lookAt(m_plane_origin[i], m_plane_normal[i], m_plane_tangent[i]);
glm::vec4 plane_local = plane_camera * glm::vec4(hit, 1);
if (glm::abs(plane_local.x) < 1.f && glm::abs(plane_local.y) < 1.f)
{
fb_pos.x = -(plane_local.x * 0.5f - 0.5f) * m_width;
fb_pos.y = (plane_local.y * 0.5f + 0.5f) * m_height;
hit_pos = hit;
hit_normal = m_plane_normal[i];
out_plane_id = i;
return true;
}
else continue;
}
else continue;
}
return false;
return pp::panopainter::legacy_canvas_point_trace(*this, loc, ray_origin, ray_dir, hit_pos, fb_pos, hit_normal, out_plane_id);
}
/*
bool Canvas::point_trace_plane(glm::vec2 loc, glm::vec3& hit_pos, glm::vec2& hit_fb_pos, int plane_id)
@@ -2068,52 +2047,20 @@ bool Canvas::point_trace_plane(glm::vec2 loc, glm::vec3& hit_pos, glm::vec2& hit
bool 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)
{
point_unproject(loc, { 0, 0, zw(m_box) }, m_mv, m_proj, ray_origin, ray_dir);
glm::vec3 hit;
float hit_t;
if (ray_intersect(ray_origin, ray_dir, m_plane_origin[plane_id],
m_plane_normal[plane_id], m_plane_tangent[plane_id], hit, hit_t))
{
glm::mat4 plane_camera = glm::lookAt(m_plane_origin[plane_id], m_plane_normal[plane_id], m_plane_tangent[plane_id]);
glm::vec4 plane_local = plane_camera * glm::vec4(hit, 1);
hit_pos = hit;
hit_normal = m_plane_normal[plane_id];
hit_fb_pos.x = -(plane_local.x * 0.5f - 0.5f);
hit_fb_pos.y = (plane_local.y * 0.5f + 0.5f);
return true;
}
return false;
return pp::panopainter::legacy_canvas_point_trace_plane(*this, loc, ray_origin, ray_dir, hit_pos, hit_normal, hit_fb_pos, plane_id);
}
void Canvas::point_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) / zw(vp) * 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 = xyz(wp0 / wp0.w);
out_dir = glm::normalize(xyz(wp1 / wp1.w) - out_origin);
};
pp::panopainter::legacy_canvas_point_unproject(loc, vp, camera, proj, out_origin, out_dir);
}
void Canvas::point_unproject(glm::vec2 loc, glm::vec3& out_origin, glm::vec3& out_dir)
{
auto clip_space = glm::vec2(loc.x, m_vp.w - loc.y - 1.f) / zw(m_vp) * 2.f - 1.f;
auto inv = glm::inverse(m_proj * m_mv);
auto wp0 = inv * glm::vec4(clip_space, 0, 1);
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);
pp::panopainter::legacy_canvas_point_unproject(*this, loc, out_origin, out_dir);
}
glm::vec3 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);
return pp::panopainter::legacy_canvas_point_trace(*this, loc);
}
void Canvas::stroke_commit()
{
@@ -2736,24 +2683,12 @@ void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm:
void Canvas::project2Dpoints(std::vector<vertex_t>& vertices)
{
for (auto& p : vertices)
{
glm::vec3 ro, rd, hit_o, hit_d;
glm::vec2 hit_fb;
int plane_id;
if (point_trace(p.pos, ro, rd, hit_o, hit_fb, hit_d, plane_id))
p.pos = glm::vec4(hit_o, 1);
}
pp::panopainter::legacy_canvas_project_2d_points(*this, vertices);
}
glm::vec3 Canvas::project2Dpoint(glm::vec2 pt)
{
glm::vec3 ro, rd, hit_o, hit_d;
glm::vec2 hit_fb;
int plane_id;
if (point_trace(pt, ro, rd, hit_o, hit_fb, hit_d, plane_id))
return glm::vec4(hit_o, 1);
return glm::vec3(0);
return pp::panopainter::legacy_canvas_project_2d_point(*this, pt);
}
@@ -2762,73 +2697,27 @@ glm::vec3 Canvas::project2Dpoint(glm::vec2 pt)
// this can be used for screen space shapes clipping
std::vector<glm::vec2> Canvas::face_to_shape2D(int plane_index)
{
static std::array<glm::vec4, 4> corners{
glm::vec4(-1.f, +1.f, -1.f, 1.f), // A top-left
glm::vec4(+1.f, +1.f, -1.f, 1.f), // B top-right
glm::vec4(+1.f, -1.f, -1.f, 1.f), // C bottom-right
glm::vec4(-1.f, -1.f, -1.f, 1.f), // D bottom-left
};
// compute points in camera space
std::vector<glm::vec3> pt_cam;
for (auto c : corners)
{
auto pt_world = m_plane_transform[plane_index] * c;
pt_cam.push_back(m_mv * pt_world);
}
// clip at near plane
pt_cam = poly_clip_near(pt_cam, 0.01);
// compute windows space
std::vector<glm::vec2> points;
for (auto p : pt_cam)
{
auto pt_clip = m_proj * glm::vec4(p, 1);
pt_clip = pt_clip / pt_clip.w;
glm::vec2 pt_screen = (glm::vec2(pt_clip) * 0.5f + 0.5f) * zw(m_vp);
pt_screen.y = m_vp.w - pt_screen.y - 1;
points.push_back(pt_screen);
}
return points;
return pp::panopainter::legacy_canvas_face_to_shape_2d(*this, plane_index);
}
void Canvas::push_camera()
{
m_camera_stack.push(get_camera());
pp::panopainter::legacy_canvas_push_camera(*this);
}
void Canvas::pop_camera()
{
if (!m_camera_stack.empty())
{
set_camera(m_camera_stack.top());
m_camera_stack.pop();
}
pp::panopainter::legacy_canvas_pop_camera(*this);
}
CameraData Canvas::get_camera()
{
CameraData c;
c.m_box = m_box;
c.m_mv = m_mv;
c.m_pan = m_pan;
std::copy_n(m_plane_dir, 6, c.m_plane_dir);
std::copy_n(m_plane_unproject, 6, c.m_plane_unproject);
c.m_proj = m_proj;
c.m_vp = m_vp;
return c;
return pp::panopainter::legacy_canvas_get_camera(*this);
}
void Canvas::set_camera(const CameraData& c)
{
m_box = c.m_box;
m_mv = c.m_mv;
m_pan = c.m_pan;
std::copy_n(c.m_plane_dir, 6, m_plane_dir);
std::copy_n(c.m_plane_unproject, 6, m_plane_unproject);
m_proj = c.m_proj;
m_vp = c.m_vp;
pp::panopainter::legacy_canvas_set_camera(*this, c);
}
void Canvas::timelapse_reset_encoder() noexcept