mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
Fixed selection behavior: bounding box now correctly takes into account
transformations of the sources, and selects only those inside the selection bounding box.
This commit is contained in:
@@ -110,9 +110,10 @@ bool GlmToolkit::AxisAlignedBoundingBox::contains(const AxisAlignedBoundingBox&
|
|||||||
if ( !intersect(bb, ignore_z))
|
if ( !intersect(bb, ignore_z))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( (mMin.x <= bb.mMin.x) && (mMax.x >= bb.mMax.x) &&
|
if ( (mMin.x < bb.mMin.x) && (mMax.x > bb.mMax.x) &&
|
||||||
(mMin.y <= bb.mMin.y) && (mMax.y >= bb.mMax.y) &&
|
(mMin.y < bb.mMin.y) && (mMax.y > bb.mMax.y)
|
||||||
( ignore_z || ((mMin.z <= bb.mMin.z) && (mMax.z >= bb.mMax.z)) ) )
|
&& ( ignore_z || ((mMin.z < bb.mMin.z) && (mMax.z > bb.mMax.z)) )
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return true;
|
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;
|
GlmToolkit::AxisAlignedBoundingBox bb;
|
||||||
bb = *this;
|
bb = *this;
|
||||||
@@ -142,26 +143,38 @@ GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::translate
|
|||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::scaled(glm::vec3 s)
|
GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::scaled(glm::vec3 s) const
|
||||||
{
|
{
|
||||||
GlmToolkit::AxisAlignedBoundingBox bb;
|
GlmToolkit::AxisAlignedBoundingBox bb;
|
||||||
bb = *this;
|
glm::vec3 vec;
|
||||||
|
|
||||||
bb.mMin *= s;
|
// Apply scaling to min & max corners (can be inverted) and update bbox accordingly
|
||||||
bb.mMax *= s;
|
vec = mMin * s;
|
||||||
|
bb.extend(vec);
|
||||||
|
|
||||||
|
vec = mMax * s;
|
||||||
|
bb.extend(vec);
|
||||||
|
|
||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::transformed(glm::mat4 m)
|
GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::transformed(glm::mat4 m) const
|
||||||
{
|
{
|
||||||
GlmToolkit::AxisAlignedBoundingBox bb;
|
GlmToolkit::AxisAlignedBoundingBox bb;
|
||||||
glm::vec4 vec;
|
glm::vec4 vec;
|
||||||
|
|
||||||
|
// Apply transform to all four corners (can be rotated) and update bbox accordingly
|
||||||
vec = m * glm::vec4(mMin, 1.f);
|
vec = m * glm::vec4(mMin, 1.f);
|
||||||
bb.mMin = glm::vec3(vec);
|
bb.extend(glm::vec3(vec));
|
||||||
|
|
||||||
vec = m * glm::vec4(mMax, 1.f);
|
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;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ public:
|
|||||||
void extend(std::vector<glm::vec3> points);
|
void extend(std::vector<glm::vec3> points);
|
||||||
void extend(const AxisAlignedBoundingBox& bb);
|
void extend(const AxisAlignedBoundingBox& bb);
|
||||||
|
|
||||||
AxisAlignedBoundingBox translated(glm::vec3 t);
|
AxisAlignedBoundingBox translated(glm::vec3 t) const;
|
||||||
AxisAlignedBoundingBox scaled(glm::vec3 s);
|
AxisAlignedBoundingBox scaled(glm::vec3 s) const;
|
||||||
AxisAlignedBoundingBox transformed(glm::mat4 m);
|
AxisAlignedBoundingBox transformed(glm::mat4 m) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,14 +69,22 @@ void PickingVisitor::visit(Surface &n)
|
|||||||
// create bounding box for those points (2 in practice)
|
// create bounding box for those points (2 in practice)
|
||||||
GlmToolkit::AxisAlignedBoundingBox bb_points;
|
GlmToolkit::AxisAlignedBoundingBox bb_points;
|
||||||
bb_points.extend(points_);
|
bb_points.extend(points_);
|
||||||
// apply inverse transform
|
// update the coordinates of the Surface bounding box to match transform
|
||||||
bb_points = bb_points.transformed(glm::inverse(modelview_)) ;
|
GlmToolkit::AxisAlignedBoundingBox surf;
|
||||||
// test bounding box for overlap with inverse transform bbox
|
surf = n.bbox().transformed(modelview_);
|
||||||
if ( bb_points.intersect( n.bbox() ) ) {
|
// Test inclusion of all four corners of the Surface inside the selection bounding box
|
||||||
// if ( n.bbox().contains( bb_points ) ) // alternative selection by total inclusion of source inside BB
|
if ( bb_points.contains( surf) ) {
|
||||||
// add this surface to the nodes picked
|
// add this surface to the nodes picked
|
||||||
nodes_.push_back( std::pair(&n, glm::vec2(0.f)) );
|
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
|
// only one point
|
||||||
else if (points_.size() > 0) {
|
else if (points_.size() > 0) {
|
||||||
|
|||||||
@@ -469,6 +469,10 @@ void UserInterface::handleMouse()
|
|||||||
mousedown = false;
|
mousedown = false;
|
||||||
picked = { nullptr, glm::vec2(0.f) };
|
picked = { nullptr, glm::vec2(0.f) };
|
||||||
Mixer::manager().view()->terminate();
|
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) )
|
if ( ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) )
|
||||||
|
|||||||
Reference in New Issue
Block a user