disable exceptions in visual studio, use xK notation for resolution, upgrade up to 32K resolution, mask resolution not doubled anymore, transform interactive controls to move, scale and rotate the selection

This commit is contained in:
2018-11-22 19:07:14 +01:00
parent 6f9b1b1c23
commit 86656cc7e3
12 changed files with 218 additions and 146 deletions

View File

@@ -114,6 +114,7 @@
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@@ -155,6 +156,7 @@
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>

View File

@@ -419,11 +419,11 @@
<text text="Resize Document Resolution" font-face="arial" font-size="11"></text> <text text="Resize Document Resolution" font-face="arial" font-size="11"></text>
</border> </border>
<border width="500" color="0 0 0 .9" pad="10" dir="col"> <border width="500" color="0 0 0 .9" pad="10" dir="col">
<text text="This action is permanent and cannot be undone.\nAll of the history will be cleared.\nResolution is measured in pixels per each face of the cube.\nThe output equirectangular will be Resolution x 4 times.\nExample: 1024px will generate a 4096x2048 equirectangular image." font-face="arial" font-size="11" margin="0 5 10 5"/> <text text="This action is permanent and cannot be undone.\nAll of the history will be cleared." font-face="arial" font-size="11" margin="0 5 10 5"/>
<border dir="row" align="center" height="30" color=".2 .2 .2 1"> <border dir="row" align="center" height="30" color=".2 .2 .2 1">
<node grow="1"><text id="current-res" text="Current: 1024px" font-face="arial" font-size="11" margin="0 5 0 5"/></node> <node grow="1"><text id="current-res" text="Current: 2K" font-face="arial" font-size="11" margin="0 5 0 5"/></node>
<text text="New Resolution:" font-face="arial" font-size="11" margin="0 5 0 5"/> <text text="New Resolution:" font-face="arial" font-size="11" margin="0 5 0 5"/>
<combobox id="resolution" width="100" height="30" text="1024" combo-list="512px,1024px,1536px,2048px" default="1"/> <combobox id="resolution" width="100" height="30" text="2K" combo-list="2K,4K,6K,8K,16K,32K" default="1"/>
</border> </border>
<node height="40" grow="1" dir="row" align="flex-end" justify="flex-end"> <node height="40" grow="1" dir="row" align="flex-end" justify="flex-end">
<button id="btn-ok" text="Resize" width="70" height="30" margin="0 10 0 0"/> <button id="btn-ok" text="Resize" width="70" height="30" margin="0 10 0 0"/>
@@ -560,11 +560,11 @@
<text text="Create New Pano Project" font-face="arial" font-size="11"></text> <text text="Create New Pano Project" font-face="arial" font-size="11"></text>
</border> </border>
<border width="500" color="0 0 0 .9" pad="10" dir="col"> <border width="500" color="0 0 0 .9" pad="10" dir="col">
<text text="Note: resolution is measured in pixels per each face of the cube.\nThe output equirectangular will be Resolution x 4 times.\nExample: 1024px will generate a 4096x2048 equirectangular image." font-face="arial" font-size="11" margin="0 5 10 5"/> <text text="Note: resolution is measured in K-pixels, so a 2K document produces\na 2048x1024 equirectangular output." font-face="arial" font-size="11" margin="0 5 10 5"/>
<border dir="row" align="center" height="30" color=".2 .2 .2 1"> <border dir="row" align="center" height="30" color=".2 .2 .2 1">
<text text="Project name: " font-face="arial" font-size="11" margin="0 5 0 5"/> <text text="Project name: " font-face="arial" font-size="11" margin="0 5 0 5"/>
<text-input id="txt-input" align="center" pad="5" grow="1" height="30" color=".3"/> <text-input id="txt-input" align="center" pad="5" grow="1" height="30" color=".3"/>
<combobox id="resolution" width="100" height="30" text="1024" combo-list="512px,1024px,1536px,2048px" default="1"/> <combobox id="resolution" width="100" height="30" text="2K" combo-list="2K,4K,6K,8K,16K,32K" default="1"/>
</border> </border>
<text os="win,osx" id="path" text="Workind dir: path" text-wrap-width="470" font-face="arial" font-size="11" margin="10 5 10 5"/> <text os="win,osx" id="path" text="Workind dir: path" text-wrap-width="470" font-face="arial" font-size="11" margin="10 5 10 5"/>
<node height="40" grow="1" dir="row" align="flex-end" justify="flex-end"> <node height="40" grow="1" dir="row" align="flex-end" justify="flex-end">

