New Grid Primitive, new Coloring visitor and some Scene corrections

This commit is contained in:
Bruno Herbelin
2023-08-21 23:02:34 +02:00
parent a8bb4ae6d1
commit d0e1101bfb
6 changed files with 222 additions and 45 deletions

View File

@@ -21,9 +21,12 @@
#include <glm/gtc/matrix_transform.hpp>
#include "Decorations.h"
#include "defines.h"
#include "DrawVisitor.h"
#include "Scene.h"
#include "Primitives.h"
#include "DrawVisitor.h"
DrawVisitor::DrawVisitor(Node *nodetodraw, glm::mat4 projection, bool force): force_(force)
@@ -115,3 +118,65 @@ void DrawVisitor::visit(Switch &n)
void DrawVisitor::visit(Primitive &)
{
}
ColorVisitor::ColorVisitor(glm::vec4 color): color_(color)
{
}
void ColorVisitor::visit(Node &)
{
}
void ColorVisitor::visit(Group &n)
{
// traverse children
for (NodeSet::iterator node = n.begin(); node != n.end(); ++node) {
(*node)->accept(*this);
}
}
void ColorVisitor::visit(Scene &n)
{
n.root()->accept(*this);
}
void ColorVisitor::visit(Switch &n)
{
n.activeChild()->accept(*this);
}
void ColorVisitor::visit(Primitive &p)
{
p.shader()->color = color_;
}
void ColorVisitor::visit(Frame &d)
{
d.color = color_;
}
void ColorVisitor::visit(Handles &d)
{
d.color = color_;
}
void ColorVisitor::visit(Symbol &d)
{
d.color = color_;
}
void ColorVisitor::visit(Disk &d)
{
d.color = color_;
}
void ColorVisitor::visit(Character &d)
{
d.color = color_;
}

View File

@@ -1,9 +1,16 @@
#ifndef DRAWVISITOR_H
#define DRAWVISITOR_H
#include "GlmToolkit.h"
#include <vector>
#include <glm/glm.hpp>
#include "Visitor.h"
///
/// \brief The DrawVisitor is typically called on a scene.
/// It traverses its root and draws only the nodes
/// listed in the constructor. The nodes listed must already
/// be in the hierarchy of the scene
///
class DrawVisitor : public Visitor
{
glm::mat4 modelview_;
@@ -26,4 +33,31 @@ public:
void visit(Switch& n) override;
};
///
/// \brief The ColorVisitor changes the colors of
/// all nodes that can draw (e.g. primitive, decorations)
/// to the given color
///
class ColorVisitor : public Visitor
{
glm::vec4 color_;
public:
ColorVisitor(glm::vec4 color);
void visit(Scene& n) override;
void visit(Node& n) override;
void visit(Group& n) override;
void visit(Switch& n) override;
void visit(Primitive& ) override;
void visit(Frame& ) override;
void visit(Handles& ) override;
void visit(Symbol& ) override;
void visit(Disk& ) override;
void visit(Character& ) override;
};
#endif // DRAWVISITOR_H

View File

