Extract canvas projection helpers and thin preview and node loading
This commit is contained in:
139
src/canvas.cpp
139
src/canvas.cpp
@@ -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
|
||||
|
||||
179
src/legacy_canvas_projection_services.cpp
Normal file
179
src/legacy_canvas_projection_services.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "legacy_canvas_projection_services.h"
|
||||
|
||||
#include "canvas.h"
|
||||
|
||||
namespace pp::panopainter {
|
||||
|
||||
bool legacy_canvas_point_trace(Canvas& canvas, 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)
|
||||
{
|
||||
legacy_canvas_point_unproject(loc, { 0, 0, zw(canvas.m_box) }, canvas.m_mv, canvas.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, canvas.m_plane_origin[i], canvas.m_plane_normal[i], canvas.m_plane_tangent[i], hit, hit_t))
|
||||
{
|
||||
glm::mat4 plane_camera = glm::lookAt(canvas.m_plane_origin[i], canvas.m_plane_normal[i], canvas.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) * canvas.m_width;
|
||||
fb_pos.y = (plane_local.y * 0.5f + 0.5f) * canvas.m_height;
|
||||
hit_pos = hit;
|
||||
hit_normal = canvas.m_plane_normal[i];
|
||||
out_plane_id = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool legacy_canvas_point_trace_plane(Canvas& canvas, 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)
|
||||
{
|
||||
legacy_canvas_point_unproject(loc, { 0, 0, zw(canvas.m_box) }, canvas.m_mv, canvas.m_proj, ray_origin, ray_dir);
|
||||
glm::vec3 hit;
|
||||
float hit_t;
|
||||
if (ray_intersect(ray_origin, ray_dir, canvas.m_plane_origin[plane_id],
|
||||
canvas.m_plane_normal[plane_id], canvas.m_plane_tangent[plane_id], hit, hit_t))
|
||||
{
|
||||
glm::mat4 plane_camera = glm::lookAt(canvas.m_plane_origin[plane_id], canvas.m_plane_normal[plane_id], canvas.m_plane_tangent[plane_id]);
|
||||
glm::vec4 plane_local = plane_camera * glm::vec4(hit, 1);
|
||||
hit_pos = hit;
|
||||
hit_normal = canvas.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;
|
||||
}
|
||||
|
||||
void legacy_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);
|
||||
}
|
||||
|
||||
void legacy_canvas_point_unproject(Canvas& canvas, glm::vec2 loc, glm::vec3& out_origin, glm::vec3& out_dir)
|
||||
{
|
||||
auto clip_space = glm::vec2(loc.x, canvas.m_vp.w - loc.y - 1.f) / zw(canvas.m_vp) * 2.f - 1.f;
|
||||
auto inv = glm::inverse(canvas.m_proj * canvas.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);
|
||||
}
|
||||
|
||||
glm::vec3 legacy_canvas_point_trace(Canvas& canvas, 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 (legacy_canvas_point_trace(canvas, loc, ray_origin, ray_dir, hit_pos, fb_pos, hit_normal, plane_id))
|
||||
return hit_pos;
|
||||
return glm::vec3(0);
|
||||
}
|
||||
|
||||
void legacy_canvas_project_2d_points(Canvas& canvas, 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 (legacy_canvas_point_trace(canvas, p.pos, ro, rd, hit_o, hit_fb, hit_d, plane_id))
|
||||
p.pos = glm::vec4(hit_o, 1);
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 legacy_canvas_project_2d_point(Canvas& canvas, glm::vec2 pt)
|
||||
{
|
||||
glm::vec3 ro, rd, hit_o, hit_d;
|
||||
glm::vec2 hit_fb;
|
||||
int plane_id;
|
||||
if (legacy_canvas_point_trace(canvas, pt, ro, rd, hit_o, hit_fb, hit_d, plane_id))
|
||||
return glm::vec4(hit_o, 1);
|
||||
return glm::vec3(0);
|
||||
}
|
||||
|
||||
std::vector<glm::vec2> legacy_canvas_face_to_shape_2d(const Canvas& canvas, int plane_index)
|
||||
{
|
||||
static std::array<glm::vec4, 4> corners{
|
||||
glm::vec4(-1.f, +1.f, -1.f, 1.f),
|
||||
glm::vec4(+1.f, +1.f, -1.f, 1.f),
|
||||
glm::vec4(+1.f, -1.f, -1.f, 1.f),
|
||||
glm::vec4(-1.f, -1.f, -1.f, 1.f),
|
||||
};
|
||||
|
||||
std::vector<glm::vec3> pt_cam;
|
||||
for (auto c : corners)
|
||||
{
|
||||
auto pt_world = canvas.m_plane_transform[plane_index] * c;
|
||||
pt_cam.push_back(canvas.m_mv * pt_world);
|
||||
}
|
||||
|
||||
pt_cam = poly_clip_near(pt_cam, 0.01f);
|
||||
|
||||
std::vector<glm::vec2> points;
|
||||
for (auto p : pt_cam)
|
||||
{
|
||||
auto pt_clip = canvas.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(canvas.m_vp);
|
||||
pt_screen.y = canvas.m_vp.w - pt_screen.y - 1;
|
||||
points.push_back(pt_screen);
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
void legacy_canvas_push_camera(Canvas& canvas)
|
||||
{
|
||||
canvas.m_camera_stack.push(legacy_canvas_get_camera(canvas));
|
||||
}
|
||||
|
||||
void legacy_canvas_pop_camera(Canvas& canvas)
|
||||
{
|
||||
if (!canvas.m_camera_stack.empty())
|
||||
{
|
||||
legacy_canvas_set_camera(canvas, canvas.m_camera_stack.top());
|
||||
canvas.m_camera_stack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
CameraData legacy_canvas_get_camera(const Canvas& canvas)
|
||||
{
|
||||
CameraData camera;
|
||||
camera.m_box = canvas.m_box;
|
||||
camera.m_mv = canvas.m_mv;
|
||||
camera.m_pan = canvas.m_pan;
|
||||
std::copy_n(canvas.m_plane_dir, 6, camera.m_plane_dir);
|
||||
std::copy_n(canvas.m_plane_unproject, 6, camera.m_plane_unproject);
|
||||
camera.m_proj = canvas.m_proj;
|
||||
camera.m_vp = canvas.m_vp;
|
||||
return camera;
|
||||
}
|
||||
|
||||
void legacy_canvas_set_camera(Canvas& canvas, const CameraData& camera)
|
||||
{
|
||||
canvas.m_box = camera.m_box;
|
||||
canvas.m_mv = camera.m_mv;
|
||||
canvas.m_pan = camera.m_pan;
|
||||
std::copy_n(camera.m_plane_dir, 6, canvas.m_plane_dir);
|
||||
std::copy_n(camera.m_plane_unproject, 6, canvas.m_plane_unproject);
|
||||
canvas.m_proj = camera.m_proj;
|
||||
canvas.m_vp = camera.m_vp;
|
||||
}
|
||||
|
||||
} // namespace pp::panopainter
|
||||
26
src/legacy_canvas_projection_services.h
Normal file
26
src/legacy_canvas_projection_services.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "canvas_modes.h"
|
||||
#include "util.h"
|
||||
|
||||
class Canvas;
|
||||
|
||||
namespace pp::panopainter {
|
||||
|
||||
bool legacy_canvas_point_trace(Canvas& canvas, 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);
|
||||
bool legacy_canvas_point_trace_plane(Canvas& canvas, 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);
|
||||
void legacy_canvas_point_unproject(glm::vec2 loc, glm::vec4 vp, glm::mat4 camera, glm::mat4 proj,
|
||||
glm::vec3& out_origin, glm::vec3& out_dir);
|
||||
void legacy_canvas_point_unproject(Canvas& canvas, glm::vec2 loc, glm::vec3& out_origin, glm::vec3& out_dir);
|
||||
glm::vec3 legacy_canvas_point_trace(Canvas& canvas, glm::vec2 loc);
|
||||
void legacy_canvas_project_2d_points(Canvas& canvas, std::vector<vertex_t>& vertices);
|
||||
glm::vec3 legacy_canvas_project_2d_point(Canvas& canvas, glm::vec2 pt);
|
||||
std::vector<glm::vec2> legacy_canvas_face_to_shape_2d(const Canvas& canvas, int plane_index);
|
||||
void legacy_canvas_push_camera(Canvas& canvas);
|
||||
void legacy_canvas_pop_camera(Canvas& canvas);
|
||||
CameraData legacy_canvas_get_camera(const Canvas& canvas);
|
||||
void legacy_canvas_set_camera(Canvas& canvas, const CameraData& camera);
|
||||
|
||||
} // namespace pp::panopainter
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "legacy_canvas_stroke_services.h"
|
||||
#include "legacy_ui_gl_dispatch.h"
|
||||
#include "paint_renderer/compositor.h"
|
||||
#include "brush.h"
|
||||
#include "texture.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -508,6 +509,38 @@ struct LegacyNodeStrokePreviewPassOrchestrationRequest {
|
||||
glm::mat4 mvp { 1.0f };
|
||||
};
|
||||
|
||||
[[nodiscard]] inline LegacyNodeStrokePreviewPassOrchestrationRequest
|
||||
make_legacy_node_stroke_preview_pass_orchestration_request(
|
||||
pp::renderer::RenderDeviceFeatures features,
|
||||
glm::vec2 preview_size,
|
||||
const Brush& brush,
|
||||
const glm::mat4& mvp) noexcept
|
||||
{
|
||||
return LegacyNodeStrokePreviewPassOrchestrationRequest {
|
||||
.features = features,
|
||||
.preview_size = preview_size,
|
||||
.pattern_scale = brush.m_pattern_scale,
|
||||
.pattern_flipx = brush.m_pattern_flipx,
|
||||
.pattern_flipy = brush.m_pattern_flipy,
|
||||
.pattern_invert = brush.m_pattern_invert,
|
||||
.pattern_brightness = brush.m_pattern_brightness,
|
||||
.pattern_contrast = brush.m_pattern_contrast,
|
||||
.pattern_depth = brush.m_pattern_depth,
|
||||
.pattern_rand_offset = brush.m_pattern_rand_offset,
|
||||
.pattern_enabled = brush.m_pattern_enabled,
|
||||
.pattern_eachsample = brush.m_pattern_eachsample,
|
||||
.tip_mix = brush.m_tip_mix,
|
||||
.tip_wet = brush.m_tip_wet,
|
||||
.tip_noise = brush.m_tip_noise,
|
||||
.dual_enabled = brush.m_dual_enabled,
|
||||
.dual_blend_mode = brush.m_dual_blend_mode,
|
||||
.dual_opacity = brush.m_dual_opacity,
|
||||
.pattern_blend_mode = brush.m_pattern_blend_mode,
|
||||
.blend_mode = brush.m_blend_mode,
|
||||
.mvp = mvp,
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] inline LegacyNodeStrokePreviewPassOrchestrationPlan
|
||||
plan_legacy_node_stroke_preview_pass_orchestration(
|
||||
const LegacyNodeStrokePreviewPassOrchestrationRequest& request) noexcept
|
||||
@@ -595,6 +628,69 @@ struct LegacyNodeStrokePreviewStrokeSetupRequest {
|
||||
int preview_point_count = 100;
|
||||
};
|
||||
|
||||
struct LegacyNodeStrokePreviewPreparedStrokes {
|
||||
Stroke stroke;
|
||||
Stroke dual_stroke;
|
||||
std::shared_ptr<Brush> dual_brush;
|
||||
};
|
||||
|
||||
[[nodiscard]] inline std::shared_ptr<Brush> make_legacy_node_stroke_preview_dual_brush(const Brush& brush)
|
||||
{
|
||||
auto dual_brush = std::make_shared<Brush>();
|
||||
dual_brush->m_tip_scale = brush.m_dual_scale;
|
||||
dual_brush->m_tip_angle = brush.m_dual_angle;
|
||||
dual_brush->m_tip_flow = brush.m_dual_flow;
|
||||
dual_brush->m_tip_opacity = brush.m_dual_opacity;
|
||||
dual_brush->m_tip_flipx = brush.m_dual_flipx;
|
||||
dual_brush->m_tip_flipy = brush.m_dual_flipy;
|
||||
dual_brush->m_tip_invert = brush.m_dual_invert;
|
||||
dual_brush->m_blend_mode = brush.m_dual_blend_mode;
|
||||
dual_brush->m_tip_randflipx = brush.m_dual_randflip;
|
||||
dual_brush->m_tip_randflipy = brush.m_dual_randflip;
|
||||
dual_brush->m_tip_size = brush.m_dual_size * brush.m_tip_size;
|
||||
dual_brush->m_tip_spacing = brush.m_dual_spacing;
|
||||
dual_brush->m_jitter_scatter = brush.m_dual_scatter;
|
||||
dual_brush->m_jitter_scatter_bothaxis = brush.m_dual_scatter_bothaxis;
|
||||
dual_brush->m_jitter_angle = brush.m_dual_rotate;
|
||||
dual_brush->m_tip_texture = brush.m_dual_texture;
|
||||
dual_brush->m_tip_aspect = brush.m_dual_aspect;
|
||||
return dual_brush;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline LegacyNodeStrokePreviewPreparedStrokes prepare_legacy_node_stroke_preview_strokes(
|
||||
const std::shared_ptr<Brush>& brush,
|
||||
const LegacyNodeStrokePreviewStrokeSetupPlan& stroke_setup,
|
||||
float camera_fov,
|
||||
const glm::mat4& camera_rot)
|
||||
{
|
||||
LegacyNodeStrokePreviewPreparedStrokes prepared;
|
||||
prepared.stroke.m_filter_points = false;
|
||||
prepared.stroke.m_max_size = stroke_setup.stroke_max_size;
|
||||
prepared.stroke.m_camera.fov = camera_fov;
|
||||
prepared.stroke.m_camera.rot = camera_rot;
|
||||
prepared.stroke.reset(true);
|
||||
prepared.stroke.start(brush);
|
||||
|
||||
prepared.dual_brush = make_legacy_node_stroke_preview_dual_brush(*brush);
|
||||
if (stroke_setup.dual_enabled) {
|
||||
prepared.dual_stroke.m_filter_points = false;
|
||||
prepared.dual_stroke.m_max_size = stroke_setup.dual_stroke_max_size;
|
||||
prepared.dual_stroke.m_camera.fov = camera_fov;
|
||||
prepared.dual_stroke.m_camera.rot = camera_rot;
|
||||
prepared.dual_stroke.reset(true);
|
||||
prepared.dual_stroke.start(prepared.dual_brush);
|
||||
}
|
||||
|
||||
for (const auto& point : stroke_setup.points) {
|
||||
prepared.stroke.add_point(point.position, point.pressure);
|
||||
if (stroke_setup.dual_enabled) {
|
||||
prepared.dual_stroke.add_point(point.position, point.pressure);
|
||||
}
|
||||
}
|
||||
|
||||
return prepared;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline glm::vec2 evaluate_legacy_node_stroke_preview_bezier(
|
||||
std::vector<glm::vec2> control_points,
|
||||
float t) noexcept
|
||||
|
||||
180
src/legacy_ui_node_loader.cpp
Normal file
180
src/legacy_ui_node_loader.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
#include "pch.h"
|
||||
#include "legacy_ui_node_loader.h"
|
||||
|
||||
#include "log.h"
|
||||
#include "node.h"
|
||||
#include "layout.h"
|
||||
#include "node_about.h"
|
||||
#include "node_border.h"
|
||||
#include "node_button.h"
|
||||
#include "node_button_custom.h"
|
||||
#include "node_canvas.h"
|
||||
#include "node_changelog.h"
|
||||
#include "node_checkbox.h"
|
||||
#include "node_color_quad.h"
|
||||
#include "node_colorwheel.h"
|
||||
#include "node_combobox.h"
|
||||
#include "node_dialog_browse.h"
|
||||
#include "node_dialog_cloud.h"
|
||||
#include "node_dialog_picker.h"
|
||||
#include "node_icon.h"
|
||||
#include "node_image.h"
|
||||
#include "node_image_texture.h"
|
||||
#include "node_metadata.h"
|
||||
#include "node_panel_animation.h"
|
||||
#include "node_panel_brush.h"
|
||||
#include "node_panel_color.h"
|
||||
#include "node_panel_grid.h"
|
||||
#include "node_panel_layer.h"
|
||||
#include "node_panel_quick.h"
|
||||
#include "node_panel_stroke.h"
|
||||
#include "node_popup_menu.h"
|
||||
#include "node_scroll.h"
|
||||
#include "node_slider.h"
|
||||
#include "node_stroke_preview.h"
|
||||
#include "node_text.h"
|
||||
#include "node_text_input.h"
|
||||
#include "node_tool_bucket.h"
|
||||
#include "node_usermanual.h"
|
||||
#include "node_viewport.h"
|
||||
#include "util.h"
|
||||
|
||||
namespace pp::panopainter {
|
||||
namespace {
|
||||
|
||||
bool should_skip_child_for_os(const tinyxml2::XMLElement& x_child)
|
||||
{
|
||||
if (auto os = x_child.Attribute("os"))
|
||||
{
|
||||
auto osv = split(os, ',');
|
||||
if (std::find(osv.begin(), osv.end(), PP_OS) == osv.end())
|
||||
{
|
||||
LOG("Element %s not for this os(%s), skipping", x_child.Name(), PP_OS)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void load_ref_child(Node& parent, const tinyxml2::XMLElement& x_child)
|
||||
{
|
||||
auto ids = x_child.Attribute("id");
|
||||
auto id = const_hash(ids);
|
||||
auto& ref = (*parent.m_manager)[id]->m_children[0];
|
||||
auto n = ref->clone();
|
||||
n->m_nodeID_s = ids;
|
||||
n->m_nodeID = id;
|
||||
parent.add_child(n);
|
||||
}
|
||||
|
||||
void load_text_child(Node& parent, const tinyxml2::XMLElement& x_child)
|
||||
{
|
||||
auto n = new NodeText();
|
||||
parent.add_child(n);
|
||||
n->load_internal(&x_child, true);
|
||||
|
||||
std::string text;
|
||||
auto node = x_child.FirstChild();
|
||||
while (node)
|
||||
{
|
||||
if (auto e = node->ToElement())
|
||||
{
|
||||
if (strcmp(e->Name(), "br") == 0)
|
||||
text.append("\n");
|
||||
}
|
||||
else if (auto t = node->ToText())
|
||||
{
|
||||
text.append(t->Value());
|
||||
}
|
||||
node = node->NextSibling();
|
||||
}
|
||||
|
||||
if (!text.empty())
|
||||
n->set_text(text);
|
||||
}
|
||||
|
||||
Node* instantiate_child_node(std::string_view node_name)
|
||||
{
|
||||
if (node_name == "node") return new Node();
|
||||
if (node_name == "border") return new NodeBorder();
|
||||
if (node_name == "image") return new NodeImage();
|
||||
if (node_name == "image-texture") return new NodeImageTexture();
|
||||
if (node_name == "icon") return new NodeIcon();
|
||||
if (node_name == "text-input") return new NodeTextInput();
|
||||
if (node_name == "button") return new NodeButton();
|
||||
if (node_name == "button-custom") return new NodeButtonCustom();
|
||||
if (node_name == "combobox") return new NodeComboBox();
|
||||
if (node_name == "slider-h") return new NodeSliderH();
|
||||
if (node_name == "slider-v") return new NodeSliderV();
|
||||
if (node_name == "slider-hue") return new NodeSliderHue();
|
||||
if (node_name == "popup-menu") return new NodePopupMenu();
|
||||
if (node_name == "viewport") return new NodeViewport();
|
||||
if (node_name == "checkbox") return new NodeCheckBox();
|
||||
if (node_name == "layer") return new NodeLayer();
|
||||
if (node_name == "panel-layer") return new NodePanelLayer();
|
||||
if (node_name == "panel-brush") return new NodePanelBrush();
|
||||
if (node_name == "panel-color") return new NodePanelColor();
|
||||
if (node_name == "panel-stroke") return new NodePanelStroke();
|
||||
if (node_name == "panel-grid") return new NodePanelGrid();
|
||||
if (node_name == "panel-quick") return new NodePanelQuick();
|
||||
if (node_name == "dialog-browse") return new NodeDialogBrowse();
|
||||
if (node_name == "dialog-browse-item") return new NodeDialogBrowseItem();
|
||||
if (node_name == "dialog-cloud") return new NodeDialogCloud();
|
||||
if (node_name == "dialog-cloud-item") return new NodeDialogCloudItem();
|
||||
if (node_name == "color-picker") return new NodeColorPicker();
|
||||
if (node_name == "about") return new NodeAbout();
|
||||
if (node_name == "changelog") return new NodeChangelog();
|
||||
if (node_name == "usermanual") return new NodeUserManual();
|
||||
if (node_name == "tool-bucket") return new NodeToolBucket();
|
||||
if (node_name == "timeline") return new NodeAnimationTimeline();
|
||||
if (node_name == "stroke-preview") return new NodeStrokePreview();
|
||||
if (node_name == "canvas") return new NodeCanvas();
|
||||
if (node_name == "scroll") return new NodeScroll();
|
||||
if (node_name == "metadata") return new NodeMetadata();
|
||||
if (node_name == "colorwheel") return new NodeColorWheel();
|
||||
if (node_name == "color-quad") return new NodeColorQuad();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void load_typed_child(Node& parent, const tinyxml2::XMLElement& x_child, std::string_view node_name)
|
||||
{
|
||||
if (auto* n = instantiate_child_node(node_name))
|
||||
{
|
||||
parent.add_child(n);
|
||||
n->load_internal(&x_child);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG("instancing UNKNOWN node: %s", x_child.Name());
|
||||
auto* n = new Node();
|
||||
parent.add_child(n);
|
||||
n->load_internal(&x_child);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void load_legacy_ui_children(Node& parent, const tinyxml2::XMLElement& x_node)
|
||||
{
|
||||
auto x_child = x_node.FirstChildElement();
|
||||
while (x_child)
|
||||
{
|
||||
if (should_skip_child_for_os(*x_child))
|
||||
{
|
||||
x_child = x_child->NextSiblingElement();
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string_view node_name = x_child->Name();
|
||||
if (node_name == "ref")
|
||||
load_ref_child(parent, *x_child);
|
||||
else if (node_name == "text")
|
||||
load_text_child(parent, *x_child);
|
||||
else
|
||||
load_typed_child(parent, *x_child, node_name);
|
||||
|
||||
x_child = x_child->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pp::panopainter
|
||||
13
src/legacy_ui_node_loader.h
Normal file
13
src/legacy_ui_node_loader.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
namespace tinyxml2 {
|
||||
class XMLElement;
|
||||
}
|
||||
|
||||
class Node;
|
||||
|
||||
namespace pp::panopainter {
|
||||
|
||||
void load_legacy_ui_children(Node& parent, const tinyxml2::XMLElement& x_node);
|
||||
|
||||
} // namespace pp::panopainter
|
||||
133
src/node.cpp
133
src/node.cpp
@@ -1,43 +1,11 @@
|
||||
#include "pch.h"
|
||||
#include "app.h"
|
||||
#include "log.h"
|
||||
#include "legacy_ui_node_loader.h"
|
||||
#include "node.h"
|
||||
#include "layout.h"
|
||||
#include "util.h"
|
||||
#include "asset.h"
|
||||
#include "node_border.h"
|
||||
#include "node_image.h"
|
||||
#include "node_image_texture.h"
|
||||
#include "node_icon.h"
|
||||
#include "node_text.h"
|
||||
#include "node_text_input.h"
|
||||
#include "node_button.h"
|
||||
#include "node_button_custom.h"
|
||||
#include "node_slider.h"
|
||||
#include "node_popup_menu.h"
|
||||
#include "node_viewport.h"
|
||||
#include "node_checkbox.h"
|
||||
#include "node_panel_layer.h"
|
||||
#include "node_panel_brush.h"
|
||||
#include "node_panel_color.h"
|
||||
#include "node_panel_stroke.h"
|
||||
#include "node_color_quad.h"
|
||||
#include "node_stroke_preview.h"
|
||||
#include "node_canvas.h"
|
||||
#include "node_scroll.h"
|
||||
#include "node_dialog_browse.h"
|
||||
#include "node_dialog_cloud.h"
|
||||
#include "node_combobox.h"
|
||||
#include "node_colorwheel.h"
|
||||
#include "node_dialog_picker.h"
|
||||
#include "node_panel_grid.h"
|
||||
#include "node_about.h"
|
||||
#include "node_changelog.h"
|
||||
#include "node_usermanual.h"
|
||||
#include "node_panel_quick.h"
|
||||
#include "node_tool_bucket.h"
|
||||
#include "node_panel_animation.h"
|
||||
#include "node_metadata.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -1430,104 +1398,7 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node, bool skip_children
|
||||
return;
|
||||
}
|
||||
|
||||
auto x_child = x_node->FirstChildElement();
|
||||
while (x_child)
|
||||
{
|
||||
if (auto os = x_child->Attribute("os"))
|
||||
{
|
||||
auto osv = split(os, ',');
|
||||
if (std::find(osv.begin(), osv.end(), PP_OS) == osv.end())
|
||||
{
|
||||
LOG("Element %s not for this os(%s), skipping", x_child->Name(), PP_OS)
|
||||
x_child = x_child->NextSiblingElement();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
std::string node_name = x_child->Name();
|
||||
if (node_name == "ref")
|
||||
{
|
||||
auto ids = x_child->Attribute("id");
|
||||
auto id = const_hash(ids);
|
||||
auto& ref = (*m_manager)[id]->m_children[0];
|
||||
auto n = ref->clone();
|
||||
n->m_nodeID_s = ids;
|
||||
n->m_nodeID = id;
|
||||
add_child(n);
|
||||
}
|
||||
else if (node_name == "text")
|
||||
{
|
||||
auto n = new NodeText();
|
||||
add_child(n);
|
||||
n->load_internal(x_child, true);
|
||||
std::string text;
|
||||
auto node = x_child->FirstChild();
|
||||
while (node)
|
||||
{
|
||||
if (auto e = node->ToElement())
|
||||
{
|
||||
if (strcmp(e->Name(), "br") == 0)
|
||||
text.append("\n");
|
||||
}
|
||||
else if (auto t = node->ToText())
|
||||
{
|
||||
text.append(t->Value());
|
||||
}
|
||||
node = node->NextSibling();
|
||||
}
|
||||
if (!text.empty())
|
||||
n->set_text(text);
|
||||
}
|
||||
#define CASE(W,C) else if (node_name == W) { auto n = new C(); add_child(n); n->load_internal(x_child); }
|
||||
CASE("node", Node)
|
||||
CASE("border", NodeBorder)
|
||||
CASE("image", NodeImage)
|
||||
CASE("image-texture", NodeImageTexture)
|
||||
CASE("icon", NodeIcon)
|
||||
CASE("text-input", NodeTextInput)
|
||||
CASE("button", NodeButton)
|
||||
CASE("button-custom", NodeButtonCustom)
|
||||
CASE("combobox", NodeComboBox)
|
||||
CASE("slider-h", NodeSliderH)
|
||||
CASE("slider-v", NodeSliderV)
|
||||
CASE("slider-hue", NodeSliderHue)
|
||||
CASE("popup-menu", NodePopupMenu)
|
||||
CASE("viewport", NodeViewport)
|
||||
CASE("checkbox", NodeCheckBox)
|
||||
CASE("layer", NodeLayer)
|
||||
CASE("panel-layer", NodePanelLayer)
|
||||
CASE("panel-brush", NodePanelBrush)
|
||||
CASE("panel-color", NodePanelColor)
|
||||
CASE("panel-stroke", NodePanelStroke)
|
||||
CASE("panel-grid", NodePanelGrid)
|
||||
CASE("panel-quick", NodePanelQuick)
|
||||
CASE("dialog-browse", NodeDialogBrowse)
|
||||
CASE("dialog-browse-item", NodeDialogBrowseItem)
|
||||
CASE("dialog-cloud", NodeDialogCloud)
|
||||
CASE("dialog-cloud-item", NodeDialogCloudItem)
|
||||
CASE("color-picker", NodeColorPicker)
|
||||
CASE("about", NodeAbout)
|
||||
CASE("changelog", NodeChangelog)
|
||||
CASE("usermanual", NodeUserManual)
|
||||
CASE("tool-bucket", NodeToolBucket)
|
||||
CASE("timeline", NodeAnimationTimeline)
|
||||
CASE("stroke-preview", NodeStrokePreview)
|
||||
CASE("canvas", NodeCanvas)
|
||||
CASE("scroll", NodeScroll)
|
||||
CASE("metadata", NodeMetadata)
|
||||
CASE("panel-quick", NodePanelQuick)
|
||||
CASE("colorwheel", NodeColorWheel)
|
||||
CASE("color-quad", NodeColorQuad)
|
||||
#undef CASE
|
||||
else
|
||||
{
|
||||
LOG("instancing UNKNOWN node: %s", x_child->Name());
|
||||
auto n = new Node();
|
||||
add_child(n);
|
||||
n->load_internal(x_child);
|
||||
}
|
||||
x_child = x_child->NextSiblingElement();
|
||||
}
|
||||
pp::panopainter::load_legacy_ui_children(*this, *x_node);
|
||||
loaded();
|
||||
}
|
||||
|
||||
|
||||
@@ -584,84 +584,26 @@ void NodeStrokePreview::draw_stroke_immediate()
|
||||
|
||||
const auto& b = m_brush;
|
||||
|
||||
Stroke m_stroke;
|
||||
Stroke m_dual_stroke;
|
||||
|
||||
m_stroke.m_filter_points = false;
|
||||
m_stroke.m_max_size = stroke_setup.stroke_max_size;
|
||||
m_stroke.m_camera.fov = Canvas::I->m_cam_fov;
|
||||
m_stroke.m_camera.rot = Canvas::I->m_cam_rot;
|
||||
m_stroke.reset(true);
|
||||
m_stroke.start(b);
|
||||
|
||||
auto dual_brush = std::make_shared<Brush>();
|
||||
dual_brush->m_tip_scale = b->m_dual_scale;
|
||||
dual_brush->m_tip_angle = b->m_dual_angle;
|
||||
dual_brush->m_tip_flow = b->m_dual_flow;
|
||||
dual_brush->m_tip_opacity = b->m_dual_opacity;
|
||||
dual_brush->m_tip_flipx = b->m_dual_flipx;
|
||||
dual_brush->m_tip_flipy = b->m_dual_flipy;
|
||||
dual_brush->m_tip_invert = b->m_dual_invert;
|
||||
dual_brush->m_blend_mode = b->m_dual_blend_mode;
|
||||
dual_brush->m_tip_randflipx = b->m_dual_randflip;
|
||||
dual_brush->m_tip_randflipy = b->m_dual_randflip;
|
||||
dual_brush->m_tip_size = b->m_dual_size * b->m_tip_size;
|
||||
dual_brush->m_tip_spacing = b->m_dual_spacing;
|
||||
dual_brush->m_jitter_scatter = b->m_dual_scatter;
|
||||
dual_brush->m_jitter_scatter_bothaxis = b->m_dual_scatter_bothaxis;
|
||||
dual_brush->m_jitter_angle = b->m_dual_rotate;
|
||||
dual_brush->m_tip_texture = b->m_dual_texture;
|
||||
dual_brush->m_tip_aspect = b->m_dual_aspect;
|
||||
|
||||
if (stroke_setup.dual_enabled)
|
||||
{
|
||||
m_dual_stroke.m_filter_points = false;
|
||||
m_dual_stroke.m_max_size = stroke_setup.dual_stroke_max_size;
|
||||
m_dual_stroke.m_camera.fov = Canvas::I->m_cam_fov;
|
||||
m_dual_stroke.m_camera.rot = Canvas::I->m_cam_rot;
|
||||
m_dual_stroke.reset(true);
|
||||
m_dual_stroke.start(dual_brush);
|
||||
}
|
||||
|
||||
for (const auto& point : stroke_setup.points)
|
||||
{
|
||||
m_stroke.add_point(point.position, point.pressure);
|
||||
if (stroke_setup.dual_enabled)
|
||||
m_dual_stroke.add_point(point.position, point.pressure);
|
||||
}
|
||||
auto prepared_strokes = pp::panopainter::prepare_legacy_node_stroke_preview_strokes(
|
||||
b,
|
||||
stroke_setup,
|
||||
Canvas::I->m_cam_fov,
|
||||
Canvas::I->m_cam_rot);
|
||||
|
||||
apply_stroke_preview_capability(pp::renderer::gl::blend_state(), false);
|
||||
const auto pass_orchestration = pp::panopainter::plan_legacy_node_stroke_preview_pass_orchestration(
|
||||
pp::panopainter::LegacyNodeStrokePreviewPassOrchestrationRequest {
|
||||
.features = stroke_preview_render_device_features(),
|
||||
.preview_size = size,
|
||||
.pattern_scale = b->m_pattern_scale,
|
||||
.pattern_flipx = b->m_pattern_flipx,
|
||||
.pattern_flipy = b->m_pattern_flipy,
|
||||
.pattern_invert = b->m_pattern_invert,
|
||||
.pattern_brightness = b->m_pattern_brightness,
|
||||
.pattern_contrast = b->m_pattern_contrast,
|
||||
.pattern_depth = b->m_pattern_depth,
|
||||
.pattern_rand_offset = b->m_pattern_rand_offset,
|
||||
.pattern_enabled = b->m_pattern_enabled,
|
||||
.pattern_eachsample = b->m_pattern_eachsample,
|
||||
.tip_mix = b->m_tip_mix,
|
||||
.tip_wet = b->m_tip_wet,
|
||||
.tip_noise = b->m_tip_noise,
|
||||
.dual_enabled = b->m_dual_enabled,
|
||||
.dual_blend_mode = b->m_dual_blend_mode,
|
||||
.dual_opacity = b->m_dual_opacity,
|
||||
.pattern_blend_mode = b->m_pattern_blend_mode,
|
||||
.blend_mode = b->m_blend_mode,
|
||||
.mvp = ortho_proj,
|
||||
});
|
||||
pp::panopainter::make_legacy_node_stroke_preview_pass_orchestration_request(
|
||||
stroke_preview_render_device_features(),
|
||||
size,
|
||||
*b,
|
||||
ortho_proj));
|
||||
const bool copy_stroke_destination = pass_orchestration.copy_stroke_destination;
|
||||
pp::panopainter::setup_legacy_stroke_shader(pass_orchestration.stroke_shader);
|
||||
execute_stroke_draw_immediate_pass_sequence(
|
||||
m_stroke,
|
||||
m_dual_stroke,
|
||||
prepared_strokes.stroke,
|
||||
prepared_strokes.dual_stroke,
|
||||
*b,
|
||||
std::move(dual_brush),
|
||||
std::move(prepared_strokes.dual_brush),
|
||||
pass_orchestration,
|
||||
copy_stroke_destination,
|
||||
zoom,
|
||||
|
||||
Reference in New Issue
Block a user