From 20cafa388f12ff9efe7e16e483b517177f3a7e1a Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Sat, 16 May 2020 12:06:52 +0200 Subject: [PATCH] Initial implementation of handles on sources to manipulate in geometry view (only resize implemented so far) --- CMakeLists.txt | 1 + FrameBuffer.cpp | 1 - GlmToolkit.cpp | 136 ++++ GlmToolkit.h | 48 ++ ImGuiVisitor.h | 7 - Mesh.cpp | 119 ++- Mesh.h | 40 +- PickingVisitor.cpp | 72 +- PickingVisitor.h | 26 +- Primitives.cpp | 28 +- Scene.cpp | 19 +- Scene.h | 10 +- SearchVisitor.h | 14 +- SessionCreator.cpp | 4 +- SessionCreator.h | 1 - SessionVisitor.cpp | 4 +- Source.cpp | 63 +- Source.h | 16 +- UserInterfaceManager.cpp | 45 +- UserInterfaceManager.h | 1 + View.cpp | 153 ++-- View.h | 6 +- Visitor.h | 30 +- rsc/mesh/border_handles_overlay.ply | 40 +- rsc/mesh/border_large_sharp.ply | 16 +- rsc/mesh/icon_image.ply | 1102 ++++++++++++++++++++++++--- 26 files changed, 1623 insertions(+), 379 deletions(-) create mode 100644 GlmToolkit.cpp create mode 100644 GlmToolkit.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 591cb95..163759c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -226,6 +226,7 @@ set(VMIX_SRCS ImGuiToolkit.cpp ImGuiVisitor.cpp GstToolkit.cpp + GlmToolkit.cpp SystemToolkit.cpp tinyxml2Toolkit.cpp ) diff --git a/FrameBuffer.cpp b/FrameBuffer.cpp index 5b867ac..af8b720 100644 --- a/FrameBuffer.cpp +++ b/FrameBuffer.cpp @@ -20,7 +20,6 @@ glm::vec3 FrameBuffer::getResolutionFromParameters(int ar, int h) return res; } - FrameBuffer::FrameBuffer(glm::vec3 resolution): textureid_(0), framebufferid_(0), usedepth_(false) { attrib_.viewport = glm::ivec2(resolution); diff --git a/GlmToolkit.cpp b/GlmToolkit.cpp new file mode 100644 index 0000000..3a89a9b --- /dev/null +++ b/GlmToolkit.cpp @@ -0,0 +1,136 @@ +// Freely inspired from https://github.com/alter-rokuz/glm-aabb.git + +#include "GlmToolkit.h" + +#include +#include +#include + +glm::mat4 GlmToolkit::transform(glm::vec3 translation, glm::vec3 rotation, glm::vec3 scale) +{ + glm::mat4 View = glm::translate(glm::identity(), translation); + View = glm::rotate(View, rotation.x, glm::vec3(1.f, 0.f, 0.f)); + View = glm::rotate(View, rotation.y, glm::vec3(0.f, 1.f, 0.f)); + View = glm::rotate(View, rotation.z, glm::vec3(0.f, 0.f, 1.f)); + glm::mat4 Model = glm::scale(glm::identity(), scale); + return View * Model; +} + + +GlmToolkit::AxisAlignedBoundingBox::AxisAlignedBoundingBox() { + mMin = glm::vec3(1.f); + mMax = glm::vec3(-1.f); +} + +void GlmToolkit::AxisAlignedBoundingBox::extend(const glm::vec3& point) +{ + if (isNull()) { + mMin = point; + mMax = point; + } + // general case + else { + mMin = glm::min(point, mMin); + mMax = glm::max(point, mMax); + } +} + +void GlmToolkit::AxisAlignedBoundingBox::extend(std::vector points) +{ + for (auto p = points.begin(); p != points.end(); p++) + extend(*p); +} + + +void GlmToolkit::AxisAlignedBoundingBox::extend(const AxisAlignedBoundingBox& bb) +{ + if (bb.isNull()) + return; + + if (isNull()) { + mMin = bb.mMin; + mMax = bb.mMax; + } + // general case + else { + mMin = glm::min(bb.mMin, mMin); + mMax = glm::max(bb.mMax, mMax); + } +} + +glm::vec3 GlmToolkit::AxisAlignedBoundingBox::center() const +{ + if (!isNull()) + { + glm::vec3 d = mMax - mMin; + return mMin + (d * 0.5f); + } + else + { + return glm::vec3(0.f); + } +} + +bool GlmToolkit::AxisAlignedBoundingBox::intersect(const AxisAlignedBoundingBox& bb, bool ignore_z) const +{ + if (isNull() || bb.isNull()) + return false; + + if ( (mMax.x < bb.mMin.x) || (mMin.x > bb.mMax.x) || + (mMax.y < bb.mMin.y) || (mMin.y > bb.mMax.y) || + ( !ignore_z && ((mMax.z < bb.mMin.z) || (mMin.z > bb.mMax.z)) ) ) + { + return false; + } + + return true; +} + +bool GlmToolkit::AxisAlignedBoundingBox::contains(const AxisAlignedBoundingBox& bb, bool ignore_z) const +{ + if ( !intersect(bb, ignore_z)) + return false; + + if ( (mMin.x <= bb.mMin.x) && (mMax.x >= bb.mMax.x) && + (mMin.y <= bb.mMin.y) && (mMax.y >= bb.mMax.y) && + ( ignore_z || ((mMin.z <= bb.mMin.z) && (mMax.z >= bb.mMax.z)) ) ) + { + return true; + } + + return false; +} + +bool GlmToolkit::AxisAlignedBoundingBox::contains(glm::vec3 point, bool ignore_z) const +{ + if ( (mMax.x < point.x) || (mMin.x > point.x) || + (mMax.y < point.y) || (mMin.y > point.y) || + ( !ignore_z && ((mMax.z < point.z) || (mMin.z > point.z)) ) ) + return false; + + return true; +} + + +GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::translated(glm::vec3 t) +{ + GlmToolkit::AxisAlignedBoundingBox bb; + bb = *this; + + bb.mMin += t; + bb.mMax += t; + + return bb; +} + +GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::scaled(glm::vec3 s) +{ + GlmToolkit::AxisAlignedBoundingBox bb; + bb = *this; + + bb.mMin *= s; + bb.mMax *= s; + + return bb; +} + diff --git a/GlmToolkit.h b/GlmToolkit.h new file mode 100644 index 0000000..1f7b8fb --- /dev/null +++ b/GlmToolkit.h @@ -0,0 +1,48 @@ +#ifndef GLMTOOLKIT_H +#define GLMTOOLKIT_H + + +#include +#include + +namespace GlmToolkit +{ + +glm::mat4 transform(glm::vec3 translation, glm::vec3 rotation, glm::vec3 scale); + + +class AxisAlignedBoundingBox +{ + glm::vec3 mMin; + glm::vec3 mMax; + +public: + AxisAlignedBoundingBox(); + + void operator = (const AxisAlignedBoundingBox &D ) { + mMin = D.mMin; + mMax = D.mMax; + } + + // test + inline bool isNull() const { return mMin.x > mMax.x || mMin.y > mMax.y || mMin.z > mMax.z;} + inline glm::vec3 min() const { return mMin; } + inline glm::vec3 max() const { return mMax; } + glm::vec3 center() const; + bool intersect(const AxisAlignedBoundingBox& bb, bool ignore_z = true) const; + bool contains(const AxisAlignedBoundingBox& bb, bool ignore_z = true) const; + bool contains(glm::vec3 point, bool ignore_z = true) const; + + // build + void extend(const glm::vec3& point); + void extend(std::vector points); + void extend(const AxisAlignedBoundingBox& bb); + + AxisAlignedBoundingBox translated(glm::vec3 t); + AxisAlignedBoundingBox scaled(glm::vec3 s); +}; + +} + + +#endif // GLMTOOLKIT_H diff --git a/ImGuiVisitor.h b/ImGuiVisitor.h index e81569a..2e6823e 100644 --- a/ImGuiVisitor.h +++ b/ImGuiVisitor.h @@ -15,15 +15,8 @@ public: void visit(Switch& n) override; void visit(Animation& n) override; void visit(Primitive& n) override; - void visit(Surface&) override {} - void visit(ImageSurface&) override {} void visit(MediaSurface& n) override; void visit(FrameBufferSurface& n) override; - void visit(LineStrip&) override {} - void visit(LineSquare&) override {} - void visit(LineCircle&) override {} - void visit(Mesh&) override {} - void visit(Frame&) override {} // Elements with attributes void visit(MediaPlayer& n) override; diff --git a/Mesh.cpp b/Mesh.cpp index cf0bd41..2553d5f 100644 --- a/Mesh.cpp +++ b/Mesh.cpp @@ -8,11 +8,14 @@ #include +#include + #include "Resource.h" #include "ImageShader.h" #include "Visitor.h" #include "Log.h" #include "Mesh.h" +#include "GlmToolkit.h" using namespace std; using namespace glm; @@ -321,6 +324,7 @@ bool parsePLY(string ascii, } + Mesh::Mesh(const std::string& ply_path, const std::string& tex_path) : Primitive(), mesh_resource_(ply_path), texture_resource_(tex_path), textureindex_(0) { if ( !parsePLY( Resource::getText(mesh_resource_), points_, colors_, texCoords_, indices_, drawMode_) ) @@ -361,12 +365,14 @@ void Mesh::draw(glm::mat4 modelview, glm::mat4 projection) if ( !initialized() ) init(); - if (textureindex_) - glBindTexture(GL_TEXTURE_2D, textureindex_); + if ( visible_ ) { + if (textureindex_) + glBindTexture(GL_TEXTURE_2D, textureindex_); - Primitive::draw(modelview, projection); + Primitive::draw(modelview, projection); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D, 0); + } } void Mesh::accept(Visitor& v) @@ -375,19 +381,17 @@ void Mesh::accept(Visitor& v) v.visit(*this); } -Frame::Frame(Style style) : Node() +Frame::Frame(Type style) : Node() { - overlay_ = nullptr; - shadow_ = nullptr; color = glm::vec4( 1.f, 1.f, 1.f, 1.f); switch (style) { - case SHARP_HANDLES: - border_ = new Mesh("mesh/border_handles_sharp.ply"); - overlay_ = new Mesh("mesh/border_handles_overlay.ply"); + case SHARP_LARGE: + border_ = new Mesh("mesh/border_large_sharp.ply"); shadow_ = new Mesh("mesh/shadow.ply", "images/shadow.png"); break; case SHARP_THIN: border_ = new Mesh("mesh/border_sharp.ply"); + shadow_ = nullptr; break; case ROUND_LARGE: border_ = new Mesh("mesh/border_large_round.ply"); @@ -403,7 +407,6 @@ Frame::Frame(Style style) : Node() Frame::~Frame() { - if(overlay_) delete overlay_; if(border_) delete border_; if(shadow_) delete shadow_; } @@ -411,29 +414,23 @@ Frame::~Frame() void Frame::draw(glm::mat4 modelview, glm::mat4 projection) { if ( !initialized() ) { - if(overlay_) overlay_->init(); if(border_) border_->init(); if(shadow_) shadow_->init(); init(); } - if ( visible_ ) { // not absolutely necessary but saves some CPU time.. + if ( visible_ ) { // shadow if(shadow_) shadow_->draw( modelview * transform_, projection); - if (overlay_) { - // overlat is not altered - overlay_->shader()->color = color; - overlay_->draw( modelview, projection ); - } - // right side float ar = scale_.x / scale_.y; - glm::vec3 s(scale_.y, scale_.y, 1.0); - glm::vec3 t(translation_.x - 1.0 +ar, translation_.y, translation_.z); - glm::mat4 ctm = modelview * transform(t, rotation_, s); + glm::vec3 s(1.f, 1.f, 1.f); +// glm::vec3 s(scale_.y, scale_.y, 1.0); + glm::vec3 t(translation_.x - 1.0 + ar, translation_.y, translation_.z); + glm::mat4 ctm = modelview * GlmToolkit::transform(t, rotation_, s); if(border_) { // right side @@ -442,7 +439,7 @@ void Frame::draw(glm::mat4 modelview, glm::mat4 projection) // left side t.x = -t.x; s.x = -s.x; - ctm = modelview * transform(t, rotation_, s); + ctm = modelview * GlmToolkit::transform(t, rotation_, s); border_->draw( ctm, projection ); } @@ -455,3 +452,79 @@ void Frame::accept(Visitor& v) Node::accept(v); v.visit(*this); } + +Handles::Handles(Type type) : Node(), type_(type) +{ + color = glm::vec4( 1.f, 1.f, 1.f, 1.f); + handle_ = new Mesh("mesh/border_handles_overlay.ply"); +} + +Handles::~Handles() +{ + if(handle_) delete handle_; +} + +void Handles::draw(glm::mat4 modelview, glm::mat4 projection) +{ + if ( !initialized() ) { + if(handle_) handle_->init(); + init(); + } + + if ( visible_ ) { + // set color + handle_->shader()->color = color; + + float ar = scale_.x / scale_.y; + glm::mat4 ctm; + + if ( type_ == RESIZE ) { + // 4 corners + ctm = modelview * glm::translate(glm::identity(), glm::vec3(ar, -1.f, 0.f) ); + ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f; + handle_->draw( ctm, projection ); + + ctm = modelview * glm::translate(glm::identity(), glm::vec3(ar, +1.f, 0.f)); + ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f; + handle_->draw( ctm, projection ); + + ctm = modelview * glm::translate(glm::identity(), glm::vec3(-ar, -1.f, 0.f)); + ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f; + handle_->draw( ctm, projection ); + + ctm = modelview * glm::translate(glm::identity(), glm::vec3(-ar, +1.f, 0.f)); + ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f; + handle_->draw( ctm, projection ); + } + else if ( type_ == RESIZE_H ){ + // left and right + ctm = modelview * glm::translate(glm::identity(), glm::vec3(ar, 0.f, 0.f) ); + ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f; + handle_->draw( ctm, projection ); + + ctm = modelview * glm::translate(glm::identity(), glm::vec3(-ar, 0.f, 0.f)); + ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f; + handle_->draw( ctm, projection ); + } + else if ( type_ == RESIZE_V ){ + // top and bottom + ctm = modelview * glm::translate(glm::identity(), glm::vec3(0.f, +1.f, 0.f) ); + ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f; + handle_->draw( ctm, projection ); + + ctm = modelview * glm::translate(glm::identity(), glm::vec3(0.f, -1.f, 0.f)); + ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f; + handle_->draw( ctm, projection ); + } + else if ( type_ == ROTATE ){ + + } + } +} + + +void Handles::accept(Visitor& v) +{ + Node::accept(v); + v.visit(*this); +} diff --git a/Mesh.h b/Mesh.h index fddac9c..5bc963d 100644 --- a/Mesh.h +++ b/Mesh.h @@ -36,20 +36,48 @@ protected: class Frame : public Node { - Mesh *border_; - Mesh *shadow_; - public: - typedef enum { ROUND_THIN = 0, ROUND_LARGE, SHARP_THIN, SHARP_HANDLES } Style; - Frame(Style style); + typedef enum { ROUND_THIN = 0, ROUND_LARGE, SHARP_THIN, SHARP_LARGE } Type; + Frame(Type style); ~Frame(); void draw (glm::mat4 modelview, glm::mat4 projection) override; void accept (Visitor& v) override; - Mesh *overlay_; + Type type() const { return type_; } + Mesh *border() const { return border_; } glm::vec4 color; + +protected: + Mesh *border_; + Mesh *shadow_; + Type type_; + }; +class Handles : public Node +{ +public: + typedef enum { RESIZE = 0, RESIZE_H, RESIZE_V, ROTATE } Type; + Handles(Type type); + ~Handles(); + + void draw (glm::mat4 modelview, glm::mat4 projection) override; + void accept (Visitor& v) override; + + Type type() const { return type_; } + Mesh *handle() const { return handle_; } + glm::vec4 color; + +protected: + Mesh *handle_; + Type type_; + +}; + +// TODO Shadow mesh with unique vao +// TODO dedicated source .cpp .h files for Frame and Handles + + #endif // MESH_H diff --git a/PickingVisitor.cpp b/PickingVisitor.cpp index 198c3ed..055bc89 100644 --- a/PickingVisitor.cpp +++ b/PickingVisitor.cpp @@ -2,6 +2,7 @@ #include "Log.h" #include "Primitives.h" +#include "GlmToolkit.h" #include "Mesh.h" #include @@ -17,8 +18,9 @@ PickingVisitor::PickingVisitor(glm::vec2 coordinates) : Visitor(), point_(coordi void PickingVisitor::visit(Node &n) { + // use the transform modified during update + modelview_ *= n.transform_; - modelview_ *= n.transform_; // modelview_ *= transform(n.translation_, n.rotation_, n.scale_); // Log::Info("Node %d", n.id()); // Log::Info("%s", glm::to_string(modelview_).c_str()); @@ -27,9 +29,9 @@ void PickingVisitor::visit(Node &n) void PickingVisitor::visit(Group &n) { glm::mat4 mv = modelview_; -//Log::Info("Group %d", n.id()); for (NodeSet::iterator node = n.begin(); node != n.end(); node++) { - (*node)->accept(*this); + if ( (*node)->visible_ ) + (*node)->accept(*this); modelview_ = mv; } } @@ -41,33 +43,71 @@ void PickingVisitor::visit(Switch &n) modelview_ = mv; } -void PickingVisitor::visit(Animation &n) -{ - -} - void PickingVisitor::visit(Primitive &n) { + // TODO: generic visitor for primitive with random shape } void PickingVisitor::visit(Surface &n) { -// Log::Info("Surface %d", n.id()); + if (!n.visible_) + return; + // apply inverse transform to the point of interest glm::vec4 P = glm::inverse(modelview_) * glm::vec4( point_, 0.f, 1.f ); - // lower left corner - glm::vec3 LL = glm::vec3( -1.f, -1.f, 0.f ); - // up right corner - glm::vec3 UR = glm::vec3( 1.f, 1.f, 0.f ); - - // if P is inside [LL UR] rectangle: - if ( P.x > LL.x && P.x < UR.x && P.y > LL.y && P.y < UR.y ) + // test bounding box: it is an exact fit for a resctangular surface + if ( n.bbox().contains( glm::vec3(P)) ) // add this surface to the nodes picked nodes_.push_back( std::pair(&n, glm::vec2(P)) ); } +void PickingVisitor::visit(Frame &n) +{ + n.border()->accept(*this); +} + +void PickingVisitor::visit(Handles &n) +{ + if (!n.visible_) + return; + + // apply inverse transform to the point of interest + glm::vec4 P = glm::inverse(modelview_) * glm::vec4( point_, 0.f, 1.f ); + + // get the bounding box of a handle + GlmToolkit::AxisAlignedBoundingBox bb = n.handle()->bbox(); + + // test picking depending on type of handle + bool picked = false; + if ( n.type() == Handles::RESIZE ) { + // 4 corners + picked = ( bb.translated(glm::vec3(+1.f, +1.f, 0.f)).contains( glm::vec3(P) ) || + bb.translated(glm::vec3(+1.f, -1.f, 0.f)).contains( glm::vec3(P) ) || + bb.translated(glm::vec3(-1.f, +1.f, 0.f)).contains( glm::vec3(P) ) || + bb.translated(glm::vec3(-1.f, -1.f, 0.f)).contains( glm::vec3(P) ) ); + } + else if ( n.type() == Handles::RESIZE_H ){ + // left & right + picked = ( bb.translated(glm::vec3(+1.f, 0.f, 0.f)).contains( glm::vec3(P) ) || + bb.translated(glm::vec3(-1.f, 0.f, 0.f)).contains( glm::vec3(P) ) ); + } + else if ( n.type() == Handles::RESIZE_V ){ + // top & bottom + picked = ( bb.translated(glm::vec3(0.f, +1.f, 0.f)).contains( glm::vec3(P) ) || + bb.translated(glm::vec3(0.f, -1.f, 0.f)).contains( glm::vec3(P) ) ); + } + else if ( n.type() == Handles::ROTATE ){ + // TODO Picking Rotation + } + + if ( picked ) + // add this surface to the nodes picked + nodes_.push_back( std::pair(&n, glm::vec2(P)) ); + +} + void PickingVisitor::visit(LineSquare &) { // apply inverse transform to the point of interest diff --git a/PickingVisitor.h b/PickingVisitor.h index 70b50cf..d253240 100644 --- a/PickingVisitor.h +++ b/PickingVisitor.h @@ -20,21 +20,17 @@ public: std::vector< std::pair > picked() { return nodes_; } // Elements of Scene - void visit(Scene& n); - void visit(Node& n); - void visit(Group& n); - void visit(Switch& n); - void visit(Animation& n); - void visit(Primitive& n); - void visit(Surface& n); - void visit(ImageSurface&){} - void visit(MediaSurface&){} - void visit(FrameBufferSurface&){} - void visit(LineStrip&){} - void visit(LineSquare&); - void visit(LineCircle& n); - void visit(Mesh&){} - void visit(Frame&){} + void visit(Scene& n) override; + void visit(Node& n) override; + void visit(Group& n) override; + void visit(Switch& n) override; + void visit(Primitive& n) override; + void visit(Surface& n) override; + void visit(Frame& n) override; + void visit(Handles& n) override; + void visit(LineSquare&) override; + void visit(LineCircle& n) override; + }; #endif // PICKINGVISITOR_H diff --git a/Primitives.cpp b/Primitives.cpp index 01e0cf3..aa6e484 100644 --- a/Primitives.cpp +++ b/Primitives.cpp @@ -66,6 +66,9 @@ void Surface::init() unique_drawCount = drawCount_; // 3. unique_vao_ will NOT be deleted } + + // replace AxisAlignedBoundingBox + bbox_.extend(square_points); } void Surface::accept(Visitor& v) @@ -220,6 +223,8 @@ void Points::draw(glm::mat4 modelview, glm::mat4 projection) glPointSize(pointsize_); Primitive::draw(modelview, projection); + + glPointSize(1); } void Points::accept(Visitor& v) @@ -248,6 +253,8 @@ void LineStrip::draw(glm::mat4 modelview, glm::mat4 projection) glLineWidth(linewidth_); Primitive::draw(modelview, projection); + + glLineWidth(1); } void LineStrip::accept(Visitor& v) @@ -272,6 +279,11 @@ void LineSquare::init() // 2. use the global vertex array object vao_ = unique_vao_; drawCount_ = unique_drawCount; + // arrays of vertices are not needed anymore (STATIC DRAW of vertex object) + points_.clear(); + colors_.clear(); + texCoords_.clear(); + indices_.clear(); } else { // 1. init the Primitive (only once) @@ -279,8 +291,10 @@ void LineSquare::init() // 2. remember global vertex array object unique_vao_ = vao_; unique_drawCount = drawCount_; - // 3. unique_vao_ will NOT be deleted because LineCircle::deleteGLBuffers_() is empty } + + // compute AxisAlignedBoundingBox + bbox_.extend(square_points); } void LineSquare::accept(Visitor& v) @@ -300,6 +314,7 @@ LineCircle::LineCircle(glm::vec4 color, uint linewidth) : LineStrip(std::vector< { static int N = 72; static float a = glm::two_pi() / static_cast(N); + // loop to build a circle glm::vec3 P(1.f, 0.f, 0.f); for (int i = 0; i < N ; i++ ){ points_.push_back( glm::vec3(P) ); @@ -308,7 +323,7 @@ LineCircle::LineCircle(glm::vec4 color, uint linewidth) : LineStrip(std::vector< P = glm::rotateZ(P, a); } - // loop + // close loop points_.push_back( glm::vec3(1.f, 0.f, 0.f) ); colors_.push_back( color ); indices_.push_back ( N ); @@ -324,7 +339,14 @@ void LineCircle::init() Node::init(); // 2. use the global vertex array object vao_ = unique_vao_; - drawCount_ = unique_drawCount; + drawCount_ = unique_drawCount; + // replace AxisAlignedBoundingBox + bbox_.extend(points_); + // arrays of vertices are not needed anymore (STATIC DRAW of vertex object) + points_.clear(); + colors_.clear(); + texCoords_.clear(); + indices_.clear(); } else { // 1. init the Primitive (only once) diff --git a/Scene.cpp b/Scene.cpp index d8d64d8..fe5a176 100644 --- a/Scene.cpp +++ b/Scene.cpp @@ -5,7 +5,7 @@ #include "Visitor.h" #include "GarbageVisitor.h" #include "Log.h" - +#include "GlmToolkit.h" #include "SessionVisitor.h" #include @@ -20,18 +20,6 @@ #include -//Group *Scene::limbo = new Group; - -glm::mat4 transform(glm::vec3 translation, glm::vec3 rotation, glm::vec3 scale) -{ - glm::mat4 View = glm::translate(glm::identity(), translation); - View = glm::rotate(View, rotation.x, glm::vec3(1.f, 0.f, 0.f)); - View = glm::rotate(View, rotation.y, glm::vec3(0.f, 1.f, 0.f)); - View = glm::rotate(View, rotation.z, glm::vec3(0.f, 0.f, 1.f)); - glm::mat4 Model = glm::scale(glm::identity(), scale); - return View * Model; -} - // Node Node::Node() : initialized_(false), visible_(true), refcount_(0) { @@ -63,7 +51,7 @@ void Node::copyTransform(Node *other) void Node::update( float ) { // update transform matrix from attributes - transform_ = transform(translation_, rotation_, scale_); + transform_ = GlmToolkit::transform(translation_, rotation_, scale_); } @@ -137,6 +125,9 @@ void Primitive::init() if ( elementBuffer_ ) glDeleteBuffers ( 1, &elementBuffer_); + // compute AxisAlignedBoundingBox + bbox_.extend(points_); + // arrays of vertices are not needed anymore (STATIC DRAW of vertex object) points_.clear(); colors_.clear(); diff --git a/Scene.h b/Scene.h index 86d8006..2a3ee16 100644 --- a/Scene.h +++ b/Scene.h @@ -10,16 +10,14 @@ #include #include #include -#include -glm::mat4 transform(glm::vec3 translation, glm::vec3 rotation, glm::vec3 scale); +#include "GlmToolkit.h" // Forward declare classes referenced class Shader; class Visitor; class Group; - /** * @brief The Node class is the base virtual class for all Node types * @@ -104,14 +102,16 @@ public: inline Shader *shader () const { return shader_; } void replaceShader (Shader* newshader); + GlmToolkit::AxisAlignedBoundingBox bbox() const { return bbox_; } + protected: Shader* shader_; uint vao_, drawMode_, drawCount_; std::vector points_; std::vector colors_; std::vector texCoords_; - std::vector indices_; - + std::vector indices_; + GlmToolkit::AxisAlignedBoundingBox bbox_; }; // diff --git a/SearchVisitor.h b/SearchVisitor.h index 85175de..128fd64 100644 --- a/SearchVisitor.h +++ b/SearchVisitor.h @@ -18,22 +18,10 @@ public: // Elements of Scene void visit(Scene& n); void visit(Node& n); + void visit(Primitive&) {} void visit(Group& n); void visit(Switch& n); - // already a Node or a Group - void visit(Animation&) {} - void visit(Primitive&) {} - void visit(Surface&) {} - void visit(ImageSurface&) {} - void visit(MediaSurface&) {} - void visit(FrameBufferSurface&) {} - void visit(LineStrip&) {} - void visit(LineSquare&) {} - void visit(LineCircle&) {} - void visit(Mesh&) {} - void visit(Frame&) {} - }; #endif // SEARCHVISITOR_H diff --git a/SessionCreator.cpp b/SessionCreator.cpp index ddfcfaa..a9edbbf 100644 --- a/SessionCreator.cpp +++ b/SessionCreator.cpp @@ -187,10 +187,10 @@ void SessionCreator::visit (Source& s) s.setName(pName); xmlCurrent_ = sourceNode->FirstChildElement("Mixing"); - s.node(View::MIXING)->accept(*this); + s.groupNode(View::MIXING)->accept(*this); xmlCurrent_ = sourceNode->FirstChildElement("Geometry"); - s.node(View::GEOMETRY)->accept(*this); + s.groupNode(View::GEOMETRY)->accept(*this); xmlCurrent_ = sourceNode->FirstChildElement("Blending"); s.blendingShader()->accept(*this); diff --git a/SessionCreator.h b/SessionCreator.h index 789f9b2..7fd541e 100644 --- a/SessionCreator.h +++ b/SessionCreator.h @@ -37,7 +37,6 @@ public: void visit(LineSquare&) override {} void visit(LineCircle& n) override {} void visit(Mesh& n) override {} - void visit(Frame& n) override {} // Elements with attributes void visit(MediaPlayer& n) override; diff --git a/SessionVisitor.cpp b/SessionVisitor.cpp index 2b5de6c..c5d15ef 100644 --- a/SessionVisitor.cpp +++ b/SessionVisitor.cpp @@ -305,11 +305,11 @@ void SessionVisitor::visit (Source& s) xmlCurrent_ = xmlDoc_->NewElement( "Mixing" ); sourceNode->InsertEndChild(xmlCurrent_); - s.node(View::MIXING)->accept(*this); + s.groupNode(View::MIXING)->accept(*this); xmlCurrent_ = xmlDoc_->NewElement( "Geometry" ); sourceNode->InsertEndChild(xmlCurrent_); - s.node(View::GEOMETRY)->accept(*this); + s.groupNode(View::GEOMETRY)->accept(*this); xmlCurrent_ = xmlDoc_->NewElement( "Blending" ); sourceNode->InsertEndChild(xmlCurrent_); diff --git a/Source.cpp b/Source.cpp index 230cb4e..57d1d82 100644 --- a/Source.cpp +++ b/Source.cpp @@ -31,6 +31,11 @@ Source::Source(const std::string &name) : name_(name), initialized_(false) groups_[View::MIXING]->attach(frame); groups_[View::MIXING]->scale_ = glm::vec3(0.15f, 0.15f, 1.f); + overlays_[View::MIXING] = new Group; + overlays_[View::MIXING]->translation_.z = 0.1; + overlays_[View::MIXING]->visible_ = false; + groups_[View::MIXING]->attach(overlays_[View::MIXING]); + // default geometry nodes groups_[View::GEOMETRY] = new Group; frame = new Frame(Frame::SHARP_THIN); @@ -38,11 +43,20 @@ Source::Source(const std::string &name) : name_(name), initialized_(false) frame->color = glm::vec4( 0.8f, 0.8f, 0.0f, 0.9f); groups_[View::GEOMETRY]->attach(frame); + overlays_[View::GEOMETRY] = new Group; + overlays_[View::GEOMETRY]->translation_.z = 0.1; + overlays_[View::GEOMETRY]->visible_ = false; + groups_[View::GEOMETRY]->attach(overlays_[View::GEOMETRY]); + // will be associated to nodes later blendingshader_ = new ImageShader; rendershader_ = new ImageProcessingShader; renderbuffer_ = nullptr; rendersurface_ = nullptr; + resize_handle_ = nullptr; + resize_H_handle_ = nullptr; + resize_V_handle_ = nullptr; + rotate_handle_ = nullptr; } Source::~Source() @@ -82,6 +96,19 @@ void Source::setOverlayVisible(bool on) (*o).second->visible_ = on; } +Handles *Source::handleNode(Handles::Type t) const +{ + if ( t == Handles::ROTATE ) + return rotate_handle_; + else if ( t == Handles::RESIZE_H ) + return resize_H_handle_; + else if ( t == Handles::RESIZE_V ) + return resize_V_handle_; + else + return resize_handle_; +} + + bool hasNode::operator()(const Source* elem) const { if (elem) @@ -112,18 +139,29 @@ MediaSource::MediaSource(const std::string &name) : Source(name), path_("") mediasurface_ = new Surface(rendershader_); // extra overlay for mixing view - overlays_[View::MIXING] = new Frame(Frame::ROUND_LARGE); - overlays_[View::MIXING]->translation_.z = 0.1; - overlays_[View::MIXING]->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f); - overlays_[View::MIXING]->visible_ = false; - groups_[View::MIXING]->attach(overlays_[View::MIXING]); + Frame *frame = new Frame(Frame::ROUND_LARGE); + frame->translation_.z = 0.1; + frame->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f); + overlays_[View::MIXING]->attach(frame); // extra overlay for geometry view - overlays_[View::GEOMETRY] = new Frame(Frame::SHARP_HANDLES); - overlays_[View::GEOMETRY]->translation_.z = 0.1; - overlays_[View::GEOMETRY]->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f); - overlays_[View::GEOMETRY]->visible_ = false; - groups_[View::GEOMETRY]->attach(overlays_[View::GEOMETRY]); + frame = new Frame(Frame::SHARP_LARGE); + frame->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f); + frame->translation_.z = 0.1; + overlays_[View::GEOMETRY]->attach(frame); + resize_handle_ = new Handles(Handles::RESIZE); + resize_handle_->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f); + resize_handle_->translation_.z = 0.15; + overlays_[View::GEOMETRY]->attach(resize_handle_); + resize_H_handle_ = new Handles(Handles::RESIZE_H); + resize_H_handle_->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f); + resize_H_handle_->translation_.z = 0.15; + overlays_[View::GEOMETRY]->attach(resize_H_handle_); + resize_V_handle_ = new Handles(Handles::RESIZE_V); + resize_V_handle_->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f); + resize_V_handle_->translation_.z = 0.15; + overlays_[View::GEOMETRY]->attach(resize_V_handle_); + } MediaSource::~MediaSource() @@ -190,9 +228,9 @@ void MediaSource::init() if (is) is->stipple = 1.0; groups_[View::MIXING]->attach(surfacemix); if (mediaplayer_->duration() == GST_CLOCK_TIME_NONE) - overlays_[View::MIXING]->overlay_ = new Mesh("mesh/icon_image.ply"); + overlays_[View::MIXING]->attach( new Mesh("mesh/icon_image.ply") ); else - overlays_[View::MIXING]->overlay_ = new Mesh("mesh/icon_video.ply"); + overlays_[View::MIXING]->attach( new Mesh("mesh/icon_video.ply") ); // scale all mixing nodes to match aspect ratio of the media for (NodeSet::iterator node = groups_[View::MIXING]->begin(); @@ -203,7 +241,6 @@ void MediaSource::init() node != groups_[View::GEOMETRY]->end(); node++) { (*node)->scale_.x = mediaplayer_->aspectRatio(); } -// mixingshader_->mask = ImageShader::mask_presets["Halo"]; // done init once and for all initialized_ = true; diff --git a/Source.h b/Source.h index bccd976..af85126 100644 --- a/Source.h +++ b/Source.h @@ -6,6 +6,7 @@ #include #include "View.h" +#include "Mesh.h" class ImageShader; class ImageProcessingShader; @@ -33,7 +34,8 @@ public: // get handle on the node used to manipulate the source in a view inline Group *group(View::Mode m) const { return groups_.at(m); } - inline Node *node(View::Mode m) const { return static_cast(groups_.at(m)); } + inline Node *groupNode(View::Mode m) const { return static_cast(groups_.at(m)); } + Handles *handleNode(Handles::Type t) const; // every Source has a shader to control image processing effects inline ImageProcessingShader *processingShader() const { return rendershader_; } @@ -50,7 +52,7 @@ public: // accept all kind of visitors virtual void accept (Visitor& v); - // informs if the source failed (and might have to be deleted) + // every Source shall informs if the source failed (i.e. shall be deleted) virtual bool failed() const { return false; } protected: @@ -73,17 +75,18 @@ protected: // It is associated to the rendershader for mixing effects FrameBufferSurface *rendersurface_; - // rendershader provides image processing controls + // rendershader performs image processing ImageProcessingShader *rendershader_; - // mixingshader provides mixing controls + // blendingshader provides mixing controls ImageShader *blendingshader_; // overlay to be displayed on top of source - std::map overlays_; + std::map overlays_; + Handles *resize_handle_, *resize_H_handle_, *resize_V_handle_, *rotate_handle_; }; -// TODO : source set sorted by shader +// TODO SourceSet sorted by shader // so that the render loop avoid switching typedef std::list SourceList; @@ -134,5 +137,6 @@ protected: MediaPlayer *mediaplayer_; }; +// TODO dedicated source .cpp .h files for MediaSource #endif // SOURCE_H diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 5e42570..1a9b2ea 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -239,17 +239,23 @@ void UserInterface::handleKeyboard() } } + else { + // Normal keys + if (ImGui::IsKeyPressed( GLFW_KEY_BACKSPACE )) + Mixer::manager().deleteCurrentSource(); + // Application F-Keys + else if (ImGui::IsKeyPressed( GLFW_KEY_F1 )) + Mixer::manager().setCurrentView(View::MIXING); + else if (ImGui::IsKeyPressed( GLFW_KEY_F2 )) + Mixer::manager().setCurrentView(View::GEOMETRY); + else if (ImGui::IsKeyPressed( GLFW_KEY_F12 )) + Rendering::manager().ToggleFullscreen(); + else if (ImGui::IsKeyPressed( GLFW_KEY_PRINT_SCREEN )) + toolbox.StartScreenshot(); + else if (ImGui::IsKeyPressed( GLFW_KEY_GRAVE_ACCENT )) + navigator.toggleMenu(); + } - // Application F-Keys - if (ImGui::IsKeyPressed( GLFW_KEY_F1 )) - Mixer::manager().setCurrentView(View::MIXING); - if (ImGui::IsKeyPressed( GLFW_KEY_F2 )) - Mixer::manager().setCurrentView(View::GEOMETRY); - if (ImGui::IsKeyPressed( GLFW_KEY_F12 )) - Rendering::manager().ToggleFullscreen(); - else if (ImGui::IsKeyPressed( GLFW_KEY_F11 )) - toolbox.StartScreenshot(); - } void UserInterface::handleMouse() @@ -261,6 +267,8 @@ void UserInterface::handleMouse() mouseclic[ImGuiMouseButton_Left] = glm::vec2(io.MouseClickedPos[ImGuiMouseButton_Left].x * io.DisplayFramebufferScale.y, io.MouseClickedPos[ImGuiMouseButton_Left].y* io.DisplayFramebufferScale.x); mouseclic[ImGuiMouseButton_Right] = glm::vec2(io.MouseClickedPos[ImGuiMouseButton_Right].x * io.DisplayFramebufferScale.y, io.MouseClickedPos[ImGuiMouseButton_Right].y* io.DisplayFramebufferScale.x); + static std::pair pick = { nullptr, glm::vec2(0.f) }; + // if not on any window if ( !ImGui::IsAnyWindowHovered() && !ImGui::IsAnyWindowFocused() ) { @@ -305,7 +313,7 @@ void UserInterface::handleMouse() if (current) { // drag current source - Mixer::manager().currentView()->grab( mouseclic[ImGuiMouseButton_Left], mousepos, current); + Mixer::manager().currentView()->grab( mouseclic[ImGuiMouseButton_Left], mousepos, current, pick); } else { // Log::Info("Mouse drag (%.1f,%.1f)(%.1f,%.1f)", io.MouseClickedPos[0].x, io.MouseClickedPos[0].y, io.MousePos.x, io.MousePos.y); @@ -328,13 +336,15 @@ void UserInterface::handleMouse() // picking visitor found nodes? if (pv.picked().empty()) Mixer::manager().unsetCurrentSource(); - else - Mixer::manager().setCurrentSource(pv.picked().back().first); + else { + pick = pv.picked().back(); + Mixer::manager().setCurrentSource( pick.first ); + } } else if ( ImGui::IsMouseReleased(ImGuiMouseButton_Left) ) { - + pick = { nullptr, glm::vec2(0.f) }; } if ( ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) ) @@ -858,6 +868,13 @@ void Navigator::showPannelSource(int index) selected_source_index = index; } +void Navigator::toggleMenu() +{ + bool previous = selected_button[NAV_MENU]; + hidePannel(); + selected_button[NAV_MENU] = !previous; +} + void Navigator::hidePannel() { clearSelection(); diff --git a/UserInterfaceManager.h b/UserInterfaceManager.h index 4db70dd..1109620 100644 --- a/UserInterfaceManager.h +++ b/UserInterfaceManager.h @@ -38,6 +38,7 @@ class Navigator public: Navigator(); + void toggleMenu(); void hidePannel(); void showPannelSource(int index); void Render(); diff --git a/View.cpp b/View.cpp index 8b0619a..79d4e56 100644 --- a/View.cpp +++ b/View.cpp @@ -106,7 +106,7 @@ void MixingView::drag (glm::vec2 from, glm::vec2 to) } -void MixingView::grab (glm::vec2 from, glm::vec2 to, Source *s) +void MixingView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair) { if (!s) return; @@ -201,6 +201,7 @@ void RenderView::setResolution(glm::vec3 resolution) delete frame_buffer_; frame_buffer_ = new FrameBuffer(resolution); + frame_buffer_->setClearColor(glm::vec4(0.f, 0.f, 0.f, 1.f)); } void RenderView::draw() @@ -230,7 +231,6 @@ GeometryView::GeometryView() : View(GEOMETRY) scene.bg()->attach(rect); Frame *border = new Frame(Frame::SHARP_THIN); - border->overlay_ = new Mesh("mesh/border_vertical_overlay.ply"); border->color = glm::vec4( 0.8f, 0.f, 0.8f, 1.f ); scene.bg()->attach(border); @@ -282,77 +282,118 @@ void GeometryView::drag (glm::vec2 from, glm::vec2 to) } -void GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s) +void GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair pick) { + // work on the given source if (!s) return; - Group *sourceNode = s->group(View::GEOMETRY); - static glm::vec3 start_translation = glm::vec3(0.f); - static glm::vec3 start_scale = glm::vec3(0.f); + // remember static glm::vec2 start_position = glm::vec2(0.f); - - + static glm::vec3 start_translation = glm::vec3(0.f); + static glm::vec3 start_scale = glm::vec3(1.f); if ( start_position != from ) { start_position = from; start_translation = sourceNode->translation_; start_scale = sourceNode->scale_; } - // unproject in scene coordinates + // grab coordinates in scene View reference frame glm::vec3 gl_Position_from = Rendering::manager().unProject(from, scene.root()->transform_); glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_); - // coordinate in source - glm::mat4 modelview; - glm::vec2 clicpos(0.f); - PickingVisitor pv(gl_Position_to); - sourceNode->accept(pv); - if (!pv.picked().empty()){ - clicpos = pv.picked().back().second; - modelview = pv.picked().back().first->transform_; -// Log::Info("clic pos source %.2f. %.2f", clicpos.x, clicpos.y); + // grab coordinates in source root reference frame + glm::vec4 S_from = glm::inverse(sourceNode->transform_) * glm::vec4( gl_Position_from, 1.f ); + glm::vec4 S_to = glm::inverse(sourceNode->transform_) * glm::vec4( gl_Position_to, 1.f ); + glm::vec3 S_resize = glm::vec3(S_to) / glm::vec3(S_from); + +// Log::Info(" screen coordinates ( %.1f, %.1f ) ", to.x, to.y); +// Log::Info(" scene coordinates ( %.1f, %.1f ) ", gl_Position_to.x, gl_Position_to.y); +// Log::Info(" source coordinates ( %.1f, %.1f ) ", P_to.x, P_to.y); + + // which manipulation to perform? + if (pick.first) { + // picking on the resizing handles in the corners + if ( pick.first == s->handleNode(Handles::RESIZE) ) { + sourceNode->scale_ = start_scale * S_resize; + } + // picking on the resizing handles left or right + else if ( pick.first == s->handleNode(Handles::RESIZE_H) ) { + sourceNode->scale_ = start_scale * glm::vec3(S_resize.x, 1.f, 1.f); + } + // picking on the resizing handles top or bottom + else if ( pick.first == s->handleNode(Handles::RESIZE_V) ) { + sourceNode->scale_ = start_scale * glm::vec3(1.f, S_resize.y, 1.f); + } + // TODO picking on the rotating handle + else if ( pick.first == s->handleNode(Handles::ROTATE) ) { + + } + // picking anywhere but on a handle: user wants to move the source + else { + sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from; + } } - -// glm::vec4 P = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_to, 1.f ); - - - if ( ABS(clicpos.x)>0.9f && ABS(clicpos.y)>0.9f ) - { - // clic inside corner - Log::Info("corner %.2f. %.2f", clicpos.x, clicpos.y); -// Log::Info(" %.2f. %.2f", P.x, P.y); - -// glm::vec2 topos = clicpos; -// PickingVisitor pv(gl_Position_from); -// sourceNode->accept(pv); - -// if (!pv.picked().empty()){ -// topos = pv.picked().back().second; -//// Log::Info("scale %.2f. %.2f", topos.x, topos.y); -// } - - glm::vec4 P = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_from, 1.f ); - - - sourceNode->scale_ = start_scale * (glm::vec3(clicpos, 1.f) / glm::vec3(P) ); - Log::Info("scale %.2f. %.2f", sourceNode->scale_.x, sourceNode->scale_.y); - Log::Info(" %.2f. %.2f", start_scale.x, start_scale.y); - } - else if ( ABS(clicpos.x)>0.95f && ABS(clicpos.y)<0.05f ) - { - // clic resize horizontal - Log::Info("H resize %.2f. %.2f", clicpos.x, clicpos.y); - } - else if ( ABS(clicpos.x)<0.05f && ABS(clicpos.y)>0.95f ) - { - // clic resize vertical - Log::Info("V resize %.2f. %.2f", clicpos.x, clicpos.y); - } - else - // clic inside source: compute delta translation + // don't have a handle, we can only move the source + else { sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from; + } + +// // coordinate in source +// glm::mat4 modelview(1.f); +// glm::vec2 clicpos(0.f); +//// PickingVisitor pv(gl_Position_to); +//// sourceNode->accept(pv); +//// if (!pv.picked().empty()){ +//// clicpos = pv.picked().back().second; +////// modelview = pv.picked().back().first->transform_; +////// Log::Info("clic pos source %.2f. %.2f", clicpos.x, clicpos.y); +//// } + + +// glm::vec4 P_from = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_from, 1.f ); +// glm::vec4 P_to = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_to, 1.f ); + + +//// glm::vec4 P = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_to, 1.f ); + + +// if ( pick.first == s->handleNode(Handles::RESIZE) ) +// { +// // clic inside corner +//// Log::Info("corner %.2f. %.2f", clicpos.x, clicpos.y); +////// Log::Info(" %.2f. %.2f", P.x, P.y); + +////// glm::vec2 topos = clicpos; +////// PickingVisitor pv(gl_Position_from); +////// sourceNode->accept(pv); + +////// if (!pv.picked().empty()){ +////// topos = pv.picked().back().second; +//////// Log::Info("scale %.2f. %.2f", topos.x, topos.y); +////// } + +////// glm::vec4 P = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_from, 1.f ); + + +// sourceNode->scale_ = start_scale * (glm::vec3(P_to) / glm::vec3(P_from) ); +//// Log::Info("scale %.2f. %.2f", sourceNode->scale_.x, sourceNode->scale_.y); +//// Log::Info(" %.2f. %.2f", start_scale.x, start_scale.y); +// } +// else if ( ABS(clicpos.x)>0.95f && ABS(clicpos.y)<0.05f ) +// { +// // clic resize horizontal +// Log::Info("H resize %.2f. %.2f", clicpos.x, clicpos.y); +// } +// else if ( ABS(clicpos.x)<0.05f && ABS(clicpos.y)>0.95f ) +// { +// // clic resize vertical +// Log::Info("V resize %.2f. %.2f", clicpos.x, clicpos.y); +// } +// else + // clic inside source: compute delta translation +// sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from; } diff --git a/View.h b/View.h index c1950be..d1e4be5 100644 --- a/View.h +++ b/View.h @@ -20,7 +20,7 @@ public: virtual void draw () = 0; virtual void zoom (float) {} virtual void drag (glm::vec2, glm::vec2) {} - virtual void grab (glm::vec2, glm::vec2, Source*) {} + virtual void grab (glm::vec2, glm::vec2, Source*, std::pair) {} virtual void restoreSettings(); virtual void saveSettings(); @@ -41,7 +41,7 @@ public: void draw () override; void zoom (float factor) override; void drag (glm::vec2 from, glm::vec2 to) override; - void grab (glm::vec2 from, glm::vec2 to, Source *s) override; + void grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair) override; private: uint textureMixingQuadratic(); @@ -73,7 +73,7 @@ public: void draw () override; void zoom (float factor) override; void drag (glm::vec2 from, glm::vec2 to) override; - void grab (glm::vec2 from, glm::vec2 to, Source *s) override; + void grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair pick) override; private: diff --git a/Visitor.h b/Visitor.h index 938c089..2440dab 100644 --- a/Visitor.h +++ b/Visitor.h @@ -19,6 +19,7 @@ class LineSquare; class LineCircle; class Mesh; class Frame; +class Handles; class MediaPlayer; class Shader; class ImageShader; @@ -30,24 +31,25 @@ class MediaSource; class Visitor { public: - // Declare overloads for each kind of Node to visit + // Need to declare overloads for basic kind of Nodes to visit virtual void visit (Scene&) = 0; virtual void visit (Node&) = 0; - virtual void visit (Group&) = 0; - virtual void visit (Switch&) = 0; - virtual void visit (Animation&) = 0; virtual void visit (Primitive&) = 0; - virtual void visit (Surface&) = 0; - virtual void visit (ImageSurface&) = 0; - virtual void visit (MediaSurface&) = 0; - virtual void visit (FrameBufferSurface&) = 0; - virtual void visit (LineStrip&) = 0; - virtual void visit (LineSquare&) = 0; - virtual void visit (LineCircle&) = 0; - virtual void visit (Mesh&) = 0; - virtual void visit (Frame&) = 0; + virtual void visit (Group&) = 0; - // not mandatory + // not mandatory for all others + virtual void visit (Switch&) {} + virtual void visit (Animation&) {} + virtual void visit (Surface&) {} + virtual void visit (ImageSurface&) {} + virtual void visit (MediaSurface&) {} + virtual void visit (FrameBufferSurface&) {} + virtual void visit (LineStrip&) {} + virtual void visit (LineSquare&) {} + virtual void visit (LineCircle&) {} + virtual void visit (Mesh&) {} + virtual void visit (Frame&) {} + virtual void visit (Handles&) {} virtual void visit (MediaPlayer&) {} virtual void visit (Shader&) {} virtual void visit (ImageShader&) {} diff --git a/rsc/mesh/border_handles_overlay.ply b/rsc/mesh/border_handles_overlay.ply index 6c1a8a1..eeb7575 100644 --- a/rsc/mesh/border_handles_overlay.ply +++ b/rsc/mesh/border_handles_overlay.ply @@ -1,33 +1,21 @@ ply format ascii 1.0 comment Created by Blender 2.82 (sub 7) - www.blender.org, source file: 'border_large_sharp_2.blend' -element vertex 16 +element vertex 8 property float x property float y property float z -property uchar red -property uchar green -property uchar blue -property uchar alpha -element face 16 +element face 8 property list uchar uint vertex_indices end_header -0.040053 -1.008800 0.000000 255 255 255 255 --0.031947 -1.000800 0.000000 255 255 255 255 --0.039947 -1.008800 0.000000 255 255 255 255 --0.031947 -0.957118 0.000000 255 255 255 255 --0.039947 -0.949118 0.000000 255 255 255 255 -0.040053 -0.949118 0.000000 255 255 255 255 -0.032053 -0.957118 0.000000 255 255 255 255 -0.032053 -1.000800 0.000000 255 255 255 255 -0.040053 0.949146 0.000000 255 255 255 255 --0.031947 0.957146 0.000000 255 255 255 255 --0.039947 0.949146 0.000000 255 255 255 255 --0.031947 1.000827 0.000000 255 255 255 255 --0.039947 1.008827 0.000000 255 255 255 255 -0.040053 1.008827 0.000000 255 255 255 255 -0.032053 1.000827 0.000000 255 255 255 255 -0.032053 0.957146 0.000000 255 255 255 255 +0.091161 0.091238 0.000000 +0.073023 -0.072006 0.000000 +0.091161 -0.090145 0.000000 +-0.072083 -0.072006 0.000000 +-0.090222 -0.090145 0.000000 +-0.090222 0.091238 0.000000 +-0.072083 0.073100 0.000000 +0.073023 0.073100 0.000000 3 0 1 2 3 2 3 4 3 3 5 4 @@ -36,11 +24,3 @@ end_header 3 2 1 3 3 3 6 5 3 0 5 6 -3 8 9 10 -3 10 11 12 -3 11 13 12 -3 8 14 15 -3 8 15 9 -3 10 9 11 -3 11 14 13 -3 8 13 14 diff --git a/rsc/mesh/border_large_sharp.ply b/rsc/mesh/border_large_sharp.ply index 3481d88..192356e 100644 --- a/rsc/mesh/border_large_sharp.ply +++ b/rsc/mesh/border_large_sharp.ply @@ -1,7 +1,7 @@ ply format ascii 1.0 comment Created by Blender 2.82 (sub 7) - www.blender.org, source file: 'border_large_sharp.blend' -element vertex 52 +element vertex 45 property float x property float y property float z @@ -9,7 +9,7 @@ property uchar red property uchar green property uchar blue property uchar alpha -element face 62 +element face 57 property list uchar uint vertex_indices end_header -0.950647 -1.000000 0.000000 255 255 255 255 @@ -57,13 +57,6 @@ end_header 1.000000 0.000000 0.000000 255 255 255 255 -0.000064 1.000000 0.000000 255 255 255 255 -0.995340 1.015000 0.000000 255 255 255 255 -1.012389 -0.007651 0.000000 255 255 255 255 -1.050200 -0.000169 0.000000 255 255 255 255 -1.011916 -0.000169 0.000000 255 255 255 255 -1.050200 0.007965 0.000000 255 255 255 255 -1.011319 -0.007674 0.000000 255 255 255 255 -1.050200 -0.007651 0.000000 255 255 255 255 -1.011401 0.007965 0.000000 255 255 255 255 3 0 1 2 3 3 4 1 3 4 5 1 @@ -121,8 +114,3 @@ end_header 3 29 31 40 3 40 44 38 3 19 14 22 -3 45 46 47 -3 48 47 46 -3 49 45 47 -3 45 50 46 -3 48 51 47 diff --git a/rsc/mesh/icon_image.ply b/rsc/mesh/icon_image.ply index 819b6b2..1e48192 100644 --- a/rsc/mesh/icon_image.ply +++ b/rsc/mesh/icon_image.ply @@ -1,132 +1,992 @@ ply format ascii 1.0 comment Created by Blender 2.82 (sub 7) - www.blender.org, source file: 'icons.blend' -element vertex 61 +element vertex 492 property float x property float y property float z -property uchar red -property uchar green -property uchar blue -property uchar alpha -element face 57 +element face 490 property list uchar uint vertex_indices end_header --0.124093 1.079884 0.000000 255 255 255 255 --0.103797 1.242214 0.000000 255 255 255 255 --0.124093 1.262506 0.000000 255 255 255 255 -0.119454 1.262506 0.000000 255 255 255 255 -0.099159 1.242214 0.000000 255 255 255 255 -0.119454 1.079884 0.000000 255 255 255 255 --0.103797 1.100175 0.000000 255 255 255 255 -0.099159 1.100175 0.000000 255 255 255 255 --0.060197 1.221784 0.000000 255 255 255 255 --0.056067 1.221784 0.000000 255 255 255 255 --0.058132 1.221923 0.000000 255 255 255 255 --0.054087 1.221379 0.000000 255 255 255 255 --0.062177 1.221379 0.000000 255 255 255 255 --0.052209 1.220727 0.000000 255 255 255 255 --0.064055 1.220727 0.000000 255 255 255 255 --0.050451 1.219844 0.000000 255 255 255 255 --0.065813 1.219844 0.000000 255 255 255 255 --0.048832 1.218751 0.000000 255 255 255 255 --0.067432 1.218751 0.000000 255 255 255 255 --0.047370 1.217464 0.000000 255 255 255 255 --0.068894 1.217464 0.000000 255 255 255 255 --0.046083 1.216002 0.000000 255 255 255 255 --0.070181 1.216002 0.000000 255 255 255 255 --0.044989 1.214384 0.000000 255 255 255 255 --0.071274 1.214384 0.000000 255 255 255 255 --0.044107 1.212627 0.000000 255 255 255 255 --0.072157 1.212627 0.000000 255 255 255 255 --0.043454 1.210749 0.000000 255 255 255 255 --0.072810 1.210749 0.000000 255 255 255 255 --0.043049 1.208769 0.000000 255 255 255 255 --0.073215 1.208769 0.000000 255 255 255 255 --0.042910 1.206705 0.000000 255 255 255 255 --0.073354 1.206705 0.000000 255 255 255 255 --0.073215 1.204638 0.000000 255 255 255 255 --0.043049 1.204638 0.000000 255 255 255 255 --0.072810 1.202657 0.000000 255 255 255 255 --0.043454 1.202657 0.000000 255 255 255 255 --0.072157 1.200779 0.000000 255 255 255 255 --0.044107 1.200778 0.000000 255 255 255 255 --0.007586 1.161049 0.000000 255 255 255 255 -0.068715 1.120467 0.000000 255 255 255 255 -0.017976 1.201632 0.000000 255 255 255 255 --0.071274 1.199021 0.000000 255 255 255 255 --0.044989 1.199021 0.000000 255 255 255 255 --0.070181 1.197403 0.000000 255 255 255 255 --0.046083 1.197403 0.000000 255 255 255 255 --0.068894 1.195941 0.000000 255 255 255 255 --0.047370 1.195941 0.000000 255 255 255 255 --0.067432 1.194655 0.000000 255 255 255 255 --0.048832 1.194655 0.000000 255 255 255 255 --0.065813 1.193563 0.000000 255 255 255 255 --0.050451 1.193563 0.000000 255 255 255 255 --0.064055 1.192681 0.000000 255 255 255 255 --0.052209 1.192681 0.000000 255 255 255 255 --0.062177 1.192029 0.000000 255 255 255 255 --0.054087 1.192029 0.000000 255 255 255 255 --0.060197 1.191625 0.000000 255 255 255 255 --0.056067 1.191625 0.000000 255 255 255 255 --0.058132 1.191486 0.000000 255 255 255 255 --0.073354 1.120467 0.000000 255 255 255 255 --0.032763 1.180935 0.000000 255 255 255 255 +-0.016736 1.260201 0.000000 +0.015567 1.260201 0.000000 +-0.000585 1.261289 0.000000 +-0.032230 1.257033 0.000000 +0.031061 1.257033 0.000000 +-0.046924 1.251927 0.000000 +0.045754 1.251927 0.000000 +-0.060676 1.245024 0.000000 +0.059506 1.245024 0.000000 +-0.073342 1.236468 0.000000 +0.072173 1.236468 0.000000 +-0.084782 1.226401 0.000000 +0.083613 1.226401 0.000000 +-0.094853 1.214964 0.000000 +-0.052001 1.224427 0.000000 +0.093683 1.214964 0.000000 +-0.057833 1.216060 0.000000 +-0.048423 1.221331 0.000000 +-0.044971 1.217843 0.000000 +-0.041635 1.214035 0.000000 +-0.062975 1.206208 0.000000 +-0.103411 1.202300 0.000000 +0.043918 1.211675 0.000000 +0.102242 1.202300 0.000000 +-0.038403 1.209976 0.000000 +0.040619 1.208751 0.000000 +0.050284 1.202992 0.000000 +-0.035265 1.205736 0.000000 +0.037584 1.205951 0.000000 +-0.067477 1.195099 0.000000 +0.034775 1.203239 0.000000 +-0.032211 1.201385 0.000000 +0.032158 1.200581 0.000000 +0.056008 1.193404 0.000000 +-0.110316 1.188551 0.000000 +0.109146 1.188551 0.000000 +-0.029228 1.196993 0.000000 +0.029697 1.197939 0.000000 +0.027356 1.195277 0.000000 +-0.026308 1.192631 0.000000 +0.025100 1.192560 0.000000 +-0.071386 1.182961 0.000000 +0.061124 1.183037 0.000000 +-0.023438 1.188368 0.000000 +0.022893 1.189751 0.000000 +0.020699 1.186814 0.000000 +-0.115424 1.173859 0.000000 +0.114254 1.173859 0.000000 +-0.020608 1.184275 0.000000 +0.018484 1.183714 0.000000 +-0.017807 1.180421 0.000000 +0.016212 1.180413 0.000000 +0.065667 1.172017 0.000000 +-0.074754 1.170021 0.000000 +-0.015025 1.176877 0.000000 +-0.013001 1.177321 0.000000 +-0.010783 1.177685 0.000000 +-0.008409 1.177969 0.000000 +-0.005917 1.178173 0.000000 +-0.003343 1.178297 0.000000 +-0.000724 1.178339 0.000000 +0.001903 1.178300 0.000000 +0.004499 1.178180 0.000000 +0.007029 1.177978 0.000000 +0.009455 1.177693 0.000000 +0.011739 1.177327 0.000000 +0.013846 1.176877 0.000000 +-0.118593 1.158367 0.000000 +0.117424 1.158367 0.000000 +0.069672 1.160468 0.000000 +-0.077627 1.156507 0.000000 +0.073173 1.148518 0.000000 +-0.119681 1.142217 0.000000 +0.118512 1.142217 0.000000 +-0.032825 1.156935 0.000000 +-0.027893 1.156935 0.000000 +-0.030359 1.157101 0.000000 +0.026724 1.156935 0.000000 +0.031655 1.156935 0.000000 +0.029189 1.157101 0.000000 +-0.035190 1.156450 0.000000 +-0.025527 1.156450 0.000000 +0.024358 1.156450 0.000000 +0.034021 1.156450 0.000000 +-0.080057 1.142647 0.000000 +-0.037434 1.155670 0.000000 +-0.023282 1.155670 0.000000 +0.022114 1.155670 0.000000 +0.036265 1.155670 0.000000 +-0.039535 1.154615 0.000000 +-0.021180 1.154615 0.000000 +0.020013 1.154615 0.000000 +0.038365 1.154615 0.000000 +-0.041470 1.153307 0.000000 +-0.019244 1.153307 0.000000 +0.018078 1.153307 0.000000 +0.040300 1.153307 0.000000 +-0.017495 1.151768 0.000000 +0.042048 1.151768 0.000000 +-0.043218 1.151768 0.000000 +0.016331 1.151768 0.000000 +-0.015955 1.150020 0.000000 +0.043587 1.150020 0.000000 +-0.044756 1.150020 0.000000 +0.014792 1.150020 0.000000 +-0.014646 1.148084 0.000000 +0.044895 1.148084 0.000000 +-0.046064 1.148084 0.000000 +0.013484 1.148084 0.000000 +0.076206 1.136292 0.000000 +-0.030359 1.147178 0.000000 +-0.029237 1.147103 0.000000 +-0.013590 1.145983 0.000000 +0.029189 1.147178 0.000000 +0.030309 1.147103 0.000000 +0.045950 1.145983 0.000000 +-0.047119 1.145983 0.000000 +-0.031478 1.147103 0.000000 +0.012429 1.145983 0.000000 +0.028070 1.147103 0.000000 +-0.032553 1.146882 0.000000 +-0.028161 1.146882 0.000000 +0.026995 1.146882 0.000000 +0.031384 1.146882 0.000000 +-0.033572 1.146527 0.000000 +-0.027140 1.146527 0.000000 +0.025976 1.146527 0.000000 +0.032403 1.146527 0.000000 +-0.034527 1.146047 0.000000 +-0.026184 1.146047 0.000000 +0.025021 1.146047 0.000000 +0.033357 1.146047 0.000000 +-0.035406 1.145452 0.000000 +-0.025303 1.145452 0.000000 +0.024142 1.145452 0.000000 +0.034237 1.145452 0.000000 +-0.012808 1.143738 0.000000 +0.046731 1.143738 0.000000 +-0.047900 1.143738 0.000000 +0.011648 1.143738 0.000000 +-0.036201 1.144752 0.000000 +-0.024508 1.144752 0.000000 +0.023347 1.144752 0.000000 +0.035031 1.144752 0.000000 +-0.023808 1.143957 0.000000 +0.035731 1.143957 0.000000 +-0.036900 1.143957 0.000000 +0.022648 1.143957 0.000000 +-0.023213 1.143077 0.000000 +0.036326 1.143077 0.000000 +-0.037495 1.143077 0.000000 +0.022053 1.143077 0.000000 +-0.012323 1.141371 0.000000 +0.047215 1.141371 0.000000 +-0.048385 1.141371 0.000000 +0.011164 1.141371 0.000000 +-0.022733 1.142122 0.000000 +0.036806 1.142122 0.000000 +-0.037975 1.142122 0.000000 +0.021573 1.142122 0.000000 +-0.082091 1.128669 0.000000 +-0.118593 1.126069 0.000000 +0.117424 1.126069 0.000000 +-0.022378 1.141101 0.000000 +0.037161 1.141101 0.000000 +-0.038330 1.141101 0.000000 +0.021218 1.141101 0.000000 +-0.012157 1.138903 0.000000 +0.047381 1.138903 0.000000 +-0.048551 1.138903 0.000000 +0.010997 1.138903 0.000000 +-0.022157 1.140025 0.000000 +0.037381 1.140025 0.000000 +-0.038550 1.140025 0.000000 +0.020998 1.140025 0.000000 +-0.022082 1.138903 0.000000 +0.037457 1.138903 0.000000 +-0.038626 1.138903 0.000000 +0.020922 1.138903 0.000000 +-0.048385 1.136440 0.000000 +-0.038550 1.137784 0.000000 +-0.022157 1.137784 0.000000 +-0.012323 1.136440 0.000000 +0.011164 1.136440 0.000000 +0.020998 1.137784 0.000000 +0.037381 1.137784 0.000000 +0.047215 1.136440 0.000000 +-0.022378 1.136709 0.000000 +0.037161 1.136709 0.000000 +-0.038330 1.136709 0.000000 +0.021218 1.136709 0.000000 +-0.022733 1.135690 0.000000 +0.036806 1.135690 0.000000 +-0.037975 1.135690 0.000000 +0.021573 1.135690 0.000000 +-0.012808 1.134076 0.000000 +0.046731 1.134076 0.000000 +-0.047900 1.134076 0.000000 +0.011648 1.134076 0.000000 +0.078806 1.123915 0.000000 +-0.023213 1.134736 0.000000 +0.036326 1.134736 0.000000 +-0.037495 1.134736 0.000000 +0.022053 1.134736 0.000000 +-0.036900 1.133857 0.000000 +-0.023808 1.133857 0.000000 +0.022648 1.133857 0.000000 +0.035731 1.133857 0.000000 +-0.013590 1.131833 0.000000 +0.045950 1.131833 0.000000 +-0.047119 1.131833 0.000000 +0.012429 1.131833 0.000000 +-0.036201 1.133062 0.000000 +-0.024508 1.133062 0.000000 +0.023347 1.133062 0.000000 +0.035031 1.133062 0.000000 +-0.035406 1.132363 0.000000 +-0.025303 1.132363 0.000000 +0.024142 1.132363 0.000000 +0.034237 1.132363 0.000000 +-0.034527 1.131768 0.000000 +-0.026184 1.131768 0.000000 +0.025021 1.131768 0.000000 +0.033357 1.131768 0.000000 +-0.014646 1.129733 0.000000 +0.044895 1.129733 0.000000 +-0.046064 1.129733 0.000000 +0.013484 1.129733 0.000000 +-0.033572 1.131289 0.000000 +-0.027140 1.131289 0.000000 +0.025976 1.131289 0.000000 +0.032403 1.131289 0.000000 +-0.032553 1.130933 0.000000 +-0.028161 1.130933 0.000000 +0.026995 1.130933 0.000000 +0.031384 1.130933 0.000000 +-0.031478 1.130713 0.000000 +-0.029237 1.130713 0.000000 +0.028070 1.130713 0.000000 +0.030309 1.130713 0.000000 +-0.030359 1.130638 0.000000 +0.029189 1.130638 0.000000 +-0.015955 1.127799 0.000000 +0.043587 1.127799 0.000000 +-0.044756 1.127799 0.000000 +0.014792 1.127799 0.000000 +-0.083779 1.114799 0.000000 +-0.017495 1.126051 0.000000 +0.042048 1.126051 0.000000 +-0.043218 1.126051 0.000000 +0.016331 1.126051 0.000000 +-0.115424 1.110579 0.000000 +0.114254 1.110579 0.000000 +-0.019244 1.124512 0.000000 +0.040300 1.124512 0.000000 +-0.041470 1.124512 0.000000 +0.018078 1.124512 0.000000 +-0.021180 1.123203 0.000000 +0.038365 1.123203 0.000000 +-0.039535 1.123203 0.000000 +0.020013 1.123203 0.000000 +0.081006 1.111513 0.000000 +-0.023282 1.122147 0.000000 +0.036265 1.122147 0.000000 +-0.037434 1.122147 0.000000 +0.022114 1.122147 0.000000 +-0.025527 1.121366 0.000000 +0.034021 1.121366 0.000000 +-0.035190 1.121366 0.000000 +0.024358 1.121366 0.000000 +-0.027893 1.120881 0.000000 +0.031655 1.120881 0.000000 +-0.032825 1.120881 0.000000 +0.026724 1.120881 0.000000 +-0.030359 1.120715 0.000000 +0.029189 1.120715 0.000000 +-0.002294 1.116439 0.000000 +0.001125 1.116439 0.000000 +-0.000585 1.116488 0.000000 +-0.003935 1.116290 0.000000 +0.002766 1.116290 0.000000 +-0.005491 1.116040 0.000000 +0.004323 1.116040 0.000000 +-0.006947 1.115687 0.000000 +0.005780 1.115687 0.000000 +-0.008289 1.115229 0.000000 +0.007123 1.115229 0.000000 +-0.009501 1.114665 0.000000 +0.008336 1.114665 0.000000 +-0.085170 1.101267 0.000000 +-0.010568 1.113991 0.000000 +0.009405 1.113991 0.000000 +-0.011475 1.113207 0.000000 +0.010313 1.113207 0.000000 +-0.012206 1.112310 0.000000 +0.011045 1.112310 0.000000 +-0.012748 1.111299 0.000000 +0.011588 1.111299 0.000000 +0.082842 1.099213 0.000000 +-0.013084 1.110172 0.000000 +0.011924 1.110172 0.000000 +-0.110316 1.095888 0.000000 +0.109146 1.095888 0.000000 +-0.013199 1.108927 0.000000 +0.012039 1.108927 0.000000 +-0.013139 1.107984 0.000000 +0.011978 1.107974 0.000000 +-0.012963 1.107033 0.000000 +0.011798 1.107011 0.000000 +-0.012678 1.106082 0.000000 +0.011506 1.106048 0.000000 +-0.012287 1.105139 0.000000 +0.011107 1.105094 0.000000 +-0.011798 1.104213 0.000000 +0.010607 1.104157 0.000000 +-0.011215 1.103313 0.000000 +0.010012 1.103247 0.000000 +-0.010545 1.102447 0.000000 +0.009329 1.102373 0.000000 +-0.009794 1.101624 0.000000 +0.008562 1.101544 0.000000 +-0.008966 1.100853 0.000000 +0.007719 1.100768 0.000000 +-0.086313 1.088298 0.000000 +-0.008068 1.100142 0.000000 +0.006804 1.100055 0.000000 +-0.007105 1.099500 0.000000 +0.005824 1.099415 0.000000 +-0.006083 1.098935 0.000000 +0.004785 1.098855 0.000000 +0.084349 1.087139 0.000000 +-0.006083 1.098843 0.000000 +0.004785 1.098765 0.000000 +-0.006083 1.098588 0.000000 +0.004785 1.098514 0.000000 +-0.006083 1.098203 0.000000 +0.004785 1.098136 0.000000 +-0.006083 1.097721 0.000000 +0.004785 1.097662 0.000000 +-0.006083 1.097173 0.000000 +0.004785 1.097124 0.000000 +-0.006083 1.096593 0.000000 +0.004785 1.096553 0.000000 +-0.006083 1.096013 0.000000 +0.004785 1.095983 0.000000 +-0.006083 1.095466 0.000000 +0.004785 1.095445 0.000000 +-0.103411 1.082139 0.000000 +0.102242 1.082139 0.000000 +-0.006083 1.094983 0.000000 +0.004785 1.094971 0.000000 +-0.006083 1.094598 0.000000 +0.004785 1.094592 0.000000 +-0.006083 1.094343 0.000000 +0.004785 1.094342 0.000000 +-0.006083 1.094251 0.000000 +0.004785 1.094251 0.000000 +-0.006331 1.091534 0.000000 +0.005049 1.091380 0.000000 +0.022976 1.093009 0.000000 +0.025400 1.092929 0.000000 +0.024221 1.093131 0.000000 +-0.026045 1.092936 0.000000 +-0.023479 1.092901 0.000000 +-0.024780 1.093096 0.000000 +0.021709 1.092525 0.000000 +-0.027216 1.092465 0.000000 +0.026465 1.092439 0.000000 +-0.022194 1.092309 0.000000 +0.020466 1.091642 0.000000 +-0.028241 1.091727 0.000000 +0.027372 1.091700 0.000000 +-0.020983 1.091275 0.000000 +-0.029063 1.090766 0.000000 +0.028074 1.090747 0.000000 +0.019294 1.090322 0.000000 +-0.006988 1.089432 0.000000 +0.005757 1.089249 0.000000 +-0.019898 1.089756 0.000000 +-0.029627 1.089625 0.000000 +0.028525 1.089620 0.000000 +0.018639 1.089635 0.000000 +-0.019186 1.088828 0.000000 +0.017610 1.088854 0.000000 +-0.029880 1.088348 0.000000 +0.028681 1.088355 0.000000 +-0.007979 1.087888 0.000000 +0.006828 1.087775 0.000000 +0.016290 1.088063 0.000000 +-0.018150 1.087948 0.000000 +0.028494 1.086989 0.000000 +-0.029765 1.086978 0.000000 +-0.087257 1.076123 0.000000 +0.014761 1.087345 0.000000 +-0.016863 1.087173 0.000000 +-0.009232 1.086846 0.000000 +0.008180 1.086875 0.000000 +0.013103 1.086784 0.000000 +-0.015399 1.086558 0.000000 +0.085562 1.075418 0.000000 +0.027919 1.085559 0.000000 +-0.029227 1.085559 0.000000 +0.009731 1.086466 0.000000 +-0.010674 1.086248 0.000000 +0.011399 1.086463 0.000000 +-0.013831 1.086161 0.000000 +-0.012231 1.086039 0.000000 +-0.028423 1.084252 0.000000 +0.027115 1.084252 0.000000 +-0.027459 1.083020 0.000000 +0.026150 1.083020 0.000000 +-0.026348 1.081871 0.000000 +0.025038 1.081871 0.000000 +-0.094853 1.069475 0.000000 +0.093683 1.069475 0.000000 +-0.025105 1.080812 0.000000 +0.023794 1.080812 0.000000 +-0.023743 1.079849 0.000000 +-0.000654 1.080578 0.000000 +0.022432 1.079849 0.000000 +-0.001422 1.079934 0.000000 +0.000115 1.079934 0.000000 +-0.002229 1.079342 0.000000 +0.000924 1.079342 0.000000 +-0.022276 1.078992 0.000000 +0.020966 1.078992 0.000000 +0.001770 1.078803 0.000000 +-0.003074 1.078803 0.000000 +-0.020719 1.078246 0.000000 +0.019409 1.078246 0.000000 +0.002651 1.078317 0.000000 +-0.003955 1.078317 0.000000 +0.003566 1.077886 0.000000 +-0.004870 1.077886 0.000000 +-0.019085 1.077619 0.000000 +0.017775 1.077619 0.000000 +0.004513 1.077509 0.000000 +-0.005816 1.077509 0.000000 +-0.017388 1.077119 0.000000 +0.016080 1.077119 0.000000 +0.005490 1.077189 0.000000 +-0.006793 1.077189 0.000000 +0.006495 1.076925 0.000000 +-0.007798 1.076925 0.000000 +-0.015642 1.076752 0.000000 +0.014336 1.076752 0.000000 +0.007526 1.076718 0.000000 +-0.008829 1.076718 0.000000 +-0.013860 1.076527 0.000000 +0.012558 1.076527 0.000000 +0.008582 1.076570 0.000000 +-0.009884 1.076570 0.000000 +0.009660 1.076480 0.000000 +-0.010961 1.076480 0.000000 +-0.012058 1.076450 0.000000 +0.010759 1.076450 0.000000 +-0.082032 1.069791 0.000000 +0.080334 1.069184 0.000000 +-0.076357 1.063869 0.000000 +-0.084782 1.058038 0.000000 +0.083613 1.058037 0.000000 +0.074668 1.063354 0.000000 +-0.070259 1.058382 0.000000 +0.068588 1.057955 0.000000 +-0.063763 1.053358 0.000000 +-0.073342 1.047969 0.000000 +0.072173 1.047969 0.000000 +0.062120 1.053012 0.000000 +-0.056896 1.048823 0.000000 +0.055289 1.048553 0.000000 +-0.049682 1.044806 0.000000 +0.048120 1.044602 0.000000 +-0.060676 1.039412 0.000000 +0.059506 1.039412 0.000000 +-0.042149 1.041332 0.000000 +0.040637 1.041188 0.000000 +-0.034321 1.038429 0.000000 +0.032867 1.038335 0.000000 +-0.046924 1.032509 0.000000 +0.045754 1.032509 0.000000 +-0.026225 1.036124 0.000000 +0.024835 1.036070 0.000000 +-0.017886 1.034445 0.000000 +0.016565 1.034420 0.000000 +-0.009331 1.033417 0.000000 +0.008084 1.033411 0.000000 +-0.000585 1.033068 0.000000 +-0.032230 1.027402 0.000000 +0.031061 1.027402 0.000000 +-0.016736 1.024234 0.000000 +0.015567 1.024234 0.000000 +-0.000585 1.023146 0.000000 3 0 1 2 -3 1 3 2 -3 1 4 3 -3 4 5 3 -3 0 6 1 -3 7 5 4 -3 8 9 10 -3 8 11 9 -3 12 11 8 -3 12 13 11 -3 14 13 12 -3 14 15 13 -3 16 15 14 -3 16 17 15 -3 18 17 16 -3 18 19 17 -3 20 19 18 -3 20 21 19 -3 22 21 20 -3 22 23 21 -3 24 23 22 -3 24 25 23 -3 26 25 24 -3 26 27 25 -3 28 27 26 -3 28 29 27 -3 30 29 28 -3 30 31 29 -3 32 31 30 -3 33 31 32 -3 33 34 31 -3 35 34 33 -3 35 36 34 -3 37 36 35 -3 37 38 36 -3 39 40 41 -3 42 38 37 -3 42 43 38 -3 44 43 42 -3 44 45 43 -3 46 45 44 -3 46 47 45 -3 48 47 46 -3 48 49 47 +3 3 1 0 +3 3 4 1 +3 5 4 3 +3 5 6 4 +3 7 6 5 +3 7 8 6 +3 9 8 7 +3 9 10 8 +3 11 10 9 +3 11 12 10 +3 13 14 11 +3 14 12 11 +3 14 15 12 +3 13 16 14 +3 17 15 14 +3 18 15 17 +3 19 15 18 +3 13 20 16 +3 21 20 13 +3 19 22 15 +3 22 23 15 +3 24 22 19 +3 24 25 22 +3 26 23 22 +3 27 25 24 +3 27 28 25 +3 21 29 20 +3 27 30 28 +3 31 30 27 +3 31 32 30 +3 33 23 26 +3 34 29 21 +3 33 35 23 +3 36 32 31 +3 36 37 32 +3 36 38 37 +3 39 38 36 +3 39 40 38 +3 34 41 29 +3 42 35 33 +3 43 40 39 +3 43 44 40 +3 43 45 44 +3 46 41 34 +3 42 47 35 +3 48 45 43 +3 48 49 45 3 50 49 48 3 50 51 49 -3 52 51 50 -3 52 53 51 -3 54 53 52 -3 54 55 53 -3 56 55 54 -3 56 57 55 -3 58 57 56 -3 59 39 60 -3 59 40 39 -3 0 7 6 -3 0 5 7 +3 52 47 42 +3 46 53 41 +3 54 55 50 +3 55 56 50 +3 56 57 50 +3 57 51 50 +3 57 58 51 +3 58 59 51 +3 59 60 51 +3 60 61 51 +3 61 62 51 +3 62 63 51 +3 63 64 51 +3 64 65 51 +3 65 66 51 +3 67 53 46 +3 52 68 47 +3 69 68 52 +3 67 70 53 +3 71 68 69 +3 72 70 67 +3 71 73 68 +3 74 75 76 +3 77 78 79 +3 80 75 74 +3 80 81 75 +3 82 78 77 +3 82 83 78 +3 72 84 70 +3 85 81 80 +3 85 86 81 +3 87 83 82 +3 87 88 83 +3 89 86 85 +3 89 90 86 +3 91 88 87 +3 91 92 88 +3 93 90 89 +3 93 94 90 +3 95 92 91 +3 95 96 92 +3 93 97 94 +3 95 98 96 +3 99 97 93 +3 100 98 95 +3 99 101 97 +3 100 102 98 +3 103 101 99 +3 104 102 100 +3 103 105 101 +3 104 106 102 +3 107 105 103 +3 108 106 104 +3 109 73 71 +3 107 110 105 +3 110 111 105 +3 111 112 105 +3 108 113 106 +3 113 114 106 +3 114 115 106 +3 116 117 107 +3 117 110 107 +3 118 119 108 +3 119 113 108 +3 116 120 117 +3 121 112 111 +3 118 122 119 +3 123 115 114 +3 116 124 120 +3 125 112 121 +3 118 126 122 +3 127 115 123 +3 116 128 124 +3 129 112 125 +3 118 130 126 +3 131 115 127 +3 116 132 128 +3 133 112 129 +3 118 134 130 +3 135 115 131 +3 133 136 112 +3 135 137 115 +3 138 132 116 +3 139 134 118 +3 138 140 132 +3 141 136 133 +3 139 142 134 +3 143 137 135 +3 144 136 141 +3 145 137 143 +3 138 146 140 +3 139 147 142 +3 148 136 144 +3 149 137 145 +3 138 150 146 +3 139 151 147 +3 148 152 136 +3 149 153 137 +3 154 150 138 +3 155 151 139 +3 156 152 148 +3 157 153 149 +3 154 158 150 +3 155 159 151 +3 72 160 84 +3 161 160 72 +3 109 162 73 +3 163 152 156 +3 164 153 157 +3 154 165 158 +3 155 166 159 +3 163 167 152 +3 164 168 153 +3 169 165 154 +3 170 166 155 +3 171 167 163 +3 172 168 164 +3 169 173 165 +3 170 174 166 +3 175 167 171 +3 176 168 172 +3 169 177 173 +3 170 178 174 +3 179 177 169 +3 179 180 177 +3 181 167 175 +3 181 182 167 +3 183 178 170 +3 183 184 178 +3 185 168 176 +3 185 186 168 +3 187 182 181 +3 188 186 185 +3 179 189 180 +3 183 190 184 +3 191 182 187 +3 192 186 188 +3 179 193 189 +3 183 194 190 +3 191 195 182 +3 192 196 186 +3 197 193 179 +3 198 194 183 +3 199 162 109 +3 200 195 191 +3 201 196 192 +3 197 202 193 +3 198 203 194 +3 197 204 202 +3 205 195 200 +3 198 206 203 +3 207 196 201 +3 205 208 195 +3 207 209 196 +3 210 204 197 +3 211 206 198 +3 210 212 204 +3 213 208 205 +3 211 214 206 +3 215 209 207 +3 210 216 212 +3 217 208 213 +3 211 218 214 +3 219 209 215 +3 210 220 216 +3 221 208 217 +3 211 222 218 +3 223 209 219 +3 221 224 208 +3 223 225 209 +3 226 220 210 +3 227 222 211 +3 226 228 220 +3 229 224 221 +3 227 230 222 +3 231 225 223 +3 226 232 228 +3 233 224 229 +3 227 234 230 +3 235 225 231 +3 226 236 232 +3 237 224 233 +3 227 238 234 +3 239 225 235 +3 226 240 236 +3 240 224 237 +3 227 241 238 +3 241 225 239 +3 226 224 240 +3 227 225 241 +3 226 242 224 +3 227 243 225 +3 244 242 226 +3 245 243 227 +3 161 246 160 +3 244 247 242 +3 245 248 243 +3 249 247 244 +3 250 248 245 +3 251 246 161 +3 199 252 162 +3 249 253 247 +3 250 254 248 +3 255 253 249 +3 256 254 250 +3 255 257 253 +3 256 258 254 +3 259 257 255 +3 260 258 256 +3 261 252 199 +3 259 262 257 +3 260 263 258 +3 264 262 259 +3 265 263 260 +3 264 266 262 +3 265 267 263 +3 268 266 264 +3 269 267 265 +3 268 270 266 +3 269 271 267 +3 272 270 268 +3 273 271 269 +3 272 274 270 +3 273 275 271 +3 276 277 278 +3 279 277 276 +3 279 280 277 +3 281 280 279 +3 281 282 280 +3 283 282 281 +3 283 284 282 +3 285 284 283 +3 285 286 284 +3 287 286 285 +3 287 288 286 +3 251 289 246 +3 290 288 287 +3 290 291 288 +3 292 291 290 +3 292 293 291 +3 294 293 292 +3 294 295 293 +3 296 295 294 +3 296 297 295 +3 298 252 261 +3 299 297 296 +3 299 300 297 +3 301 289 251 +3 298 302 252 +3 303 300 299 +3 303 304 300 +3 305 304 303 +3 305 306 304 +3 307 306 305 +3 307 308 306 +3 309 308 307 +3 309 310 308 +3 311 310 309 +3 311 312 310 +3 313 312 311 +3 313 314 312 +3 315 314 313 +3 315 316 314 +3 317 316 315 +3 317 318 316 +3 319 318 317 +3 319 320 318 +3 321 320 319 +3 321 322 320 +3 301 323 289 +3 324 322 321 +3 324 325 322 +3 326 325 324 +3 326 327 325 +3 328 327 326 +3 328 329 327 +3 330 302 298 +3 331 329 328 +3 331 332 329 +3 333 332 331 +3 333 334 332 +3 335 334 333 +3 335 336 334 +3 337 336 335 +3 337 338 336 +3 339 338 337 +3 339 340 338 +3 341 340 339 +3 341 342 340 +3 343 342 341 +3 343 344 342 +3 345 344 343 +3 345 346 344 +3 347 323 301 +3 330 348 302 +3 349 346 345 +3 349 350 346 +3 351 350 349 +3 351 352 350 +3 353 352 351 +3 353 354 352 +3 355 354 353 +3 355 356 354 +3 357 356 355 +3 357 358 356 +3 359 360 361 +3 362 363 364 +3 365 360 359 +3 366 363 362 +3 365 367 360 +3 366 368 363 +3 369 367 365 +3 370 368 366 +3 369 371 367 +3 370 372 368 +3 373 372 370 +3 369 374 371 +3 375 374 369 +3 376 358 357 +3 376 377 358 +3 373 378 372 +3 379 378 373 +3 375 380 374 +3 381 380 375 +3 379 382 378 +3 383 380 381 +3 384 382 379 +3 383 385 380 +3 386 377 376 +3 386 387 377 +3 388 385 383 +3 384 389 382 +3 388 390 385 +3 391 389 384 +3 347 392 323 +3 393 390 388 +3 391 394 389 +3 395 387 386 +3 395 396 387 +3 397 390 393 +3 391 398 394 +3 399 348 330 +3 397 400 390 +3 401 398 391 +3 395 402 396 +3 403 402 395 +3 404 400 397 +3 401 405 398 +3 403 404 402 +3 403 400 404 +3 406 400 403 +3 401 406 405 +3 401 400 406 +3 407 400 401 +3 407 408 400 +3 409 408 407 +3 409 410 408 +3 411 410 409 +3 411 412 410 +3 413 392 347 +3 399 414 348 +3 415 412 411 +3 415 416 412 +3 417 418 415 +3 418 416 415 +3 418 419 416 +3 417 420 418 +3 421 419 418 +3 417 422 420 +3 423 419 421 +3 424 422 417 +3 423 425 419 +3 426 425 423 +3 424 427 422 +3 428 427 424 +3 426 429 425 +3 430 429 426 +3 428 431 427 +3 432 429 430 +3 428 433 431 +3 434 433 428 +3 432 435 429 +3 436 435 432 +3 434 437 433 +3 438 437 434 +3 436 439 435 +3 440 439 436 +3 438 441 437 +3 442 439 440 +3 438 443 441 +3 444 443 438 +3 442 445 439 +3 446 445 442 +3 444 447 443 +3 448 447 444 +3 446 449 445 +3 450 449 446 +3 448 451 447 +3 452 449 450 +3 448 453 451 +3 454 453 448 +3 452 455 449 +3 413 456 392 +3 457 414 399 +3 413 458 456 +3 459 458 413 +3 457 460 414 +3 461 460 457 +3 459 462 458 +3 463 460 461 +3 459 464 462 +3 465 464 459 +3 463 466 460 +3 467 466 463 +3 465 468 464 +3 469 466 467 +3 465 470 468 +3 471 466 469 +3 472 470 465 +3 471 473 466 +3 472 474 470 +3 475 473 471 +3 472 476 474 +3 477 473 475 +3 478 476 472 +3 477 479 473 +3 478 480 476 +3 481 479 477 +3 478 482 480 +3 483 479 481 +3 478 484 482 +3 485 479 483 +3 478 486 484 +3 486 479 485 +3 478 479 486 +3 487 479 478 +3 487 488 479 +3 489 488 487 +3 489 490 488 +3 491 490 489