@@ -192,7 +192,7 @@ void Points::accept(Visitor& v)
HLine::HLine(float linewidth): Primitive(new Shader), width(linewidth)
HLine::HLine(float linewidth, Shader *s): Primitive(s), width(linewidth)
{
// 1 3
// +-------+ ^
@@ -216,9 +216,6 @@ HLine::HLine(float linewidth): Primitive(new Shader), width(linewidth)
// default scale
scale_.y = width;
//default color
color = glm::vec4( 1.f, 1.f, 1.f, 1.f);
}
HLine::~HLine()
@@ -271,13 +268,10 @@ void HLine::draw(glm::mat4 modelview, glm::mat4 projection)
scale_.y = (float) width / vec.y;
update(0);
// change color
shader_->color = color;
Primitive::draw(modelview, projection);
}
VLine::VLine(float linewidth): Primitive(new Shader), width(linewidth)
VLine::VLine(float linewidth, Shader *s): Primitive(s), width(linewidth)
{
points_ = std::vector<glm::vec3> { glm::vec3( 0.f, -1.f, 0.f ),
glm::vec3( 0.001f, -0.999f, 0.f ),
@@ -293,9 +287,6 @@ VLine::VLine(float linewidth): Primitive(new Shader), width(linewidth)
// default scale
scale_.x = width;
// default color
color = glm::vec4( 1.f, 1.f, 1.f, 1.f);
}
VLine::~VLine()
@@ -348,45 +339,53 @@ void VLine::draw(glm::mat4 modelview, glm::mat4 projection)
scale_.x = width / vec.x;
update(0);
// change color
shader_->color = color;
Primitive::draw(modelview, projection);
}
LineSquare::LineSquare(float linewidth) : Group()
{
top_ = new HLine(linewidth);
shader__ = new Shader;
top_ = new HLine(linewidth, shader__);
top_->translation_ = glm::vec3(0.f, 1.f, 0.f);
attach(top_);
bottom_ = new HLine(linewidth);
bottom_ = new HLine(linewidth, shader__);
bottom_->translation_ = glm::vec3(0.f, -1.f, 0.f);
attach(bottom_);
left_ = new VLine(linewidth);
left_ = new VLine(linewidth, shader__);
left_->translation_ = glm::vec3(-1.f, 0.f, 0.f);
attach(left_);
right_ = new VLine(linewidth);
right_ = new VLine(linewidth, shader__);
right_->translation_ = glm::vec3(1.f, 0.f, 0.f);
attach(right_);
}
LineSquare::LineSquare(const LineSquare &square)
{
top_ = new HLine(square.top_->width);
shader__ = new Shader;
shader__->color = square.color();
top_ = new HLine(square.top_->width, shader__);
top_->translation_ = glm::vec3(0.f, 1.f, 0.f);
attach(top_);
bottom_ = new HLine(square.bottom_->width);
bottom_ = new HLine(square.bottom_->width, shader__);
bottom_->translation_ = glm::vec3(0.f, -1.f, 0.f);
attach(bottom_);
left_ = new VLine(square.left_->width);
left_ = new VLine(square.left_->width, shader__);
left_->translation_ = glm::vec3(-1.f, 0.f, 0.f);
attach(left_);
right_ = new VLine(square.right_->width);
right_ = new VLine(square.right_->width, shader__);
right_->translation_ = glm::vec3(1.f, 0.f, 0.f);
attach(right_);
}
setColor(square.color());
LineSquare::~LineSquare()
{
top_->replaceShader(nullptr);
bottom_->replaceShader(nullptr);
left_->replaceShader(nullptr);
right_->replaceShader(nullptr);
delete shader__;
}
void LineSquare::setLineWidth(float v)
@@ -397,12 +396,74 @@ void LineSquare::setLineWidth(float v)
right_->width = v;
}
void LineSquare::setColor(glm::vec4 c)
LineGrid::LineGrid(size_t N, float step, float linewidth)
{
top_->color = c;
bottom_->color = c;
left_->color = c;
right_->color = c;
shader__ = new Shader;
N = MAX(1, N);
for (size_t n = 0; n < N ; ++n) {
VLine *l = new VLine(linewidth, shader__);
l->translation_.x = (float)n * step;
l->scale_.y = (float)N * step;
attach(l);
}
for (size_t n = 1; n < N ; ++n) {
VLine *l = new VLine(linewidth, shader__);
l->translation_.x = (float)n * -step;
l->scale_.y = (float)N * step;
attach(l);
}
for (size_t n = 0; n < N ; ++n) {
HLine *l = new HLine(linewidth, shader__);
l->translation_.y = (float)n * step;
l->scale_.x = (float)N * step;
attach(l);
}
for (size_t n = 1; n < N ; ++n) {
HLine *l = new HLine(linewidth, shader__);
l->translation_.y = (float)n * -step;
l->scale_.x = (float)N * step;
attach(l);
}
}
LineGrid::~LineGrid()
{
// prevent nodes from deleting the shader
for (NodeSet::iterator node = begin(); node != end(); ++node) {
Primitive *p = dynamic_cast<Primitive *>(*node);
if (p)
p->replaceShader(nullptr);
}
delete shader__;
}
void LineGrid::setLineWidth(float v)
{
for (NodeSet::iterator node = begin(); node != end(); ++node) {
VLine *vl = dynamic_cast<VLine *>(*node);
if (vl) {
vl->width = v;
continue;
}
HLine *hl = dynamic_cast<HLine *>(*node);
if (hl)
hl->width = v;
}
}
float LineGrid::lineWidth() const
{
Node *n = front();
if (n) {
VLine *vl = dynamic_cast<VLine *>(n);
if (vl)
return vl->width;
HLine *hl = dynamic_cast<HLine *>(n);
if (hl)
return hl->width;
}
return 0.f;
}
LineStrip::LineStrip(const std::vector<glm::vec2> &path, float linewidth) : Primitive(new Shader),