View File

@@ -606,6 +606,21 @@ void App::update_rec_frames()
} }
} }
int App::res_from_index(int i)
{
return res_map[i];
}
int App::res_to_index(int res)
{
return std::distance(res_map.begin(), std::find(res_map.begin(), res_map.end(), res));
}
std::string App::res_to_string(int res)
{
return res_map_str[res_to_index(res)];
}
void App::rec_clear() void App::rec_clear()
{ {
rec_stop(); rec_stop();

View File

@@ -71,6 +71,8 @@ public:
Node* current_panel = nullptr; Node* current_panel = nullptr;
NodeScroll* panels; NodeScroll* panels;
const uint16_t main_id = const_hash("main"); const uint16_t main_id = const_hash("main");
const std::array<int, 6> res_map{ 512, 1024, 1536, 2048, 4096, 8192 };
const std::array<std::string, 6> res_map_str{ "2K", "4K", "6K", "8K", "16K", "32K" };
std::string doc_name = "no-name"; std::string doc_name = "no-name";
std::string doc_path; std::string doc_path;
std::string doc_dir; std::string doc_dir;
@@ -192,6 +194,9 @@ public:
void title_update(); void title_update();
void update_memory_usage(size_t bytes); void update_memory_usage(size_t bytes);
void update_rec_frames(); void update_rec_frames();
int res_from_index(int i);
int res_to_index(int res);
std::string res_to_string(int res);
void cmd_convert(std::string pano_path, std::string out_path); void cmd_convert(std::string pano_path, std::string out_path);
}; };

View File

@@ -99,7 +99,7 @@ void App::dialog_newdoc()
} }
auto action = [this, dialog, name, path] { auto action = [this, dialog, name, path] {
std::array<int, 4> resolutions{ 512, 1024, 1536, 2048 }; std::array<int, 6> resolutions{ 512, 1024, 1536, 2048, 4096, 8192 };
int res = resolutions[dialog->m_resolution->m_current_index]; int res = resolutions[dialog->m_resolution->m_current_index];
doc_name = name; doc_name = name;
doc_path = path; doc_path = path;

View File

@@ -14,7 +14,7 @@ static glm::vec4 color_button_hlight{ 1, .0, .0, 1 };
void App::title_update() void App::title_update()
{ {
static char str[256]; static char str[256];
snprintf(str, 256, "Panodoc: %s%s (%dpx)", doc_name.c_str(), canvas->m_canvas->m_unsaved ? "*" : "", canvas->m_canvas->m_width); snprintf(str, 256, "Panodoc: %s%s (%s)", doc_name.c_str(), canvas->m_canvas->m_unsaved ? "*" : "", res_to_string(canvas->m_canvas->m_width).c_str());
if (auto docname = layout[main_id]->find<NodeText>("txt-docname")) if (auto docname = layout[main_id]->find<NodeText>("txt-docname"))
docname->set_text(str); docname->set_text(str);
} }

View File

@@ -78,7 +78,7 @@ bool ui::BrushMesh::create()
if (!(buffers[0] && buffers[1] && buffers[2])) if (!(buffers[0] && buffers[1] && buffers[2]))
return false; return false;
static instance_t inst{ glm::mat4(), .1f }; static instance_t inst{ glm::mat4(1), .1f };
glBindBuffer(GL_ARRAY_BUFFER, buffers[2]); glBindBuffer(GL_ARRAY_BUFFER, buffers[2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(instance_t), &inst, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(instance_t), &inst, GL_STATIC_DRAW);

View File

@@ -1010,7 +1010,7 @@ void ui::Canvas::resize(int width, int height)
} }
for (auto& l : m_layers) for (auto& l : m_layers)
l.resize(width, height); l.resize(width, height);
m_smask.create(width*2, height*2, "mask"); m_smask.create(width, height, "mask");
m_unsaved = true; m_unsaved = true;
} }
bool ui::Canvas::create(int width, int height) bool ui::Canvas::create(int width, int height)
@@ -1046,7 +1046,7 @@ bool ui::Canvas::create(int width, int height)
{ {
l.create(width, height, ""); l.create(width, height, "");
} }
m_smask.create(width*2, height*2, "mask"); m_smask.create(width, height, "mask");
//m_smask.clear({1, 1, 1, 1}); //m_smask.clear({1, 1, 1, 1});
m_unsaved = true; m_unsaved = true;
return true; return true;

