From 3c55e2543272d1ff0c961c5ef35648abdde9fee8 Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Mon, 30 Nov 2020 00:25:02 +0100 Subject: [PATCH] Finally a working implementation of crop and UV manipulation in AppearanceView! Added saving and loading. --- SessionCreator.cpp | 6 ++-- SessionVisitor.cpp | 8 ++--- Source.cpp | 19 ++++------- Source.h | 5 ++- View.cpp | 85 ++++++++-------------------------------------- View.h | 9 ++--- 6 files changed, 32 insertions(+), 100 deletions(-) diff --git a/SessionCreator.cpp b/SessionCreator.cpp index 3eb86bd..02cb462 100644 --- a/SessionCreator.cpp +++ b/SessionCreator.cpp @@ -431,9 +431,6 @@ void SessionLoader::visit(ImageShader &n) uniforms->QueryUnsignedAttribute("mask", &n.mask); } -// XMLElement* uvtex = xmlCurrent_->FirstChildElement("uv"); -// if (uvtex) -// tinyxml2::XMLElementToGLM( uvtex->FirstChildElement("vec4"), n.uv); } void SessionLoader::visit(ImageProcessingShader &n) @@ -485,6 +482,9 @@ void SessionLoader::visit (Source& s) xmlCurrent_ = sourceNode->FirstChildElement("Appearance"); s.groupNode(View::APPEARANCE)->accept(*this); + xmlCurrent_ = sourceNode->FirstChildElement("Crop"); + s.texturesurface_->accept(*this); + xmlCurrent_ = sourceNode->FirstChildElement("Blending"); s.blendingShader()->accept(*this); diff --git a/SessionVisitor.cpp b/SessionVisitor.cpp index a6bedd4..25b8a0f 100644 --- a/SessionVisitor.cpp +++ b/SessionVisitor.cpp @@ -202,10 +202,6 @@ void SessionVisitor::visit(ImageShader &n) uniforms->SetAttribute("mask", n.mask); xmlCurrent_->InsertEndChild(uniforms); -// XMLElement *uvtex = xmlDoc_->NewElement("uv"); -// uvtex->InsertEndChild( XMLElementFromGLM(xmlDoc_, n.uv) ); -// xmlCurrent_->InsertEndChild(uvtex); - } void SessionVisitor::visit(ImageProcessingShader &n) @@ -347,6 +343,10 @@ void SessionVisitor::visit (Source& s) sourceNode->InsertEndChild(xmlCurrent_); s.groupNode(View::APPEARANCE)->accept(*this); + xmlCurrent_ = xmlDoc_->NewElement("Crop"); + sourceNode->InsertEndChild(xmlCurrent_); + s.texturesurface_->accept(*this); + xmlCurrent_ = xmlDoc_->NewElement( "Blending" ); sourceNode->InsertEndChild(xmlCurrent_); s.blendingShader()->accept(*this); diff --git a/Source.cpp b/Source.cpp index 78dff8a..3da28b9 100644 --- a/Source.cpp +++ b/Source.cpp @@ -186,7 +186,6 @@ Source::Source() : initialized_(false), active_(true), need_update_(true), symbo // - crop & repeat UV can be managed here // - additional custom shader can be associated texturesurface_ = new Surface(renderingshader_); - crop_ = glm::vec2(1.f, 1.f); // will be created at init renderbuffer_ = nullptr; @@ -441,19 +440,19 @@ void Source::update(float dt) static glm::mat4 UVtoScene = GlmToolkit::transform(glm::vec3(1.f, -1.f, 0.f), glm::vec3(0.f, 0.f, 0.f), glm::vec3(-2.f, 2.f, 1.f)); - + // make sure to update rendering texture surface node + texturesurface_->update(dt); // Aspect Ratio correction transform : coordinates of Appearance Frame are scaled by render buffer width glm::mat4 Ar = glm::identity(); if (renderbuffer_) - Ar = glm::scale(glm::identity(), glm::vec3(renderbuffer_->aspectRatio() * crop_.x, crop_.y, 1.f) ); + Ar = glm::scale(glm::identity(), glm::vec3(renderbuffer_->aspectRatio() * texturesurface_->scale_.x, texturesurface_->scale_.y, 1.f) ); // Translation : same as Appearance Frame (modified by Ar) glm::mat4 Tra = glm::translate(glm::identity(), groups_[View::APPEARANCE]->translation_); // Scaling : inverse scaling (larger UV when smaller Appearance Frame) - glm::mat4 Sca = glm::scale(glm::identity(), glm::vec3( crop_.x / groups_[View::APPEARANCE]->scale_.x, - crop_.y / groups_[View::APPEARANCE]->scale_.y, 1.f)); + glm::mat4 Sca = glm::scale(glm::identity(), glm::vec3( texturesurface_->scale_.x / groups_[View::APPEARANCE]->scale_.x, + texturesurface_->scale_.y / groups_[View::APPEARANCE]->scale_.y, 1.f)); // Rotation : same angle than Appearance Frame, inverted axis glm::mat4 Rot = glm::rotate(glm::identity(), groups_[View::APPEARANCE]->rotation_.z, glm::vec3(0.f, 0.f, -1.f) ); - // Combine transformations (non transitive) in this order: // 1. switch to Scene coordinate system // 2. Apply the aspect ratio correction @@ -464,13 +463,7 @@ void Source::update(float dt) // 7. switch back to UV coordinate system texturesurface_->shader()->iTransform = glm::inverse(UVtoScene) * Sca * glm::inverse(Ar) * Rot * Tra * Ar * UVtoScene; -// // MODIFY CROP -// if (renderbuffer_) { -// glm::vec2 crop = renderbuffer_->projectionArea(); -// groups_[View::MIXING]->scale_.x *= crop.x / crop.y; -// groups_[View::LAYER]->scale_.x = crop.x / crop.y; -// } - + // do not update next frame need_update_ = false; } } diff --git a/Source.h b/Source.h index fd78357..f5e6627 100644 --- a/Source.h +++ b/Source.h @@ -138,6 +138,8 @@ public: virtual glm::ivec2 icon () const { return glm::ivec2(12, 11); } + // surface to draw on + Surface *texturesurface_; protected: // name std::string name_; @@ -169,9 +171,6 @@ protected: // blendingshader provides mixing controls ImageShader *blendingshader_; - // surface to draw on - Surface *texturesurface_; - glm::vec2 crop_; // mode for display Mode mode_; diff --git a/View.cpp b/View.cpp index 7a2cb9c..508c77f 100644 --- a/View.cpp +++ b/View.cpp @@ -1771,8 +1771,12 @@ AppearanceView::AppearanceView() : View(APPEARANCE), edit_source_(nullptr), need tmp->shader()->color = glm::vec4( 0.1f, 0.1f, 0.1f, 0.6f ); scene.bg()->attach(tmp); // frame showing the source original shape - backgroundframe_ = new Surface( new Shader); - backgroundframe_->shader()->color = glm::vec4( COLOR_BGROUND, 1.0f ); + backgroundchecker_ = new ImageSurface("images/checker.dds"); + static glm::mat4 Tra = glm::scale(glm::translate(glm::identity(), glm::vec3( -32.f, -32.f, 0.f)), glm::vec3( 64.f, 64.f, 1.f)); + backgroundchecker_->shader()->iTransform = Tra; + scene.bg()->attach(backgroundchecker_); + backgroundframe_ = new Frame(Frame::SHARP, Frame::THIN, Frame::GLOW); + backgroundframe_->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f ); scene.bg()->attach(backgroundframe_); // Horizontal axis horizontal_line_ = new Mesh("mesh/h_line.ply"); @@ -1803,23 +1807,13 @@ AppearanceView::AppearanceView() : View(APPEARANCE), edit_source_(nullptr), need vertical_line_->attach(mark); scene.bg()->attach(vertical_line_); - // surface showing the source transparency background - backgroundpreview = new ImageSurface("images/checker.dds"); - static glm::mat4 Tra = glm::scale(glm::translate(glm::identity(), glm::vec3( -32.f, -32.f, 0.f)), glm::vec3( 64.f, 64.f, 1.f)); - backgroundpreview->shader()->iTransform = Tra; - backgroundpreview->translation_.z = 0.001f; - scene.bg()->attach(backgroundpreview); // surface to show the texture of the source surfacepreview = new Surface; // to attach source preview surfacepreview->translation_.z = 0.002f; scene.bg()->attach(surfacepreview); - // Geometry Scene foreground + // Scene foreground // - // frame showing the edited source shape - foregroundframe_ = new Frame(Frame::SHARP, Frame::LARGE, Frame::GLOW); - foregroundframe_->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f ); - scene.fg()->attach(foregroundframe_); // crop icons crop_horizontal_ = new Symbol(Symbol::CROP); crop_horizontal_->translation_ = glm::vec3(1.0f, 1.1f, 0.f); @@ -1828,6 +1822,7 @@ AppearanceView::AppearanceView() : View(APPEARANCE), edit_source_(nullptr), need crop_vertical_->rotation_.z = M_PI_2; crop_vertical_->translation_ = glm::vec3(-1.1f, -1.0f, 0.f); scene.fg()->attach(crop_vertical_); + // User interface foreground // // point to show POSITION @@ -2034,11 +2029,9 @@ void AppearanceView::adjustBackground() image_original_width = edit_source_->frame()->aspectRatio(); surfacepreview->setTextureIndex( edit_source_->frame()->texture() ); -// image_crop_area = edit_source_->frame()->projectionArea(); - image_crop_area = edit_source_->crop_; + image_crop_area = glm::vec2(edit_source_->texturesurface_->scale_); surfacepreview->scale_.x = image_original_width; - image_crop_area.x *= image_original_width; } @@ -2048,20 +2041,15 @@ void AppearanceView::adjustBackground() horizontal_line_->scale_.x = image_original_width; vertical_line_->translation_.x = -image_original_width; backgroundframe_->scale_.x = image_original_width; - - // background of preview -// surfacepreview->scale_ = glm::vec3(image_crop_area, 1.f); - backgroundpreview->scale_ = glm::vec3(image_crop_area, 1.f); - backgroundpreview->update(0); - glm::mat4 Ar = glm::scale(glm::identity(), glm::vec3(image_crop_area, 1.f) ); + backgroundchecker_->scale_.x = image_original_width; + glm::mat4 Ar = glm::scale(glm::identity(), glm::vec3(image_original_width, 1.f, 1.f) ); static glm::mat4 Tra = glm::scale(glm::translate(glm::identity(), glm::vec3( -32.f, -32.f, 0.f)), glm::vec3( 64.f, 64.f, 1.f)); - backgroundpreview->shader()->iTransform = Ar * Tra; + backgroundchecker_->shader()->iTransform = Ar * Tra; // foreground crop_horizontal_->translation_.x = image_crop_area.x; crop_vertical_->translation_.y = -image_crop_area.y; crop_vertical_->translation_.x = -image_original_width - 0.1f; - foregroundframe_->scale_ = glm::vec3(image_crop_area, 1.f); } @@ -2115,10 +2103,6 @@ void AppearanceView::draw() // force to redraw the frame of the edit source (even if source is not visible) DrawVisitor dv(edit_source_->frames_[mode_], Rendering::manager().Projection(), true); scene.accept(dv); - -// float edit_width = edit_source_->frame()->aspectRatio(); -// glm::vec2 cropped = edit_source_->frame()->projectionArea(); -// crop_horizontal_->translation_.x = cropped.x * edit_width; } } @@ -2136,49 +2120,21 @@ View::Cursor AppearanceView::grab (Source *s, glm::vec2 from, glm::vec2 to, std: // work on the edited source if ( edit_source_ != nullptr ) { - // make sure matrix transform of stored status is updated -// Group *sourceNode = edit_source_->group(View::GEOMETRY); // groups_[View::GEOMETRY] -// edit_source_status_.update(0); - // picking on the resizing handles in the corners if ( pick.first == crop_horizontal_ ) { - // crop horizontally -// glm::vec2 cropped = edit_source_->frame()->projectionArea(); -// float max_width = edit_source_->frame()->aspectRatio(); -// cropped.x = CLAMP(scene_to.x, 0.2f, max_width) / max_width; -// edit_source_->frame()->setProjectionArea(cropped); - float max_width = edit_source_->frame()->aspectRatio(); - edit_source_->crop_.x = CLAMP(scene_to.x, 0.2f, max_width) / max_width; - - // TODO scale GEOMETRY and RENDER groups - edit_source_->texturesurface_->scale_.x = edit_source_->crop_.x; - edit_source_->texturesurface_->update(0); - -// edit_source_->group(View::GEOMETRY)->scale_ = edit_source_status_.scale_ * glm::vec3(cropped, 1.f); + edit_source_->texturesurface_->scale_.x = CLAMP(scene_to.x, 0.2f, max_width) / max_width; edit_source_->touch(); - // update background and frame adjustBackground(); // cursor indication ret.type = Cursor_ResizeEW; } if ( pick.first == crop_vertical_ ) { - -// // crop vertically -// glm::vec2 cropped = edit_source_->frame()->projectionArea(); -// cropped.y = -1.f * CLAMP(scene_to.y, -1.f, -0.2f); -// edit_source_->frame()->setProjectionArea(cropped); - - edit_source_->crop_.y = -1.f * CLAMP(scene_to.y, -1.f, -0.2f); - - // TODO scale GEOMETRY and RENDER groups - edit_source_->texturesurface_->scale_.y = edit_source_->crop_.y; - edit_source_->texturesurface_->update(0); - + // crop vertically + edit_source_->texturesurface_->scale_.y = -1.f * CLAMP(scene_to.y, -1.f, -0.2f); edit_source_->touch(); - // update background and frame adjustBackground(); // cursor indication @@ -2477,17 +2433,6 @@ View::Cursor AppearanceView::grab (Source *s, glm::vec2 from, glm::vec2 to, std: } -//void AppearanceView::initiate() -//{ -// View::initiate(); - -//Log::Info("AppearanceView::initiate") ; -// if ( edit_source_ != nullptr ) { -// Log::Info("store edit_source_status_") ; -// edit_source_status_.copyTransform(edit_source_->group(View::GEOMETRY)); -// } -//} - void AppearanceView::terminate() { View::terminate(); diff --git a/View.h b/View.h index c9a2170..087b78b 100644 --- a/View.h +++ b/View.h @@ -239,23 +239,18 @@ public: std::pair pick(glm::vec2 P) override; Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair pick) override; Cursor drag (glm::vec2, glm::vec2) override; -// void initiate() override; void terminate() override; private: Source *edit_source_; - Group edit_source_status_; bool need_edit_update_; Source *getEditOrCurrentSource(); - void adjustBackground(); - Surface *backgroundpreview; Surface *surfacepreview; - - Surface *backgroundframe_; - Frame *foregroundframe_; + Surface *backgroundchecker_; + Frame *backgroundframe_; Mesh *horizontal_line_; Group *vertical_line_; Symbol *crop_horizontal_;