View File

@@ -108,13 +108,12 @@ class HLine : public Primitive {
public:
HLine(float width = 1.f);
HLine(float width = 1.f, Shader *s = new Shader);
virtual ~HLine();
void init () override;
void draw(glm::mat4 modelview, glm::mat4 projection) override;
glm::vec4 color;
float width;
};
@@ -122,13 +121,12 @@ class VLine : public Primitive {
public:
VLine(float width = 1.f);
VLine(float width = 1.f, Shader *s = new Shader);
virtual ~VLine();
void init () override;
void draw(glm::mat4 modelview, glm::mat4 projection) override;
glm::vec4 color;
float width;
};
@@ -137,18 +135,38 @@ public:
*/
class LineSquare : public Group {
Shader *shader__;
HLine *top_, *bottom_;
VLine *left_, *right_;
public:
LineSquare(float linewidth = 1.f);
LineSquare(const LineSquare &square);
virtual ~LineSquare();
void setLineWidth(float v);
inline float lineWidth() const { return top_->width; }
void setColor(glm::vec4 c);
inline glm::vec4 color() const { return top_->color; }
inline void setColor(glm::vec4 c) { shader__->color = c; }
inline glm::vec4 color() const { return shader__->color; }
};
/**
* @brief The Grid class is a group of NxN vertical and horizontal lines
*/
class LineGrid : public Group {
Shader *shader__;
public:
LineGrid(size_t N, float step, float linewidth = 1.f);
~LineGrid();
void setLineWidth(float v);
float lineWidth() const;
inline void setColor(glm::vec4 c) { shader__->color = c; }
inline glm::vec4 color() const { return shader__->color; }
};
/**

View File

@@ -230,10 +230,10 @@ void Primitive::replaceShader( Shader *newshader )
color = shader_->color;
delete shader_;
}
shader_ = newshader;
shader_->iTransform = iTransform;
shader_->color = color;
}
shader_ = newshader;
}
//
@@ -268,7 +268,6 @@ void Group::attach(Node *child)
}
}
void Group::sort()
{
// reorder list of nodes
@@ -338,17 +337,17 @@ NodeSet::iterator Group::end()
}
Node *Group::front()
Node *Group::front() const
{
if (!children_.empty())
return *children_.rbegin();
return *children_.crbegin();
return nullptr;
}
Node *Group::back()
Node *Group::back() const
{
if (!children_.empty())
return *children_.begin();
return *children_.cbegin();
return nullptr;
}

View File

@@ -178,8 +178,8 @@ public:
void sort();
NodeSet::iterator begin();
NodeSet::iterator end();
Node *front();
Node *back();
Node *front() const;
Node *back() const;
protected:
NodeSet children_;