diff --git a/GlmToolkit.cpp b/GlmToolkit.cpp index 098efb0..54717bc 100644 --- a/GlmToolkit.cpp +++ b/GlmToolkit.cpp @@ -110,9 +110,10 @@ bool GlmToolkit::AxisAlignedBoundingBox::contains(const AxisAlignedBoundingBox& 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)) ) ) + 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; } @@ -131,7 +132,7 @@ bool GlmToolkit::AxisAlignedBoundingBox::contains(glm::vec3 point, bool ignore_z } -GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::translated(glm::vec3 t) +GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::translated(glm::vec3 t) const { GlmToolkit::AxisAlignedBoundingBox bb; bb = *this; @@ -142,26 +143,38 @@ GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::translate return bb; } -GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::scaled(glm::vec3 s) +GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::scaled(glm::vec3 s) const { - GlmToolkit::AxisAlignedBoundingBox bb; - bb = *this; + GlmToolkit::AxisAlignedBoundingBox bb; + glm::vec3 vec; - bb.mMin *= s; - bb.mMax *= s; + // Apply scaling to min & max corners (can be inverted) and update bbox accordingly + vec = mMin * s; + bb.extend(vec); + + vec = mMax * s; + bb.extend(vec); return bb; } -GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::transformed(glm::mat4 m) +GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::transformed(glm::mat4 m) const { GlmToolkit::AxisAlignedBoundingBox bb; glm::vec4 vec; + + // Apply transform to all four corners (can be rotated) and update bbox accordingly vec = m * glm::vec4(mMin, 1.f); - bb.mMin = glm::vec3(vec); + bb.extend(glm::vec3(vec)); vec = m * glm::vec4(mMax, 1.f); - bb.mMax = glm::vec3(vec); + bb.extend(glm::vec3(vec)); + + vec = m * glm::vec4(mMin.x, mMax.y, 0.f, 1.f); + bb.extend(glm::vec3(vec)); + + vec = m * glm::vec4(mMax.x, mMin.y, 0.f, 1.f); + bb.extend(glm::vec3(vec)); return bb; } diff --git a/GlmToolkit.h b/GlmToolkit.h index 43c2bcc..bbd2811 100644 --- a/GlmToolkit.h +++ b/GlmToolkit.h @@ -39,9 +39,9 @@ public: void extend(std::vector points); void extend(const AxisAlignedBoundingBox& bb); - AxisAlignedBoundingBox translated(glm::vec3 t); - AxisAlignedBoundingBox scaled(glm::vec3 s); - AxisAlignedBoundingBox transformed(glm::mat4 m); + AxisAlignedBoundingBox translated(glm::vec3 t) const; + AxisAlignedBoundingBox scaled(glm::vec3 s) const; + AxisAlignedBoundingBox transformed(glm::mat4 m) const; }; } diff --git a/PickingVisitor.cpp b/PickingVisitor.cpp index c261715..15eca29 100644 --- a/PickingVisitor.cpp +++ b/PickingVisitor.cpp @@ -69,14 +69,22 @@ void PickingVisitor::visit(Surface &n) // create bounding box for those points (2 in practice) GlmToolkit::AxisAlignedBoundingBox bb_points; bb_points.extend(points_); - // apply inverse transform - bb_points = bb_points.transformed(glm::inverse(modelview_)) ; - // test bounding box for overlap with inverse transform bbox - if ( bb_points.intersect( n.bbox() ) ) { -// if ( n.bbox().contains( bb_points ) ) // alternative selection by total inclusion of source inside BB + // update the coordinates of the Surface bounding box to match transform + GlmToolkit::AxisAlignedBoundingBox surf; + surf = n.bbox().transformed(modelview_); + // Test inclusion of all four corners of the Surface inside the selection bounding box + if ( bb_points.contains( surf) ) { // add this surface to the nodes picked nodes_.push_back( std::pair(&n, glm::vec2(0.f)) ); } +// // ALTERNATIVE BEHAVIOR : test bounding box for overlap only +// // apply inverse transform +// bb_points = bb_points.transformed(glm::inverse(modelview_)) ; +// if ( bb_points.intersect( n.bbox() ) ) { +// // add this surface to the nodes picked +// nodes_.push_back( std::pair(&n, glm::vec2(0.f)) ); +// } + } // only one point else if (points_.size() > 0) { diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 8f99d02..8cc483f 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -469,6 +469,10 @@ void UserInterface::handleMouse() mousedown = false; picked = { nullptr, glm::vec2(0.f) }; Mixer::manager().view()->terminate(); + + // special case of one single source in selection : make current after release + if (Mixer::selection().size() == 1) + Mixer::manager().setCurrentSource( Mixer::selection().front() ); } if ( ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) ) diff --git a/View.cpp b/View.cpp index 2e833ce..799ac64 100644 --- a/View.cpp +++ b/View.cpp @@ -207,6 +207,7 @@ void View::select(glm::vec2 A, glm::vec2 B) } // set the selection with list of picked (overlaped) sources Mixer::selection().set(selection); + } }