Improved DrawVisitor to accept list of nodes

This commit is contained in:
Bruno
2021-01-24 17:16:28 +01:00
parent edeec9568e
commit b17136d23a
2 changed files with 25 additions and 13 deletions

View File

@@ -1,3 +1,4 @@
#include <algorithm>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
@@ -8,14 +9,21 @@
DrawVisitor::DrawVisitor(Node *nodetodraw, glm::mat4 projection, bool force): force_(force) DrawVisitor::DrawVisitor(Node *nodetodraw, glm::mat4 projection, bool force): force_(force)
{ {
target_ = nodetodraw; targets_.push_back(nodetodraw);
modelview_ = glm::identity<glm::mat4>(); modelview_ = glm::identity<glm::mat4>();
projection_ = projection; projection_ = projection;
done_ = false;
num_duplicat_ = 1; num_duplicat_ = 1;
transform_duplicat_ = glm::identity<glm::mat4>(); transform_duplicat_ = glm::identity<glm::mat4>();
} }
DrawVisitor::DrawVisitor(std::vector<Node *> nodestodraw, glm::mat4 projection, bool force): force_(force)
{
targets_ = nodestodraw;
modelview_ = glm::identity<glm::mat4>();
projection_ = projection;
num_duplicat_ = 1;
transform_duplicat_ = glm::identity<glm::mat4>();
}
void DrawVisitor::loop(int num, glm::mat4 transform) void DrawVisitor::loop(int num, glm::mat4 transform)
{ {
@@ -30,22 +38,25 @@ void DrawVisitor::visit(Node &n)
if (force_) if (force_)
n.visible_ = true; n.visible_ = true;
// draw the target // find the node with this id
if ( target_ && n.id() == target_->id()) { std::vector<Node *>::iterator it = std::find_if(targets_.begin(), targets_.end(), hasId(n.id()));
// found this node in the list of targets: draw it
if (it != targets_.end()) {
targets_.erase(it);
for (int i = 0; i < num_duplicat_; ++i) { for (int i = 0; i < num_duplicat_; ++i) {
// draw multiple copies if requested // draw multiple copies if requested
n.draw(modelview_, projection_); n.draw(modelview_, projection_);
modelview_ *= transform_duplicat_; modelview_ *= transform_duplicat_;
} }
done_ = true;
} }
// restore visibility // restore visibility
n.visible_ = v; n.visible_ = v;
if (done_) return; if (targets_.empty()) return;
// update transform // update transform
modelview_ *= n.transform_; modelview_ *= n.transform_;
@@ -55,11 +66,11 @@ void DrawVisitor::visit(Node &n)
void DrawVisitor::visit(Group &n) void DrawVisitor::visit(Group &n)
{ {
// no need to traverse deeper if this node was drawn already // no need to traverse deeper if this node was drawn already
if (done_) return; if (targets_.empty()) return;
// traverse children // traverse children
glm::mat4 mv = modelview_; glm::mat4 mv = modelview_;
for (NodeSet::iterator node = n.begin(); !done_ && node != n.end(); node++) { for (NodeSet::iterator node = n.begin(); !targets_.empty() && node != n.end(); node++) {
if ( (*node)->visible_ || force_) if ( (*node)->visible_ || force_)
(*node)->accept(*this); (*node)->accept(*this);
modelview_ = mv; modelview_ = mv;
@@ -68,7 +79,6 @@ void DrawVisitor::visit(Group &n)
void DrawVisitor::visit(Scene &n) void DrawVisitor::visit(Scene &n)
{ {
done_ = false;
modelview_ = glm::identity<glm::mat4>(); modelview_ = glm::identity<glm::mat4>();
n.root()->accept(*this); n.root()->accept(*this);
} }
@@ -76,7 +86,7 @@ void DrawVisitor::visit(Scene &n)
void DrawVisitor::visit(Switch &n) void DrawVisitor::visit(Switch &n)
{ {
// no need to traverse deeper if this node was drawn already // no need to traverse deeper if this node was drawn already
if (done_) return; if (targets_.empty()) return;
// traverse acive child // traverse acive child
glm::mat4 mv = modelview_; glm::mat4 mv = modelview_;

View File

@@ -1,6 +1,8 @@
#ifndef DRAWVISITOR_H #ifndef DRAWVISITOR_H
#define DRAWVISITOR_H #define DRAWVISITOR_H
#include <vector>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "Visitor.h" #include "Visitor.h"
@@ -8,14 +10,14 @@ class DrawVisitor : public Visitor
{ {
glm::mat4 modelview_; glm::mat4 modelview_;
glm::mat4 projection_; glm::mat4 projection_;
Node *target_; std::vector<Node *> targets_;
bool done_;
bool force_; bool force_;
int num_duplicat_; int num_duplicat_;
glm::mat4 transform_duplicat_; glm::mat4 transform_duplicat_;
public: public:
DrawVisitor(Node *nodetodraw, glm::mat4 projection, bool force = false); DrawVisitor(Node *nodetodraw, glm::mat4 projection, bool force = false);
DrawVisitor(std::vector<Node *> nodestodraw, glm::mat4 projection, bool force = false);
void loop(int num, glm::mat4 transform); void loop(int num, glm::mat4 transform);