View File

@@ -449,7 +449,7 @@ void CanvasModeMaskFree::init()
void CanvasModeMaskFree::leave() void CanvasModeMaskFree::leave()
{ {
// canvas->draw_objects(std::bind(&CanvasModeFill::on_Draw, this, glm::mat4(), std::placeholders::_1, std::placeholders::_2)); // canvas->draw_objects(std::bind(&CanvasModeFill::on_Draw, this, glm::mat4(1), std::placeholders::_1, std::placeholders::_2));
// m_points.clear(); // m_points.clear();
} }
@@ -843,65 +843,91 @@ 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_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_circle.create<16>(1.f);
m_shape.create(); for (int i = 0; i < 6; i++)
m_shape[i].create();
m_xform = glm::mat4(1); m_xform = glm::mat4(1);
m_xform_local = glm::mat4(1);
} }
void CanvasModeTransform::enter() void CanvasModeTransform::enter()
{ {
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]);
int plane = 0; canvas->m_smask_active = false;
auto face = canvas->face_to_shape2D(plane); auto points = std::move(m->m_points2d);
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; glm::vec2 bb_min(FLT_MAX);
v.pos = glm::vec4(xyz(p3d_world), 1); glm::vec2 bb_max(-FLT_MAX);
v.uvs = p2d_plane_raster; for (auto p2d : points)
shape3d.push_back(v); {
bb_min = glm::min(bb_min, p2d);
bb_max = glm::max(bb_max, p2d);
} }
auto bb_sz = bb_max - bb_min; glm::vec2 midpoint = (bb_min + bb_max) * 0.5f;
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); 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)); auto center_mat = 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))); m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(midpoint), xyz(cam_up)));
m_xform_local = glm::mat4(1);
corners.clear();
corners.emplace_back(bb_min, 0);
corners.emplace_back(bb_max, 0);
corners.emplace_back(bb_max.x, bb_min.y, 0);
corners.emplace_back(bb_min.x, bb_max.y, 0);
corners.emplace_back(midpoint, 0);
corners.emplace_back(midpoint + (bb_max-bb_min) * glm::vec2(0.75f, 0), 0);
for (auto& c : corners)
c = center_mat * glm::vec4(canvas->point_trace(c), 1);
shape3d = canvas->triangulate(shape3d); for (int plane = 0; plane < 6; plane++)
m_shape.update_vertices(shape3d.data(), shape3d.size()); {
auto face = canvas->face_to_shape2D(plane);
auto shape2d = poly_intersect(points, face);
if (shape2d.size() < 3)
{
m_shape[plane].update_vertices(nullptr, 0);
continue;
}
std::vector<vertex_t> shape3d;
shape3d.reserve(shape2d.size());
glm::vec2 bb_min(canvas->m_size);
glm::vec2 bb_max(0, 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);
auto p3d_plane = canvas->m_plane_unproject[plane] * glm::vec4(p2d_clip, 0, 1);
auto p2d_plane = (-xy(p3d_plane) / p3d_plane.z);
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);
canvas->m_layers[canvas->m_current_layer_idx].m_rtt[plane].bindFramebuffer(); //glm::vec3 pt_o, pt_d;
m_tex.create(bb_sz.x, bb_sz.y); //canvas->point_unproject(p2d, pt_o, pt_d);
m_tex.bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bb_min.x, bb_min.y, bb_sz.x, bb_sz.y); vertex_t v;
m_tex.unbind(); v.pos = glm::vec4(xyz(p3d_world), 1);
canvas->m_layers[canvas->m_current_layer_idx].m_rtt[plane].unbindFramebuffer(); 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;
auto center3d = canvas->point_trace(midpoint);
for (auto& v : shape3d)
{
v.uvs = (v.uvs - bb_min) / bb_sz;
v.pos = center_mat * v.pos;
}
shape3d = canvas->triangulate(shape3d);
m_shape[plane].update_vertices(shape3d.data(), shape3d.size());
canvas->m_layers[canvas->m_current_layer_idx].m_rtt[plane].bindFramebuffer();
m_tex[plane].create(bb_sz.x, bb_sz.y);
m_tex[plane].bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bb_min.x, bb_min.y, bb_sz.x, bb_sz.y);
m_tex[plane].unbind();
canvas->m_layers[canvas->m_current_layer_idx].m_rtt[plane].unbindFramebuffer();
}
} }
void CanvasModeTransform::leave() void CanvasModeTransform::leave()
@@ -926,18 +952,21 @@ void CanvasModeTransform::leave()
glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), canvas->m_plane_origin[i], canvas->m_plane_tangent[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(); layer.m_rtt[i].bindFramebuffer();
ui::ShaderManager::use(ui::kShader::Color); for (int j = 0; j < 6; j++)
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform); {
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 1, 1, .1 }); ui::ShaderManager::use(ui::kShader::Color);
m_shape.draw_fill(); ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform * m_xform_local);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 1, 1, .1 });
m_shape[j].draw_fill();
ui::ShaderManager::use(ui::kShader::Texture); ui::ShaderManager::use(ui::kShader::Texture);
ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0); ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform); ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform * m_xform_local);
m_tex.bind(); m_tex[j].bind();
canvas->m_sampler.bind(0); canvas->m_sampler.bind(0);
m_shape.draw_fill(); m_shape[j].draw_fill();
m_tex.unbind(); m_tex[j].unbind();
}
layer.m_rtt[i].unbindFramebuffer(); layer.m_rtt[i].unbindFramebuffer();
} }
@@ -971,34 +1000,42 @@ void CanvasModeTransform::on_Draw(const glm::mat4& ortho, const glm::mat4& proj,
auto face = canvas->face_to_shape2D(0); auto face = canvas->face_to_shape2D(0);
auto shape = poly_intersect(m->m_points2d, face); auto shape = poly_intersect(m->m_points2d, face);
// 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); glEnable(GL_BLEND);
ui::ShaderManager::use(ui::kShader::Texture); for (int i = 0; i < 6; i++)
ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0); {
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera * m_xform); //ui::ShaderManager::use(ui::kShader::UVs);
glActiveTexture(GL_TEXTURE0); ui::ShaderManager::use(ui::kShader::Color);
m_tex.bind(); ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera * m_xform * m_xform_local);
canvas->m_sampler.bind(0); ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 1, 1, .1 });
m_shape.draw_fill(); m_shape[i].draw_fill();
m_tex.unbind();
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 * m_xform_local);
glActiveTexture(GL_TEXTURE0);
m_tex[i].bind();
canvas->m_sampler.bind(0);
m_shape[i].draw_fill();
m_tex[i].unbind();
}
auto m2d = canvas->m_proj * canvas->m_mv * m_xform * m_xform_local;
for (int i = 0; i < corners.size(); i++)
{
auto c = m2d * glm::vec4(corners[i], 1);
auto c2d = ((xy(c) / c.z) * 0.5f + 0.5f) * zw(canvas->m_box);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, ortho * glm::translate(glm::vec3(c2d, 0)) * glm::scale(glm::vec3(10.f)));
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, i == corner_hl ? 1.f : .5f });
m_circle.draw_fill();
}
if (depth) glEnable(GL_DEPTH_TEST); if (depth) glEnable(GL_DEPTH_TEST);
} }
void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc) void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
{ {
auto m2d = glm::scale(glm::vec3(1, -1, 1)) * canvas->m_proj * canvas->m_mv * m_xform * m_xform_local;
switch (me->m_type) switch (me->m_type)
{ {
case kEventType::MouseDownR: case kEventType::MouseDownR:
@@ -1009,21 +1046,57 @@ void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
m_dragging = false; m_dragging = false;
break; break;
case kEventType::MouseDownL: case kEventType::MouseDownL:
m_dragging = true; if (corner_hl != -1)
m_drag_start = loc; {
m_drag_xform = m_xform; m_dragging = true;
//m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(loc), { 0, 1, 0 })); m_drag_start = loc;
m_drag_xform = m_xform;
m_drag_xform_local = m_xform_local;
m_drag_corner = corner_hl;
m_drag_corners2d = corners2d;
if (m_drag_corner < 4)
{
m_drag_diag = glm::distance(corners2d[4], corners2d[m_drag_corner]);
}
}
break; break;
case kEventType::MouseMove: case kEventType::MouseMove:
{ {
corner_hl = -1;
corners2d.resize(corners.size());
for (int i = 0; i < corners.size(); i++)
{
auto c = m2d * glm::vec4(corners[i], 1);
corners2d[i] = ((xy(c) / c.z) * 0.5f + 0.5f) * zw(canvas->m_box);
float d = glm::distance(corners2d[i], loc);
if (d < 10)
corner_hl = i;
}
if (m_dragging) if (m_dragging)
{ {
auto cam_up = glm::inverse(canvas->m_mv) * glm::vec4(0, 1, 0, 1);
//auto diff = glm::radians(loc - m_drag_start) * 0.1f; //auto diff = glm::radians(loc - m_drag_start) * 0.1f;
//auto m = glm::eulerAngleXY(-diff.y, -diff.x); //auto m = glm::eulerAngleXY(-diff.y, -diff.x);
//m_xform = m * m_drag_xform; //m_xform = m * m_drag_xform;
auto cam_up = glm::inverse(canvas->m_mv) * glm::vec4(0, 1, 0, 1); if (m_drag_corner > -1 && m_drag_corner < 4)
m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(loc), xyz(cam_up))); {
auto diag = glm::distance(corners2d[4], loc);
auto scale = diag / m_drag_diag;
m_xform_local = m_drag_xform_local * glm::scale(glm::vec3(scale, scale, 1));
}
if (m_drag_corner == 4)
{
m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(loc), xyz(cam_up)));
}
if (m_drag_corner == 5)
{
auto a = glm::normalize(m_drag_corners2d[m_drag_corner] - m_drag_corners2d[4]);
auto b = glm::normalize(loc - m_drag_corners2d[4]);
auto angle = glm::orientedAngle(a, b);
m_xform_local = m_drag_xform_local * glm::eulerAngleZ(-angle);
}
} }
/*
{ {
auto p2d = loc; auto p2d = loc;
//p2d.y = canvas->m_box.w - p2d.y - 1; //p2d.y = canvas->m_box.w - p2d.y - 1;
@@ -1034,39 +1107,7 @@ void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
int x = 0; int x = 0;
LOG("pt %f %f %f %f", p2d_plane.x, p2d_plane.y, p2d_plane.z, p2d_plane.w); 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);
float r = glm::length(m_center_point);
float lat = glm::acos(m_center_point.z / r);
float lon = glm::atan(m_center_point.y, m_center_point.x);
m_center_point_uv = { lat, lon };
//LOG("pt lat-lon %f %f", lat, lon);
auto face = canvas->face_to_shape2D(0);
if (face.size() > 2)
{
std::vector<vertex_t> quad{
vertex_t{{200, 200}, {0, 0}},
vertex_t{{200, 400}, {0, 1}},
vertex_t{{400, 400}, {1, 1}},
vertex_t{{400, 200}, {1, 0}},
};
auto poly = poly_intersect(quad, face);
m_points2d.clear();
if (!poly.empty())
{
std::vector<std::shared_ptr<p2t::Point>> points;
for (auto& v : poly)
{
v.pos.y = canvas->m_box.w - v.pos.y - 1;
m_points2d.push_back(v.pos);
points.push_back(std::make_shared<p2t::Point>(v.pos.x, v.pos.y));
}
auto vert = canvas->triangulate(poly);
//m_shape.update_vertices(vert.data(), vert.size());
}
}
} }
break; break;

View File

@@ -21,6 +21,8 @@ public:
virtual void init() {} virtual void init() {}
virtual void enter() {} virtual void enter() {}
virtual void leave() {} virtual void leave() {}
CanvasMode() = default;
virtual ~CanvasMode() = default;
}; };
class CanvasModeBasicCamera : public CanvasMode class CanvasModeBasicCamera : public CanvasMode
@@ -146,26 +148,34 @@ public:
class CanvasModeTransform : public CanvasMode class CanvasModeTransform : public CanvasMode
{ {
ui::DynamicShape m_shape; ui::DynamicShape m_shape[6]{};
ui::Sphere m_sphere; ui::Sphere m_sphere{};
ui::Circle m_circle; ui::Circle m_circle{};
Texture2D m_tex; Texture2D m_tex[6]{};
glm::vec3 m_origin{0, 0, 1 }; glm::vec3 m_origin{0, 0, 1 };
glm::vec3 m_center_point; std::vector<glm::vec3> corners{};
glm::vec2 m_center_point_uv; std::vector<glm::vec2> corners2d{};
glm::mat4 m_xform; int corner_hl = -1;
glm::vec3 m_center_point{};
glm::vec2 m_center_point_uv{};
glm::mat4 m_xform{};
glm::mat4 m_xform_local{};
int m_counter = 0; int m_counter = 0;
bool m_dragging = false; bool m_dragging = false;
glm::vec2 m_drag_start; int m_drag_corner = -1;
glm::mat4 m_drag_xform; float m_drag_diag = 0;
std::vector<vertex_t> m_points; std::vector<glm::vec2> m_drag_corners2d{};
std::vector<glm::vec2> m_points2d; glm::vec2 m_drag_start{};
std::map<int, int> m_dirty_planes; glm::mat4 m_drag_xform{};
glm::mat4 m_drag_xform_local{};
std::vector<vertex_t> m_points{};
std::vector<glm::vec2> m_points2d{};
std::map<int, int> m_dirty_planes{};
bool m_active_tool = false; bool m_active_tool = false;
public: public:
CanvasModeTransform() = default; CanvasModeTransform() = default;
virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override;; virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override;
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;; virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
virtual void init() override;; virtual void init() override;;
virtual void enter() override; virtual void enter() override;
virtual void leave() override; virtual void leave() override;

View File

@@ -34,7 +34,7 @@ void NodeDialogResize::init_controls()
text = find<NodeText>("current-res"); text = find<NodeText>("current-res");
resolution = ui::Canvas::I->m_width; resolution = ui::Canvas::I->m_width;
static char txt[128]; static char txt[128];
sprintf(txt, "Current: %dpx", resolution); sprintf(txt, "Current: %s", App::I.res_to_string(resolution));
text->set_text(txt); text->set_text(txt);
btn_cancel->on_click = [this](Node*) { btn_cancel->on_click = [this](Node*) {
destroy(); destroy();
@@ -50,5 +50,5 @@ void NodeDialogResize::loaded()
int NodeDialogResize::get_resolution() int NodeDialogResize::get_resolution()
{ {
return combo ? res_map[combo->m_current_index] : 512; return combo ? App::I.res_from_index(combo->m_current_index) : 512;
} }

View File

@@ -7,7 +7,6 @@
class NodeDialogResize : public NodeBorder class NodeDialogResize : public NodeBorder
{ {
public: public:
const std::array<int, 4> res_map{512, 1024, 1536, 2048};
NodeButton* btn_cancel; NodeButton* btn_cancel;
NodeButton* btn_ok; NodeButton* btn_ok;
NodeComboBox* combo; NodeComboBox* combo;