mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
Fixed picking visitor and source node inclusion test for source
manipulation in GeometryView
This commit is contained in:
@@ -29,10 +29,6 @@ void PickingVisitor::visit(Node &n)
|
||||
{
|
||||
// use the transform modified during update
|
||||
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());
|
||||
}
|
||||
|
||||
void PickingVisitor::visit(Group &n)
|
||||
@@ -73,26 +69,24 @@ 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 ) )
|
||||
if ( bb_points.intersect( n.bbox() ) ) {
|
||||
// if ( n.bbox().contains( bb_points ) ) // alternative selection by total inclusion of source inside BB
|
||||
// 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) {
|
||||
|
||||
// apply inverse transform to the point of interest
|
||||
glm::vec4 P = glm::inverse(modelview_) * glm::vec4( points_[0], 1.f );
|
||||
|
||||
// test bounding box for picking from a single point
|
||||
if ( n.bbox().contains( glm::vec3(P)) )
|
||||
if ( n.bbox().contains( glm::vec3(P)) ) {
|
||||
// add this surface to the nodes picked
|
||||
nodes_.push_back( std::pair(&n, glm::vec2(P)) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,11 @@ public:
|
||||
|
||||
PickingVisitor(glm::vec3 coordinates);
|
||||
PickingVisitor(glm::vec3 selectionstart, glm::vec3 selection_end);
|
||||
std::vector< std::pair<Node *, glm::vec2> > picked() { return nodes_; }
|
||||
|
||||
bool empty() const {return nodes_.empty(); }
|
||||
std::pair<Node *, glm::vec2> back() const { return nodes_.back(); }
|
||||
std::vector< std::pair<Node *, glm::vec2> >::const_reverse_iterator rbegin() { return nodes_.rbegin(); }
|
||||
std::vector< std::pair<Node *, glm::vec2> >::const_reverse_iterator rend() { return nodes_.rend(); }
|
||||
|
||||
// Elements of Scene
|
||||
void visit(Scene& n) override;
|
||||
|
||||
@@ -24,7 +24,7 @@ Node::Node() : initialized_(false), visible_(true), refcount_(0)
|
||||
{
|
||||
// create unique id
|
||||
auto duration = std::chrono::high_resolution_clock::now().time_since_epoch();
|
||||
id_ = std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count() % 1000000000;
|
||||
id_ = std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count() % 100000000;
|
||||
|
||||
transform_ = glm::identity<glm::mat4>();
|
||||
scale_ = glm::vec3(1.f);
|
||||
|
||||
@@ -388,11 +388,18 @@ bool Source::hasNode::operator()(const Source* elem) const
|
||||
|
||||
// general case: traverse tree of all Groups recursively using a SearchVisitor
|
||||
SearchVisitor sv(_n);
|
||||
// search in groups for all views
|
||||
for (auto g = elem->groups_.begin(); g != elem->groups_.end(); g++) {
|
||||
(*g).second->accept(sv);
|
||||
if (sv.found())
|
||||
return true;
|
||||
}
|
||||
// search in overlays for all views
|
||||
for (auto g = elem->overlays_.begin(); g != elem->overlays_.end(); g++) {
|
||||
(*g).second->accept(sv);
|
||||
if (sv.found())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
34
View.cpp
34
View.cpp
@@ -99,9 +99,9 @@ std::pair<Node *, glm::vec2> View::pick(glm::vec2 P)
|
||||
scene.accept(pv);
|
||||
|
||||
// picking visitor found nodes?
|
||||
if ( !pv.picked().empty()) {
|
||||
if ( !pv.empty()) {
|
||||
// select top-most Node picked
|
||||
pick = pv.picked().back();
|
||||
pick = pv.back();
|
||||
}
|
||||
|
||||
return pick;
|
||||
@@ -193,13 +193,14 @@ void View::select(glm::vec2 A, glm::vec2 B)
|
||||
Mixer::selection().clear();
|
||||
|
||||
// picking visitor found nodes in the area?
|
||||
if ( !pv.picked().empty()) {
|
||||
if ( !pv.empty()) {
|
||||
|
||||
// create a list of source matching the list of picked nodes
|
||||
SourceList selection;
|
||||
std::vector< std::pair<Node *, glm::vec2> > pick = pv.picked();
|
||||
// std::vector< std::pair<Node *, glm::vec2> > pick = pv.picked();
|
||||
// loop over the nodes and add all sources found.
|
||||
for(std::vector< std::pair<Node *, glm::vec2> >::iterator p = pick.begin(); p != pick.end(); p++){
|
||||
// for(std::vector< std::pair<Node *, glm::vec2> >::iterator p = pick.begin(); p != pick.end(); p++){
|
||||
for(std::vector< std::pair<Node *, glm::vec2> >::const_reverse_iterator p = pv.rbegin(); p != pv.rend(); p++){
|
||||
Source *s = Mixer::manager().findSource( p->first );
|
||||
if (s)
|
||||
selection.push_back( s );
|
||||
@@ -756,28 +757,29 @@ std::pair<Node *, glm::vec2> GeometryView::pick(glm::vec2 P)
|
||||
scene.accept(pv);
|
||||
|
||||
// picking visitor found nodes?
|
||||
if ( pv.picked().size() > 0) {
|
||||
|
||||
if ( !pv.empty() ) {
|
||||
// keep current source active if it is clicked
|
||||
Source *s = Mixer::manager().currentSource();
|
||||
if (s != nullptr) {
|
||||
|
||||
// find if the current source was picked
|
||||
auto itp = pv.picked().rbegin();
|
||||
for (; itp != pv.picked().rend(); itp++){
|
||||
if ( s->contains( (*itp).first ) ){
|
||||
auto itp = pv.rbegin();
|
||||
for (; itp != pv.rend(); itp++){
|
||||
// test if source contains this node
|
||||
Source::hasNode is_in_source((*itp).first );
|
||||
if ( is_in_source( s ) ){
|
||||
// a node in the current source was clicked !
|
||||
pick = *itp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// not found: the current source was not clicked
|
||||
if (itp == pv.picked().rend())
|
||||
if (itp == pv.rend())
|
||||
s = nullptr;
|
||||
}
|
||||
// maybe the source changed
|
||||
if (s == nullptr)
|
||||
{
|
||||
// the clicked source changed (not the current source)
|
||||
if (s == nullptr) {
|
||||
// select top-most Node picked
|
||||
pick = pv.picked().back();
|
||||
pick = pv.back();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user