mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
Initial implementation of handles on sources to manipulate in geometry
view (only resize implemented so far)
This commit is contained in:
@@ -226,6 +226,7 @@ set(VMIX_SRCS
|
||||
ImGuiToolkit.cpp
|
||||
ImGuiVisitor.cpp
|
||||
GstToolkit.cpp
|
||||
GlmToolkit.cpp
|
||||
SystemToolkit.cpp
|
||||
tinyxml2Toolkit.cpp
|
||||
)
|
||||
|
||||
@@ -20,7 +20,6 @@ glm::vec3 FrameBuffer::getResolutionFromParameters(int ar, int h)
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
FrameBuffer::FrameBuffer(glm::vec3 resolution): textureid_(0), framebufferid_(0), usedepth_(false)
|
||||
{
|
||||
attrib_.viewport = glm::ivec2(resolution);
|
||||
|
||||
136
GlmToolkit.cpp
Normal file
136
GlmToolkit.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
// Freely inspired from https://github.com/alter-rokuz/glm-aabb.git
|
||||
|
||||
#include "GlmToolkit.h"
|
||||
|
||||
#include <glm/gtc/matrix_access.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/random.hpp>
|
||||
|
||||
glm::mat4 GlmToolkit::transform(glm::vec3 translation, glm::vec3 rotation, glm::vec3 scale)
|
||||
{
|
||||
glm::mat4 View = glm::translate(glm::identity<glm::mat4>(), translation);
|
||||
View = glm::rotate(View, rotation.x, glm::vec3(1.f, 0.f, 0.f));
|
||||
View = glm::rotate(View, rotation.y, glm::vec3(0.f, 1.f, 0.f));
|
||||
View = glm::rotate(View, rotation.z, glm::vec3(0.f, 0.f, 1.f));
|
||||
glm::mat4 Model = glm::scale(glm::identity<glm::mat4>(), scale);
|
||||
return View * Model;
|
||||
}
|
||||
|
||||
|
||||
GlmToolkit::AxisAlignedBoundingBox::AxisAlignedBoundingBox() {
|
||||
mMin = glm::vec3(1.f);
|
||||
mMax = glm::vec3(-1.f);
|
||||
}
|
||||
|
||||
void GlmToolkit::AxisAlignedBoundingBox::extend(const glm::vec3& point)
|
||||
{
|
||||
if (isNull()) {
|
||||
mMin = point;
|
||||
mMax = point;
|
||||
}
|
||||
// general case
|
||||
else {
|
||||
mMin = glm::min(point, mMin);
|
||||
mMax = glm::max(point, mMax);
|
||||
}
|
||||
}
|
||||
|
||||
void GlmToolkit::AxisAlignedBoundingBox::extend(std::vector<glm::vec3> points)
|
||||
{
|
||||
for (auto p = points.begin(); p != points.end(); p++)
|
||||
extend(*p);
|
||||
}
|
||||
|
||||
|
||||
void GlmToolkit::AxisAlignedBoundingBox::extend(const AxisAlignedBoundingBox& bb)
|
||||
{
|
||||
if (bb.isNull())
|
||||
return;
|
||||
|
||||
if (isNull()) {
|
||||
mMin = bb.mMin;
|
||||
mMax = bb.mMax;
|
||||
}
|
||||
// general case
|
||||
else {
|
||||
mMin = glm::min(bb.mMin, mMin);
|
||||
mMax = glm::max(bb.mMax, mMax);
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 GlmToolkit::AxisAlignedBoundingBox::center() const
|
||||
{
|
||||
if (!isNull())
|
||||
{
|
||||
glm::vec3 d = mMax - mMin;
|
||||
return mMin + (d * 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
return glm::vec3(0.f);
|
||||
}
|
||||
}
|
||||
|
||||
bool GlmToolkit::AxisAlignedBoundingBox::intersect(const AxisAlignedBoundingBox& bb, bool ignore_z) const
|
||||
{
|
||||
if (isNull() || bb.isNull())
|
||||
return false;
|
||||
|
||||
if ( (mMax.x < bb.mMin.x) || (mMin.x > bb.mMax.x) ||
|
||||
(mMax.y < bb.mMin.y) || (mMin.y > bb.mMax.y) ||
|
||||
( !ignore_z && ((mMax.z < bb.mMin.z) || (mMin.z > bb.mMax.z)) ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GlmToolkit::AxisAlignedBoundingBox::contains(const AxisAlignedBoundingBox& bb, bool ignore_z) const
|
||||
{
|
||||
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)) ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GlmToolkit::AxisAlignedBoundingBox::contains(glm::vec3 point, bool ignore_z) const
|
||||
{
|
||||
if ( (mMax.x < point.x) || (mMin.x > point.x) ||
|
||||
(mMax.y < point.y) || (mMin.y > point.y) ||
|
||||
( !ignore_z && ((mMax.z < point.z) || (mMin.z > point.z)) ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::translated(glm::vec3 t)
|
||||
{
|
||||
GlmToolkit::AxisAlignedBoundingBox bb;
|
||||
bb = *this;
|
||||
|
||||
bb.mMin += t;
|
||||
bb.mMax += t;
|
||||
|
||||
return bb;
|
||||
}
|
||||
|
||||
GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::scaled(glm::vec3 s)
|
||||
{
|
||||
GlmToolkit::AxisAlignedBoundingBox bb;
|
||||
bb = *this;
|
||||
|
||||
bb.mMin *= s;
|
||||
bb.mMax *= s;
|
||||
|
||||
return bb;
|
||||
}
|
||||
|
||||
48
GlmToolkit.h
Normal file
48
GlmToolkit.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef GLMTOOLKIT_H
|
||||
#define GLMTOOLKIT_H
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace GlmToolkit
|
||||
{
|
||||
|
||||
glm::mat4 transform(glm::vec3 translation, glm::vec3 rotation, glm::vec3 scale);
|
||||
|
||||
|
||||
class AxisAlignedBoundingBox
|
||||
{
|
||||
glm::vec3 mMin;
|
||||
glm::vec3 mMax;
|
||||
|
||||
public:
|
||||
AxisAlignedBoundingBox();
|
||||
|
||||
void operator = (const AxisAlignedBoundingBox &D ) {
|
||||
mMin = D.mMin;
|
||||
mMax = D.mMax;
|
||||
}
|
||||
|
||||
// test
|
||||
inline bool isNull() const { return mMin.x > mMax.x || mMin.y > mMax.y || mMin.z > mMax.z;}
|
||||
inline glm::vec3 min() const { return mMin; }
|
||||
inline glm::vec3 max() const { return mMax; }
|
||||
glm::vec3 center() const;
|
||||
bool intersect(const AxisAlignedBoundingBox& bb, bool ignore_z = true) const;
|
||||
bool contains(const AxisAlignedBoundingBox& bb, bool ignore_z = true) const;
|
||||
bool contains(glm::vec3 point, bool ignore_z = true) const;
|
||||
|
||||
// build
|
||||
void extend(const glm::vec3& point);
|
||||
void extend(std::vector<glm::vec3> points);
|
||||
void extend(const AxisAlignedBoundingBox& bb);
|
||||
|
||||
AxisAlignedBoundingBox translated(glm::vec3 t);
|
||||
AxisAlignedBoundingBox scaled(glm::vec3 s);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // GLMTOOLKIT_H
|
||||
@@ -15,15 +15,8 @@ public:
|
||||
void visit(Switch& n) override;
|
||||
void visit(Animation& n) override;
|
||||
void visit(Primitive& n) override;
|
||||
void visit(Surface&) override {}
|
||||
void visit(ImageSurface&) override {}
|
||||
void visit(MediaSurface& n) override;
|
||||
void visit(FrameBufferSurface& n) override;
|
||||
void visit(LineStrip&) override {}
|
||||
void visit(LineSquare&) override {}
|
||||
void visit(LineCircle&) override {}
|
||||
void visit(Mesh&) override {}
|
||||
void visit(Frame&) override {}
|
||||
|
||||
// Elements with attributes
|
||||
void visit(MediaPlayer& n) override;
|
||||
|
||||
119
Mesh.cpp
119
Mesh.cpp
@@ -8,11 +8,14 @@
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include "Resource.h"
|
||||
#include "ImageShader.h"
|
||||
#include "Visitor.h"
|
||||
#include "Log.h"
|
||||
#include "Mesh.h"
|
||||
#include "GlmToolkit.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace glm;
|
||||
@@ -321,6 +324,7 @@ bool parsePLY(string ascii,
|
||||
}
|
||||
|
||||
|
||||
|
||||
Mesh::Mesh(const std::string& ply_path, const std::string& tex_path) : Primitive(), mesh_resource_(ply_path), texture_resource_(tex_path), textureindex_(0)
|
||||
{
|
||||
if ( !parsePLY( Resource::getText(mesh_resource_), points_, colors_, texCoords_, indices_, drawMode_) )
|
||||
@@ -361,12 +365,14 @@ void Mesh::draw(glm::mat4 modelview, glm::mat4 projection)
|
||||
if ( !initialized() )
|
||||
init();
|
||||
|
||||
if (textureindex_)
|
||||
glBindTexture(GL_TEXTURE_2D, textureindex_);
|
||||
if ( visible_ ) {
|
||||
if (textureindex_)
|
||||
glBindTexture(GL_TEXTURE_2D, textureindex_);
|
||||
|
||||
Primitive::draw(modelview, projection);
|
||||
Primitive::draw(modelview, projection);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Mesh::accept(Visitor& v)
|
||||
@@ -375,19 +381,17 @@ void Mesh::accept(Visitor& v)
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
Frame::Frame(Style style) : Node()
|
||||
Frame::Frame(Type style) : Node()
|
||||
{
|
||||
overlay_ = nullptr;
|
||||
shadow_ = nullptr;
|
||||
color = glm::vec4( 1.f, 1.f, 1.f, 1.f);
|
||||
switch (style) {
|
||||
case SHARP_HANDLES:
|
||||
border_ = new Mesh("mesh/border_handles_sharp.ply");
|
||||
overlay_ = new Mesh("mesh/border_handles_overlay.ply");
|
||||
case SHARP_LARGE:
|
||||
border_ = new Mesh("mesh/border_large_sharp.ply");
|
||||
shadow_ = new Mesh("mesh/shadow.ply", "images/shadow.png");
|
||||
break;
|
||||
case SHARP_THIN:
|
||||
border_ = new Mesh("mesh/border_sharp.ply");
|
||||
shadow_ = nullptr;
|
||||
break;
|
||||
case ROUND_LARGE:
|
||||
border_ = new Mesh("mesh/border_large_round.ply");
|
||||
@@ -403,7 +407,6 @@ Frame::Frame(Style style) : Node()
|
||||
|
||||
Frame::~Frame()
|
||||
{
|
||||
if(overlay_) delete overlay_;
|
||||
if(border_) delete border_;
|
||||
if(shadow_) delete shadow_;
|
||||
}
|
||||
@@ -411,29 +414,23 @@ Frame::~Frame()
|
||||
void Frame::draw(glm::mat4 modelview, glm::mat4 projection)
|
||||
{
|
||||
if ( !initialized() ) {
|
||||
if(overlay_) overlay_->init();
|
||||
if(border_) border_->init();
|
||||
if(shadow_) shadow_->init();
|
||||
init();
|
||||
}
|
||||
|
||||
if ( visible_ ) { // not absolutely necessary but saves some CPU time..
|
||||
if ( visible_ ) {
|
||||
|
||||
// shadow
|
||||
if(shadow_)
|
||||
shadow_->draw( modelview * transform_, projection);
|
||||
|
||||
if (overlay_) {
|
||||
// overlat is not altered
|
||||
overlay_->shader()->color = color;
|
||||
overlay_->draw( modelview, projection );
|
||||
}
|
||||
|
||||
// right side
|
||||
float ar = scale_.x / scale_.y;
|
||||
glm::vec3 s(scale_.y, scale_.y, 1.0);
|
||||
glm::vec3 t(translation_.x - 1.0 +ar, translation_.y, translation_.z);
|
||||
glm::mat4 ctm = modelview * transform(t, rotation_, s);
|
||||
glm::vec3 s(1.f, 1.f, 1.f);
|
||||
// glm::vec3 s(scale_.y, scale_.y, 1.0);
|
||||
glm::vec3 t(translation_.x - 1.0 + ar, translation_.y, translation_.z);
|
||||
glm::mat4 ctm = modelview * GlmToolkit::transform(t, rotation_, s);
|
||||
|
||||
if(border_) {
|
||||
// right side
|
||||
@@ -442,7 +439,7 @@ void Frame::draw(glm::mat4 modelview, glm::mat4 projection)
|
||||
// left side
|
||||
t.x = -t.x;
|
||||
s.x = -s.x;
|
||||
ctm = modelview * transform(t, rotation_, s);
|
||||
ctm = modelview * GlmToolkit::transform(t, rotation_, s);
|
||||
border_->draw( ctm, projection );
|
||||
}
|
||||
|
||||
@@ -455,3 +452,79 @@ void Frame::accept(Visitor& v)
|
||||
Node::accept(v);
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
Handles::Handles(Type type) : Node(), type_(type)
|
||||
{
|
||||
color = glm::vec4( 1.f, 1.f, 1.f, 1.f);
|
||||
handle_ = new Mesh("mesh/border_handles_overlay.ply");
|
||||
}
|
||||
|
||||
Handles::~Handles()
|
||||
{
|
||||
if(handle_) delete handle_;
|
||||
}
|
||||
|
||||
void Handles::draw(glm::mat4 modelview, glm::mat4 projection)
|
||||
{
|
||||
if ( !initialized() ) {
|
||||
if(handle_) handle_->init();
|
||||
init();
|
||||
}
|
||||
|
||||
if ( visible_ ) {
|
||||
// set color
|
||||
handle_->shader()->color = color;
|
||||
|
||||
float ar = scale_.x / scale_.y;
|
||||
glm::mat4 ctm;
|
||||
|
||||
if ( type_ == RESIZE ) {
|
||||
// 4 corners
|
||||
ctm = modelview * glm::translate(glm::identity<glm::mat4>(), glm::vec3(ar, -1.f, 0.f) );
|
||||
ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f;
|
||||
handle_->draw( ctm, projection );
|
||||
|
||||
ctm = modelview * glm::translate(glm::identity<glm::mat4>(), glm::vec3(ar, +1.f, 0.f));
|
||||
ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f;
|
||||
handle_->draw( ctm, projection );
|
||||
|
||||
ctm = modelview * glm::translate(glm::identity<glm::mat4>(), glm::vec3(-ar, -1.f, 0.f));
|
||||
ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f;
|
||||
handle_->draw( ctm, projection );
|
||||
|
||||
ctm = modelview * glm::translate(glm::identity<glm::mat4>(), glm::vec3(-ar, +1.f, 0.f));
|
||||
ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f;
|
||||
handle_->draw( ctm, projection );
|
||||
}
|
||||
else if ( type_ == RESIZE_H ){
|
||||
// left and right
|
||||
ctm = modelview * glm::translate(glm::identity<glm::mat4>(), glm::vec3(ar, 0.f, 0.f) );
|
||||
ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f;
|
||||
handle_->draw( ctm, projection );
|
||||
|
||||
ctm = modelview * glm::translate(glm::identity<glm::mat4>(), glm::vec3(-ar, 0.f, 0.f));
|
||||
ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f;
|
||||
handle_->draw( ctm, projection );
|
||||
}
|
||||
else if ( type_ == RESIZE_V ){
|
||||
// top and bottom
|
||||
ctm = modelview * glm::translate(glm::identity<glm::mat4>(), glm::vec3(0.f, +1.f, 0.f) );
|
||||
ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f;
|
||||
handle_->draw( ctm, projection );
|
||||
|
||||
ctm = modelview * glm::translate(glm::identity<glm::mat4>(), glm::vec3(0.f, -1.f, 0.f));
|
||||
ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f;
|
||||
handle_->draw( ctm, projection );
|
||||
}
|
||||
else if ( type_ == ROTATE ){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Handles::accept(Visitor& v)
|
||||
{
|
||||
Node::accept(v);
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
40
Mesh.h
40
Mesh.h
@@ -36,20 +36,48 @@ protected:
|
||||
|
||||
class Frame : public Node
|
||||
{
|
||||
Mesh *border_;
|
||||
Mesh *shadow_;
|
||||
|
||||
public:
|
||||
|
||||
typedef enum { ROUND_THIN = 0, ROUND_LARGE, SHARP_THIN, SHARP_HANDLES } Style;
|
||||
Frame(Style style);
|
||||
typedef enum { ROUND_THIN = 0, ROUND_LARGE, SHARP_THIN, SHARP_LARGE } Type;
|
||||
Frame(Type style);
|
||||
~Frame();
|
||||
|
||||
void draw (glm::mat4 modelview, glm::mat4 projection) override;
|
||||
void accept (Visitor& v) override;
|
||||
|
||||
Mesh *overlay_;
|
||||
Type type() const { return type_; }
|
||||
Mesh *border() const { return border_; }
|
||||
glm::vec4 color;
|
||||
|
||||
protected:
|
||||
Mesh *border_;
|
||||
Mesh *shadow_;
|
||||
Type type_;
|
||||
|
||||
};
|
||||
|
||||
class Handles : public Node
|
||||
{
|
||||
public:
|
||||
typedef enum { RESIZE = 0, RESIZE_H, RESIZE_V, ROTATE } Type;
|
||||
Handles(Type type);
|
||||
~Handles();
|
||||
|
||||
void draw (glm::mat4 modelview, glm::mat4 projection) override;
|
||||
void accept (Visitor& v) override;
|
||||
|
||||
Type type() const { return type_; }
|
||||
Mesh *handle() const { return handle_; }
|
||||
glm::vec4 color;
|
||||
|
||||
protected:
|
||||
Mesh *handle_;
|
||||
Type type_;
|
||||
|
||||
};
|
||||
|
||||
// TODO Shadow mesh with unique vao
|
||||
// TODO dedicated source .cpp .h files for Frame and Handles
|
||||
|
||||
|
||||
#endif // MESH_H
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Log.h"
|
||||
#include "Primitives.h"
|
||||
#include "GlmToolkit.h"
|
||||
#include "Mesh.h"
|
||||
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
@@ -17,8 +18,9 @@ PickingVisitor::PickingVisitor(glm::vec2 coordinates) : Visitor(), point_(coordi
|
||||
|
||||
void PickingVisitor::visit(Node &n)
|
||||
{
|
||||
// use the transform modified during update
|
||||
modelview_ *= n.transform_;
|
||||
|
||||
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());
|
||||
@@ -27,9 +29,9 @@ void PickingVisitor::visit(Node &n)
|
||||
void PickingVisitor::visit(Group &n)
|
||||
{
|
||||
glm::mat4 mv = modelview_;
|
||||
//Log::Info("Group %d", n.id());
|
||||
for (NodeSet::iterator node = n.begin(); node != n.end(); node++) {
|
||||
(*node)->accept(*this);
|
||||
if ( (*node)->visible_ )
|
||||
(*node)->accept(*this);
|
||||
modelview_ = mv;
|
||||
}
|
||||
}
|
||||
@@ -41,33 +43,71 @@ void PickingVisitor::visit(Switch &n)
|
||||
modelview_ = mv;
|
||||
}
|
||||
|
||||
void PickingVisitor::visit(Animation &n)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PickingVisitor::visit(Primitive &n)
|
||||
{
|
||||
// TODO: generic visitor for primitive with random shape
|
||||
|
||||
}
|
||||
|
||||
void PickingVisitor::visit(Surface &n)
|
||||
{
|
||||
// Log::Info("Surface %d", n.id());
|
||||
if (!n.visible_)
|
||||
return;
|
||||
|
||||
// apply inverse transform to the point of interest
|
||||
glm::vec4 P = glm::inverse(modelview_) * glm::vec4( point_, 0.f, 1.f );
|
||||
|
||||
// lower left corner
|
||||
glm::vec3 LL = glm::vec3( -1.f, -1.f, 0.f );
|
||||
// up right corner
|
||||
glm::vec3 UR = glm::vec3( 1.f, 1.f, 0.f );
|
||||
|
||||
// if P is inside [LL UR] rectangle:
|
||||
if ( P.x > LL.x && P.x < UR.x && P.y > LL.y && P.y < UR.y )
|
||||
// test bounding box: it is an exact fit for a resctangular surface
|
||||
if ( n.bbox().contains( glm::vec3(P)) )
|
||||
// add this surface to the nodes picked
|
||||
nodes_.push_back( std::pair(&n, glm::vec2(P)) );
|
||||
}
|
||||
|
||||
void PickingVisitor::visit(Frame &n)
|
||||
{
|
||||
n.border()->accept(*this);
|
||||
}
|
||||
|
||||
void PickingVisitor::visit(Handles &n)
|
||||
{
|
||||
if (!n.visible_)
|
||||
return;
|
||||
|
||||
// apply inverse transform to the point of interest
|
||||
glm::vec4 P = glm::inverse(modelview_) * glm::vec4( point_, 0.f, 1.f );
|
||||
|
||||
// get the bounding box of a handle
|
||||
GlmToolkit::AxisAlignedBoundingBox bb = n.handle()->bbox();
|
||||
|
||||
// test picking depending on type of handle
|
||||
bool picked = false;
|
||||
if ( n.type() == Handles::RESIZE ) {
|
||||
// 4 corners
|
||||
picked = ( bb.translated(glm::vec3(+1.f, +1.f, 0.f)).contains( glm::vec3(P) ) ||
|
||||
bb.translated(glm::vec3(+1.f, -1.f, 0.f)).contains( glm::vec3(P) ) ||
|
||||
bb.translated(glm::vec3(-1.f, +1.f, 0.f)).contains( glm::vec3(P) ) ||
|
||||
bb.translated(glm::vec3(-1.f, -1.f, 0.f)).contains( glm::vec3(P) ) );
|
||||
}
|
||||
else if ( n.type() == Handles::RESIZE_H ){
|
||||
// left & right
|
||||
picked = ( bb.translated(glm::vec3(+1.f, 0.f, 0.f)).contains( glm::vec3(P) ) ||
|
||||
bb.translated(glm::vec3(-1.f, 0.f, 0.f)).contains( glm::vec3(P) ) );
|
||||
}
|
||||
else if ( n.type() == Handles::RESIZE_V ){
|
||||
// top & bottom
|
||||
picked = ( bb.translated(glm::vec3(0.f, +1.f, 0.f)).contains( glm::vec3(P) ) ||
|
||||
bb.translated(glm::vec3(0.f, -1.f, 0.f)).contains( glm::vec3(P) ) );
|
||||
}
|
||||
else if ( n.type() == Handles::ROTATE ){
|
||||
// TODO Picking Rotation
|
||||
}
|
||||
|
||||
if ( picked )
|
||||
// add this surface to the nodes picked
|
||||
nodes_.push_back( std::pair(&n, glm::vec2(P)) );
|
||||
|
||||
}
|
||||
|
||||
void PickingVisitor::visit(LineSquare &)
|
||||
{
|
||||
// apply inverse transform to the point of interest
|
||||
|
||||
@@ -20,21 +20,17 @@ public:
|
||||
std::vector< std::pair<Node *, glm::vec2> > picked() { return nodes_; }
|
||||
|
||||
// Elements of Scene
|
||||
void visit(Scene& n);
|
||||
void visit(Node& n);
|
||||
void visit(Group& n);
|
||||
void visit(Switch& n);
|
||||
void visit(Animation& n);
|
||||
void visit(Primitive& n);
|
||||
void visit(Surface& n);
|
||||
void visit(ImageSurface&){}
|
||||
void visit(MediaSurface&){}
|
||||
void visit(FrameBufferSurface&){}
|
||||
void visit(LineStrip&){}
|
||||
void visit(LineSquare&);
|
||||
void visit(LineCircle& n);
|
||||
void visit(Mesh&){}
|
||||
void visit(Frame&){}
|
||||
void visit(Scene& n) override;
|
||||
void visit(Node& n) override;
|
||||
void visit(Group& n) override;
|
||||
void visit(Switch& n) override;
|
||||
void visit(Primitive& n) override;
|
||||
void visit(Surface& n) override;
|
||||
void visit(Frame& n) override;
|
||||
void visit(Handles& n) override;
|
||||
void visit(LineSquare&) override;
|
||||
void visit(LineCircle& n) override;
|
||||
|
||||
};
|
||||
|
||||
#endif // PICKINGVISITOR_H
|
||||
|
||||
@@ -66,6 +66,9 @@ void Surface::init()
|
||||
unique_drawCount = drawCount_;
|
||||
// 3. unique_vao_ will NOT be deleted
|
||||
}
|
||||
|
||||
// replace AxisAlignedBoundingBox
|
||||
bbox_.extend(square_points);
|
||||
}
|
||||
|
||||
void Surface::accept(Visitor& v)
|
||||
@@ -220,6 +223,8 @@ void Points::draw(glm::mat4 modelview, glm::mat4 projection)
|
||||
glPointSize(pointsize_);
|
||||
|
||||
Primitive::draw(modelview, projection);
|
||||
|
||||
glPointSize(1);
|
||||
}
|
||||
|
||||
void Points::accept(Visitor& v)
|
||||
@@ -248,6 +253,8 @@ void LineStrip::draw(glm::mat4 modelview, glm::mat4 projection)
|
||||
glLineWidth(linewidth_);
|
||||
|
||||
Primitive::draw(modelview, projection);
|
||||
|
||||
glLineWidth(1);
|
||||
}
|
||||
|
||||
void LineStrip::accept(Visitor& v)
|
||||
@@ -272,6 +279,11 @@ void LineSquare::init()
|
||||
// 2. use the global vertex array object
|
||||
vao_ = unique_vao_;
|
||||
drawCount_ = unique_drawCount;
|
||||
// arrays of vertices are not needed anymore (STATIC DRAW of vertex object)
|
||||
points_.clear();
|
||||
colors_.clear();
|
||||
texCoords_.clear();
|
||||
indices_.clear();
|
||||
}
|
||||
else {
|
||||
// 1. init the Primitive (only once)
|
||||
@@ -279,8 +291,10 @@ void LineSquare::init()
|
||||
// 2. remember global vertex array object
|
||||
unique_vao_ = vao_;
|
||||
unique_drawCount = drawCount_;
|
||||
// 3. unique_vao_ will NOT be deleted because LineCircle::deleteGLBuffers_() is empty
|
||||
}
|
||||
|
||||
// compute AxisAlignedBoundingBox
|
||||
bbox_.extend(square_points);
|
||||
}
|
||||
|
||||
void LineSquare::accept(Visitor& v)
|
||||
@@ -300,6 +314,7 @@ LineCircle::LineCircle(glm::vec4 color, uint linewidth) : LineStrip(std::vector<
|
||||
{
|
||||
static int N = 72;
|
||||
static float a = glm::two_pi<float>() / static_cast<float>(N);
|
||||
// loop to build a circle
|
||||
glm::vec3 P(1.f, 0.f, 0.f);
|
||||
for (int i = 0; i < N ; i++ ){
|
||||
points_.push_back( glm::vec3(P) );
|
||||
@@ -308,7 +323,7 @@ LineCircle::LineCircle(glm::vec4 color, uint linewidth) : LineStrip(std::vector<
|
||||
|
||||
P = glm::rotateZ(P, a);
|
||||
}
|
||||
// loop
|
||||
// close loop
|
||||
points_.push_back( glm::vec3(1.f, 0.f, 0.f) );
|
||||
colors_.push_back( color );
|
||||
indices_.push_back ( N );
|
||||
@@ -324,7 +339,14 @@ void LineCircle::init()
|
||||
Node::init();
|
||||
// 2. use the global vertex array object
|
||||
vao_ = unique_vao_;
|
||||
drawCount_ = unique_drawCount;
|
||||
drawCount_ = unique_drawCount;
|
||||
// replace AxisAlignedBoundingBox
|
||||
bbox_.extend(points_);
|
||||
// arrays of vertices are not needed anymore (STATIC DRAW of vertex object)
|
||||
points_.clear();
|
||||
colors_.clear();
|
||||
texCoords_.clear();
|
||||
indices_.clear();
|
||||
}
|
||||
else {
|
||||
// 1. init the Primitive (only once)
|
||||
|
||||
19
Scene.cpp
19
Scene.cpp
@@ -5,7 +5,7 @@
|
||||
#include "Visitor.h"
|
||||
#include "GarbageVisitor.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include "GlmToolkit.h"
|
||||
#include "SessionVisitor.h"
|
||||
|
||||
#include <glad/glad.h>
|
||||
@@ -20,18 +20,6 @@
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
//Group *Scene::limbo = new Group;
|
||||
|
||||
glm::mat4 transform(glm::vec3 translation, glm::vec3 rotation, glm::vec3 scale)
|
||||
{
|
||||
glm::mat4 View = glm::translate(glm::identity<glm::mat4>(), translation);
|
||||
View = glm::rotate(View, rotation.x, glm::vec3(1.f, 0.f, 0.f));
|
||||
View = glm::rotate(View, rotation.y, glm::vec3(0.f, 1.f, 0.f));
|
||||
View = glm::rotate(View, rotation.z, glm::vec3(0.f, 0.f, 1.f));
|
||||
glm::mat4 Model = glm::scale(glm::identity<glm::mat4>(), scale);
|
||||
return View * Model;
|
||||
}
|
||||
|
||||
// Node
|
||||
Node::Node() : initialized_(false), visible_(true), refcount_(0)
|
||||
{
|
||||
@@ -63,7 +51,7 @@ void Node::copyTransform(Node *other)
|
||||
void Node::update( float )
|
||||
{
|
||||
// update transform matrix from attributes
|
||||
transform_ = transform(translation_, rotation_, scale_);
|
||||
transform_ = GlmToolkit::transform(translation_, rotation_, scale_);
|
||||
|
||||
}
|
||||
|
||||
@@ -137,6 +125,9 @@ void Primitive::init()
|
||||
if ( elementBuffer_ )
|
||||
glDeleteBuffers ( 1, &elementBuffer_);
|
||||
|
||||
// compute AxisAlignedBoundingBox
|
||||
bbox_.extend(points_);
|
||||
|
||||
// arrays of vertices are not needed anymore (STATIC DRAW of vertex object)
|
||||
points_.clear();
|
||||
colors_.clear();
|
||||
|
||||
10
Scene.h
10
Scene.h
@@ -10,16 +10,14 @@
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
glm::mat4 transform(glm::vec3 translation, glm::vec3 rotation, glm::vec3 scale);
|
||||
#include "GlmToolkit.h"
|
||||
|
||||
// Forward declare classes referenced
|
||||
class Shader;
|
||||
class Visitor;
|
||||
class Group;
|
||||
|
||||
|
||||
/**
|
||||
* @brief The Node class is the base virtual class for all Node types
|
||||
*
|
||||
@@ -104,14 +102,16 @@ public:
|
||||
inline Shader *shader () const { return shader_; }
|
||||
void replaceShader (Shader* newshader);
|
||||
|
||||
GlmToolkit::AxisAlignedBoundingBox bbox() const { return bbox_; }
|
||||
|
||||
protected:
|
||||
Shader* shader_;
|
||||
uint vao_, drawMode_, drawCount_;
|
||||
std::vector<glm::vec3> points_;
|
||||
std::vector<glm::vec4> colors_;
|
||||
std::vector<glm::vec2> texCoords_;
|
||||
std::vector<uint> indices_;
|
||||
|
||||
std::vector<uint> indices_;
|
||||
GlmToolkit::AxisAlignedBoundingBox bbox_;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
@@ -18,22 +18,10 @@ public:
|
||||
// Elements of Scene
|
||||
void visit(Scene& n);
|
||||
void visit(Node& n);
|
||||
void visit(Primitive&) {}
|
||||
void visit(Group& n);
|
||||
void visit(Switch& n);
|
||||
|
||||
// already a Node or a Group
|
||||
void visit(Animation&) {}
|
||||
void visit(Primitive&) {}
|
||||
void visit(Surface&) {}
|
||||
void visit(ImageSurface&) {}
|
||||
void visit(MediaSurface&) {}
|
||||
void visit(FrameBufferSurface&) {}
|
||||
void visit(LineStrip&) {}
|
||||
void visit(LineSquare&) {}
|
||||
void visit(LineCircle&) {}
|
||||
void visit(Mesh&) {}
|
||||
void visit(Frame&) {}
|
||||
|
||||
};
|
||||
|
||||
#endif // SEARCHVISITOR_H
|
||||
|
||||
@@ -187,10 +187,10 @@ void SessionCreator::visit (Source& s)
|
||||
s.setName(pName);
|
||||
|
||||
xmlCurrent_ = sourceNode->FirstChildElement("Mixing");
|
||||
s.node(View::MIXING)->accept(*this);
|
||||
s.groupNode(View::MIXING)->accept(*this);
|
||||
|
||||
xmlCurrent_ = sourceNode->FirstChildElement("Geometry");
|
||||
s.node(View::GEOMETRY)->accept(*this);
|
||||
s.groupNode(View::GEOMETRY)->accept(*this);
|
||||
|
||||
xmlCurrent_ = sourceNode->FirstChildElement("Blending");
|
||||
s.blendingShader()->accept(*this);
|
||||
|
||||
@@ -37,7 +37,6 @@ public:
|
||||
void visit(LineSquare&) override {}
|
||||
void visit(LineCircle& n) override {}
|
||||
void visit(Mesh& n) override {}
|
||||
void visit(Frame& n) override {}
|
||||
|
||||
// Elements with attributes
|
||||
void visit(MediaPlayer& n) override;
|
||||
|
||||
@@ -305,11 +305,11 @@ void SessionVisitor::visit (Source& s)
|
||||
|
||||
xmlCurrent_ = xmlDoc_->NewElement( "Mixing" );
|
||||
sourceNode->InsertEndChild(xmlCurrent_);
|
||||
s.node(View::MIXING)->accept(*this);
|
||||
s.groupNode(View::MIXING)->accept(*this);
|
||||
|
||||
xmlCurrent_ = xmlDoc_->NewElement( "Geometry" );
|
||||
sourceNode->InsertEndChild(xmlCurrent_);
|
||||
s.node(View::GEOMETRY)->accept(*this);
|
||||
s.groupNode(View::GEOMETRY)->accept(*this);
|
||||
|
||||
xmlCurrent_ = xmlDoc_->NewElement( "Blending" );
|
||||
sourceNode->InsertEndChild(xmlCurrent_);
|
||||
|
||||
63
Source.cpp
63
Source.cpp
@@ -31,6 +31,11 @@ Source::Source(const std::string &name) : name_(name), initialized_(false)
|
||||
groups_[View::MIXING]->attach(frame);
|
||||
groups_[View::MIXING]->scale_ = glm::vec3(0.15f, 0.15f, 1.f);
|
||||
|
||||
overlays_[View::MIXING] = new Group;
|
||||
overlays_[View::MIXING]->translation_.z = 0.1;
|
||||
overlays_[View::MIXING]->visible_ = false;
|
||||
groups_[View::MIXING]->attach(overlays_[View::MIXING]);
|
||||
|
||||
// default geometry nodes
|
||||
groups_[View::GEOMETRY] = new Group;
|
||||
frame = new Frame(Frame::SHARP_THIN);
|
||||
@@ -38,11 +43,20 @@ Source::Source(const std::string &name) : name_(name), initialized_(false)
|
||||
frame->color = glm::vec4( 0.8f, 0.8f, 0.0f, 0.9f);
|
||||
groups_[View::GEOMETRY]->attach(frame);
|
||||
|
||||
overlays_[View::GEOMETRY] = new Group;
|
||||
overlays_[View::GEOMETRY]->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->visible_ = false;
|
||||
groups_[View::GEOMETRY]->attach(overlays_[View::GEOMETRY]);
|
||||
|
||||
// will be associated to nodes later
|
||||
blendingshader_ = new ImageShader;
|
||||
rendershader_ = new ImageProcessingShader;
|
||||
renderbuffer_ = nullptr;
|
||||
rendersurface_ = nullptr;
|
||||
resize_handle_ = nullptr;
|
||||
resize_H_handle_ = nullptr;
|
||||
resize_V_handle_ = nullptr;
|
||||
rotate_handle_ = nullptr;
|
||||
}
|
||||
|
||||
Source::~Source()
|
||||
@@ -82,6 +96,19 @@ void Source::setOverlayVisible(bool on)
|
||||
(*o).second->visible_ = on;
|
||||
}
|
||||
|
||||
Handles *Source::handleNode(Handles::Type t) const
|
||||
{
|
||||
if ( t == Handles::ROTATE )
|
||||
return rotate_handle_;
|
||||
else if ( t == Handles::RESIZE_H )
|
||||
return resize_H_handle_;
|
||||
else if ( t == Handles::RESIZE_V )
|
||||
return resize_V_handle_;
|
||||
else
|
||||
return resize_handle_;
|
||||
}
|
||||
|
||||
|
||||
bool hasNode::operator()(const Source* elem) const
|
||||
{
|
||||
if (elem)
|
||||
@@ -112,18 +139,29 @@ MediaSource::MediaSource(const std::string &name) : Source(name), path_("")
|
||||
mediasurface_ = new Surface(rendershader_);
|
||||
|
||||
// extra overlay for mixing view
|
||||
overlays_[View::MIXING] = new Frame(Frame::ROUND_LARGE);
|
||||
overlays_[View::MIXING]->translation_.z = 0.1;
|
||||
overlays_[View::MIXING]->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f);
|
||||
overlays_[View::MIXING]->visible_ = false;
|
||||
groups_[View::MIXING]->attach(overlays_[View::MIXING]);
|
||||
Frame *frame = new Frame(Frame::ROUND_LARGE);
|
||||
frame->translation_.z = 0.1;
|
||||
frame->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f);
|
||||
overlays_[View::MIXING]->attach(frame);
|
||||
|
||||
// extra overlay for geometry view
|
||||
overlays_[View::GEOMETRY] = new Frame(Frame::SHARP_HANDLES);
|
||||
overlays_[View::GEOMETRY]->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f);
|
||||
overlays_[View::GEOMETRY]->visible_ = false;
|
||||
groups_[View::GEOMETRY]->attach(overlays_[View::GEOMETRY]);
|
||||
frame = new Frame(Frame::SHARP_LARGE);
|
||||
frame->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f);
|
||||
frame->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->attach(frame);
|
||||
resize_handle_ = new Handles(Handles::RESIZE);
|
||||
resize_handle_->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f);
|
||||
resize_handle_->translation_.z = 0.15;
|
||||
overlays_[View::GEOMETRY]->attach(resize_handle_);
|
||||
resize_H_handle_ = new Handles(Handles::RESIZE_H);
|
||||
resize_H_handle_->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f);
|
||||
resize_H_handle_->translation_.z = 0.15;
|
||||
overlays_[View::GEOMETRY]->attach(resize_H_handle_);
|
||||
resize_V_handle_ = new Handles(Handles::RESIZE_V);
|
||||
resize_V_handle_->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f);
|
||||
resize_V_handle_->translation_.z = 0.15;
|
||||
overlays_[View::GEOMETRY]->attach(resize_V_handle_);
|
||||
|
||||
}
|
||||
|
||||
MediaSource::~MediaSource()
|
||||
@@ -190,9 +228,9 @@ void MediaSource::init()
|
||||
if (is) is->stipple = 1.0;
|
||||
groups_[View::MIXING]->attach(surfacemix);
|
||||
if (mediaplayer_->duration() == GST_CLOCK_TIME_NONE)
|
||||
overlays_[View::MIXING]->overlay_ = new Mesh("mesh/icon_image.ply");
|
||||
overlays_[View::MIXING]->attach( new Mesh("mesh/icon_image.ply") );
|
||||
else
|
||||
overlays_[View::MIXING]->overlay_ = new Mesh("mesh/icon_video.ply");
|
||||
overlays_[View::MIXING]->attach( new Mesh("mesh/icon_video.ply") );
|
||||
|
||||
// scale all mixing nodes to match aspect ratio of the media
|
||||
for (NodeSet::iterator node = groups_[View::MIXING]->begin();
|
||||
@@ -203,7 +241,6 @@ void MediaSource::init()
|
||||
node != groups_[View::GEOMETRY]->end(); node++) {
|
||||
(*node)->scale_.x = mediaplayer_->aspectRatio();
|
||||
}
|
||||
// mixingshader_->mask = ImageShader::mask_presets["Halo"];
|
||||
|
||||
// done init once and for all
|
||||
initialized_ = true;
|
||||
|
||||
16
Source.h
16
Source.h
@@ -6,6 +6,7 @@
|
||||
#include <list>
|
||||
|
||||
#include "View.h"
|
||||
#include "Mesh.h"
|
||||
|
||||
class ImageShader;
|
||||
class ImageProcessingShader;
|
||||
@@ -33,7 +34,8 @@ public:
|
||||
|
||||
// get handle on the node used to manipulate the source in a view
|
||||
inline Group *group(View::Mode m) const { return groups_.at(m); }
|
||||
inline Node *node(View::Mode m) const { return static_cast<Node*>(groups_.at(m)); }
|
||||
inline Node *groupNode(View::Mode m) const { return static_cast<Node*>(groups_.at(m)); }
|
||||
Handles *handleNode(Handles::Type t) const;
|
||||
|
||||
// every Source has a shader to control image processing effects
|
||||
inline ImageProcessingShader *processingShader() const { return rendershader_; }
|
||||
@@ -50,7 +52,7 @@ public:
|
||||
// accept all kind of visitors
|
||||
virtual void accept (Visitor& v);
|
||||
|
||||
// informs if the source failed (and might have to be deleted)
|
||||
// every Source shall informs if the source failed (i.e. shall be deleted)
|
||||
virtual bool failed() const { return false; }
|
||||
|
||||
protected:
|
||||
@@ -73,17 +75,18 @@ protected:
|
||||
// It is associated to the rendershader for mixing effects
|
||||
FrameBufferSurface *rendersurface_;
|
||||
|
||||
// rendershader provides image processing controls
|
||||
// rendershader performs image processing
|
||||
ImageProcessingShader *rendershader_;
|
||||
|
||||
// mixingshader provides mixing controls
|
||||
// blendingshader provides mixing controls
|
||||
ImageShader *blendingshader_;
|
||||
|
||||
// overlay to be displayed on top of source
|
||||
std::map<View::Mode, Frame*> overlays_;
|
||||
std::map<View::Mode, Group*> overlays_;
|
||||
Handles *resize_handle_, *resize_H_handle_, *resize_V_handle_, *rotate_handle_;
|
||||
};
|
||||
|
||||
// TODO : source set sorted by shader
|
||||
// TODO SourceSet sorted by shader
|
||||
// so that the render loop avoid switching
|
||||
typedef std::list<Source *> SourceList;
|
||||
|
||||
@@ -134,5 +137,6 @@ protected:
|
||||
MediaPlayer *mediaplayer_;
|
||||
};
|
||||
|
||||
// TODO dedicated source .cpp .h files for MediaSource
|
||||
|
||||
#endif // SOURCE_H
|
||||
|
||||
@@ -239,17 +239,23 @@ void UserInterface::handleKeyboard()
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
// Normal keys
|
||||
if (ImGui::IsKeyPressed( GLFW_KEY_BACKSPACE ))
|
||||
Mixer::manager().deleteCurrentSource();
|
||||
// Application F-Keys
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_F1 ))
|
||||
Mixer::manager().setCurrentView(View::MIXING);
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_F2 ))
|
||||
Mixer::manager().setCurrentView(View::GEOMETRY);
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_F12 ))
|
||||
Rendering::manager().ToggleFullscreen();
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_PRINT_SCREEN ))
|
||||
toolbox.StartScreenshot();
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_GRAVE_ACCENT ))
|
||||
navigator.toggleMenu();
|
||||
}
|
||||
|
||||
// Application F-Keys
|
||||
if (ImGui::IsKeyPressed( GLFW_KEY_F1 ))
|
||||
Mixer::manager().setCurrentView(View::MIXING);
|
||||
if (ImGui::IsKeyPressed( GLFW_KEY_F2 ))
|
||||
Mixer::manager().setCurrentView(View::GEOMETRY);
|
||||
if (ImGui::IsKeyPressed( GLFW_KEY_F12 ))
|
||||
Rendering::manager().ToggleFullscreen();
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_F11 ))
|
||||
toolbox.StartScreenshot();
|
||||
|
||||
}
|
||||
|
||||
void UserInterface::handleMouse()
|
||||
@@ -261,6 +267,8 @@ void UserInterface::handleMouse()
|
||||
mouseclic[ImGuiMouseButton_Left] = glm::vec2(io.MouseClickedPos[ImGuiMouseButton_Left].x * io.DisplayFramebufferScale.y, io.MouseClickedPos[ImGuiMouseButton_Left].y* io.DisplayFramebufferScale.x);
|
||||
mouseclic[ImGuiMouseButton_Right] = glm::vec2(io.MouseClickedPos[ImGuiMouseButton_Right].x * io.DisplayFramebufferScale.y, io.MouseClickedPos[ImGuiMouseButton_Right].y* io.DisplayFramebufferScale.x);
|
||||
|
||||
static std::pair<Node *, glm::vec2> pick = { nullptr, glm::vec2(0.f) };
|
||||
|
||||
// if not on any window
|
||||
if ( !ImGui::IsAnyWindowHovered() && !ImGui::IsAnyWindowFocused() )
|
||||
{
|
||||
@@ -305,7 +313,7 @@ void UserInterface::handleMouse()
|
||||
if (current)
|
||||
{
|
||||
// drag current source
|
||||
Mixer::manager().currentView()->grab( mouseclic[ImGuiMouseButton_Left], mousepos, current);
|
||||
Mixer::manager().currentView()->grab( mouseclic[ImGuiMouseButton_Left], mousepos, current, pick);
|
||||
}
|
||||
else {
|
||||
// Log::Info("Mouse drag (%.1f,%.1f)(%.1f,%.1f)", io.MouseClickedPos[0].x, io.MouseClickedPos[0].y, io.MousePos.x, io.MousePos.y);
|
||||
@@ -328,13 +336,15 @@ void UserInterface::handleMouse()
|
||||
// picking visitor found nodes?
|
||||
if (pv.picked().empty())
|
||||
Mixer::manager().unsetCurrentSource();
|
||||
else
|
||||
Mixer::manager().setCurrentSource(pv.picked().back().first);
|
||||
else {
|
||||
pick = pv.picked().back();
|
||||
Mixer::manager().setCurrentSource( pick.first );
|
||||
}
|
||||
|
||||
}
|
||||
else if ( ImGui::IsMouseReleased(ImGuiMouseButton_Left) )
|
||||
{
|
||||
|
||||
pick = { nullptr, glm::vec2(0.f) };
|
||||
|
||||
}
|
||||
if ( ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) )
|
||||
@@ -858,6 +868,13 @@ void Navigator::showPannelSource(int index)
|
||||
selected_source_index = index;
|
||||
}
|
||||
|
||||
void Navigator::toggleMenu()
|
||||
{
|
||||
bool previous = selected_button[NAV_MENU];
|
||||
hidePannel();
|
||||
selected_button[NAV_MENU] = !previous;
|
||||
}
|
||||
|
||||
void Navigator::hidePannel()
|
||||
{
|
||||
clearSelection();
|
||||
|
||||
@@ -38,6 +38,7 @@ class Navigator
|
||||
public:
|
||||
Navigator();
|
||||
|
||||
void toggleMenu();
|
||||
void hidePannel();
|
||||
void showPannelSource(int index);
|
||||
void Render();
|
||||
|
||||
153
View.cpp
153
View.cpp
@@ -106,7 +106,7 @@ void MixingView::drag (glm::vec2 from, glm::vec2 to)
|
||||
}
|
||||
|
||||
|
||||
void MixingView::grab (glm::vec2 from, glm::vec2 to, Source *s)
|
||||
void MixingView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2>)
|
||||
{
|
||||
if (!s)
|
||||
return;
|
||||
@@ -201,6 +201,7 @@ void RenderView::setResolution(glm::vec3 resolution)
|
||||
delete frame_buffer_;
|
||||
|
||||
frame_buffer_ = new FrameBuffer(resolution);
|
||||
frame_buffer_->setClearColor(glm::vec4(0.f, 0.f, 0.f, 1.f));
|
||||
}
|
||||
|
||||
void RenderView::draw()
|
||||
@@ -230,7 +231,6 @@ GeometryView::GeometryView() : View(GEOMETRY)
|
||||
scene.bg()->attach(rect);
|
||||
|
||||
Frame *border = new Frame(Frame::SHARP_THIN);
|
||||
border->overlay_ = new Mesh("mesh/border_vertical_overlay.ply");
|
||||
border->color = glm::vec4( 0.8f, 0.f, 0.8f, 1.f );
|
||||
scene.bg()->attach(border);
|
||||
|
||||
@@ -282,77 +282,118 @@ void GeometryView::drag (glm::vec2 from, glm::vec2 to)
|
||||
}
|
||||
|
||||
|
||||
void GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s)
|
||||
void GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2> pick)
|
||||
{
|
||||
// work on the given source
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
Group *sourceNode = s->group(View::GEOMETRY);
|
||||
|
||||
static glm::vec3 start_translation = glm::vec3(0.f);
|
||||
static glm::vec3 start_scale = glm::vec3(0.f);
|
||||
// remember
|
||||
static glm::vec2 start_position = glm::vec2(0.f);
|
||||
|
||||
|
||||
static glm::vec3 start_translation = glm::vec3(0.f);
|
||||
static glm::vec3 start_scale = glm::vec3(1.f);
|
||||
if ( start_position != from ) {
|
||||
start_position = from;
|
||||
start_translation = sourceNode->translation_;
|
||||
start_scale = sourceNode->scale_;
|
||||
}
|
||||
|
||||
// unproject in scene coordinates
|
||||
// grab coordinates in scene View reference frame
|
||||
glm::vec3 gl_Position_from = Rendering::manager().unProject(from, scene.root()->transform_);
|
||||
glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_);
|
||||
|
||||
// coordinate in source
|
||||
glm::mat4 modelview;
|
||||
glm::vec2 clicpos(0.f);
|
||||
PickingVisitor pv(gl_Position_to);
|
||||
sourceNode->accept(pv);
|
||||
if (!pv.picked().empty()){
|
||||
clicpos = pv.picked().back().second;
|
||||
modelview = pv.picked().back().first->transform_;
|
||||
// Log::Info("clic pos source %.2f. %.2f", clicpos.x, clicpos.y);
|
||||
// grab coordinates in source root reference frame
|
||||
glm::vec4 S_from = glm::inverse(sourceNode->transform_) * glm::vec4( gl_Position_from, 1.f );
|
||||
glm::vec4 S_to = glm::inverse(sourceNode->transform_) * glm::vec4( gl_Position_to, 1.f );
|
||||
glm::vec3 S_resize = glm::vec3(S_to) / glm::vec3(S_from);
|
||||
|
||||
// Log::Info(" screen coordinates ( %.1f, %.1f ) ", to.x, to.y);
|
||||
// Log::Info(" scene coordinates ( %.1f, %.1f ) ", gl_Position_to.x, gl_Position_to.y);
|
||||
// Log::Info(" source coordinates ( %.1f, %.1f ) ", P_to.x, P_to.y);
|
||||
|
||||
// which manipulation to perform?
|
||||
if (pick.first) {
|
||||
// picking on the resizing handles in the corners
|
||||
if ( pick.first == s->handleNode(Handles::RESIZE) ) {
|
||||
sourceNode->scale_ = start_scale * S_resize;
|
||||
}
|
||||
// picking on the resizing handles left or right
|
||||
else if ( pick.first == s->handleNode(Handles::RESIZE_H) ) {
|
||||
sourceNode->scale_ = start_scale * glm::vec3(S_resize.x, 1.f, 1.f);
|
||||
}
|
||||
// picking on the resizing handles top or bottom
|
||||
else if ( pick.first == s->handleNode(Handles::RESIZE_V) ) {
|
||||
sourceNode->scale_ = start_scale * glm::vec3(1.f, S_resize.y, 1.f);
|
||||
}
|
||||
// TODO picking on the rotating handle
|
||||
else if ( pick.first == s->handleNode(Handles::ROTATE) ) {
|
||||
|
||||
}
|
||||
// picking anywhere but on a handle: user wants to move the source
|
||||
else {
|
||||
sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from;
|
||||
}
|
||||
}
|
||||
|
||||
// glm::vec4 P = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_to, 1.f );
|
||||
|
||||
|
||||
if ( ABS(clicpos.x)>0.9f && ABS(clicpos.y)>0.9f )
|
||||
{
|
||||
// clic inside corner
|
||||
Log::Info("corner %.2f. %.2f", clicpos.x, clicpos.y);
|
||||
// Log::Info(" %.2f. %.2f", P.x, P.y);
|
||||
|
||||
// glm::vec2 topos = clicpos;
|
||||
// PickingVisitor pv(gl_Position_from);
|
||||
// sourceNode->accept(pv);
|
||||
|
||||
// if (!pv.picked().empty()){
|
||||
// topos = pv.picked().back().second;
|
||||
//// Log::Info("scale %.2f. %.2f", topos.x, topos.y);
|
||||
// }
|
||||
|
||||
glm::vec4 P = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_from, 1.f );
|
||||
|
||||
|
||||
sourceNode->scale_ = start_scale * (glm::vec3(clicpos, 1.f) / glm::vec3(P) );
|
||||
Log::Info("scale %.2f. %.2f", sourceNode->scale_.x, sourceNode->scale_.y);
|
||||
Log::Info(" %.2f. %.2f", start_scale.x, start_scale.y);
|
||||
}
|
||||
else if ( ABS(clicpos.x)>0.95f && ABS(clicpos.y)<0.05f )
|
||||
{
|
||||
// clic resize horizontal
|
||||
Log::Info("H resize %.2f. %.2f", clicpos.x, clicpos.y);
|
||||
}
|
||||
else if ( ABS(clicpos.x)<0.05f && ABS(clicpos.y)>0.95f )
|
||||
{
|
||||
// clic resize vertical
|
||||
Log::Info("V resize %.2f. %.2f", clicpos.x, clicpos.y);
|
||||
}
|
||||
else
|
||||
// clic inside source: compute delta translation
|
||||
// don't have a handle, we can only move the source
|
||||
else {
|
||||
sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from;
|
||||
}
|
||||
|
||||
// // coordinate in source
|
||||
// glm::mat4 modelview(1.f);
|
||||
// glm::vec2 clicpos(0.f);
|
||||
//// PickingVisitor pv(gl_Position_to);
|
||||
//// sourceNode->accept(pv);
|
||||
//// if (!pv.picked().empty()){
|
||||
//// clicpos = pv.picked().back().second;
|
||||
////// modelview = pv.picked().back().first->transform_;
|
||||
////// Log::Info("clic pos source %.2f. %.2f", clicpos.x, clicpos.y);
|
||||
//// }
|
||||
|
||||
|
||||
// glm::vec4 P_from = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_from, 1.f );
|
||||
// glm::vec4 P_to = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_to, 1.f );
|
||||
|
||||
|
||||
//// glm::vec4 P = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_to, 1.f );
|
||||
|
||||
|
||||
// if ( pick.first == s->handleNode(Handles::RESIZE) )
|
||||
// {
|
||||
// // clic inside corner
|
||||
//// Log::Info("corner %.2f. %.2f", clicpos.x, clicpos.y);
|
||||
////// Log::Info(" %.2f. %.2f", P.x, P.y);
|
||||
|
||||
////// glm::vec2 topos = clicpos;
|
||||
////// PickingVisitor pv(gl_Position_from);
|
||||
////// sourceNode->accept(pv);
|
||||
|
||||
////// if (!pv.picked().empty()){
|
||||
////// topos = pv.picked().back().second;
|
||||
//////// Log::Info("scale %.2f. %.2f", topos.x, topos.y);
|
||||
////// }
|
||||
|
||||
////// glm::vec4 P = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_from, 1.f );
|
||||
|
||||
|
||||
// sourceNode->scale_ = start_scale * (glm::vec3(P_to) / glm::vec3(P_from) );
|
||||
//// Log::Info("scale %.2f. %.2f", sourceNode->scale_.x, sourceNode->scale_.y);
|
||||
//// Log::Info(" %.2f. %.2f", start_scale.x, start_scale.y);
|
||||
// }
|
||||
// else if ( ABS(clicpos.x)>0.95f && ABS(clicpos.y)<0.05f )
|
||||
// {
|
||||
// // clic resize horizontal
|
||||
// Log::Info("H resize %.2f. %.2f", clicpos.x, clicpos.y);
|
||||
// }
|
||||
// else if ( ABS(clicpos.x)<0.05f && ABS(clicpos.y)>0.95f )
|
||||
// {
|
||||
// // clic resize vertical
|
||||
// Log::Info("V resize %.2f. %.2f", clicpos.x, clicpos.y);
|
||||
// }
|
||||
// else
|
||||
// clic inside source: compute delta translation
|
||||
// sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from;
|
||||
|
||||
}
|
||||
|
||||
|
||||
6
View.h
6
View.h
@@ -20,7 +20,7 @@ public:
|
||||
virtual void draw () = 0;
|
||||
virtual void zoom (float) {}
|
||||
virtual void drag (glm::vec2, glm::vec2) {}
|
||||
virtual void grab (glm::vec2, glm::vec2, Source*) {}
|
||||
virtual void grab (glm::vec2, glm::vec2, Source*, std::pair<Node *, glm::vec2>) {}
|
||||
|
||||
virtual void restoreSettings();
|
||||
virtual void saveSettings();
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
void draw () override;
|
||||
void zoom (float factor) override;
|
||||
void drag (glm::vec2 from, glm::vec2 to) override;
|
||||
void grab (glm::vec2 from, glm::vec2 to, Source *s) override;
|
||||
void grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2>) override;
|
||||
|
||||
private:
|
||||
uint textureMixingQuadratic();
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
void draw () override;
|
||||
void zoom (float factor) override;
|
||||
void drag (glm::vec2 from, glm::vec2 to) override;
|
||||
void grab (glm::vec2 from, glm::vec2 to, Source *s) override;
|
||||
void grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2> pick) override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
30
Visitor.h
30
Visitor.h
@@ -19,6 +19,7 @@ class LineSquare;
|
||||
class LineCircle;
|
||||
class Mesh;
|
||||
class Frame;
|
||||
class Handles;
|
||||
class MediaPlayer;
|
||||
class Shader;
|
||||
class ImageShader;
|
||||
@@ -30,24 +31,25 @@ class MediaSource;
|
||||
class Visitor {
|
||||
|
||||
public:
|
||||
// Declare overloads for each kind of Node to visit
|
||||
// Need to declare overloads for basic kind of Nodes to visit
|
||||
virtual void visit (Scene&) = 0;
|
||||
virtual void visit (Node&) = 0;
|
||||
virtual void visit (Group&) = 0;
|
||||
virtual void visit (Switch&) = 0;
|
||||
virtual void visit (Animation&) = 0;
|
||||
virtual void visit (Primitive&) = 0;
|
||||
virtual void visit (Surface&) = 0;
|
||||
virtual void visit (ImageSurface&) = 0;
|
||||
virtual void visit (MediaSurface&) = 0;
|
||||
virtual void visit (FrameBufferSurface&) = 0;
|
||||
virtual void visit (LineStrip&) = 0;
|
||||
virtual void visit (LineSquare&) = 0;
|
||||
virtual void visit (LineCircle&) = 0;
|
||||
virtual void visit (Mesh&) = 0;
|
||||
virtual void visit (Frame&) = 0;
|
||||
virtual void visit (Group&) = 0;
|
||||
|
||||
// not mandatory
|
||||
// not mandatory for all others
|
||||
virtual void visit (Switch&) {}
|
||||
virtual void visit (Animation&) {}
|
||||
virtual void visit (Surface&) {}
|
||||
virtual void visit (ImageSurface&) {}
|
||||
virtual void visit (MediaSurface&) {}
|
||||
virtual void visit (FrameBufferSurface&) {}
|
||||
virtual void visit (LineStrip&) {}
|
||||
virtual void visit (LineSquare&) {}
|
||||
virtual void visit (LineCircle&) {}
|
||||
virtual void visit (Mesh&) {}
|
||||
virtual void visit (Frame&) {}
|
||||
virtual void visit (Handles&) {}
|
||||
virtual void visit (MediaPlayer&) {}
|
||||
virtual void visit (Shader&) {}
|
||||
virtual void visit (ImageShader&) {}
|
||||
|
||||
@@ -1,33 +1,21 @@
|
||||
ply
|
||||
format ascii 1.0
|
||||
comment Created by Blender 2.82 (sub 7) - www.blender.org, source file: 'border_large_sharp_2.blend'
|
||||
element vertex 16
|
||||
element vertex 8
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
property uchar red
|
||||
property uchar green
|
||||
property uchar blue
|
||||
property uchar alpha
|
||||
element face 16
|
||||
element face 8
|
||||
property list uchar uint vertex_indices
|
||||
end_header
|
||||
0.040053 -1.008800 0.000000 255 255 255 255
|
||||
-0.031947 -1.000800 0.000000 255 255 255 255
|
||||
-0.039947 -1.008800 0.000000 255 255 255 255
|
||||
-0.031947 -0.957118 0.000000 255 255 255 255
|
||||
-0.039947 -0.949118 0.000000 255 255 255 255
|
||||
0.040053 -0.949118 0.000000 255 255 255 255
|
||||
0.032053 -0.957118 0.000000 255 255 255 255
|
||||
0.032053 -1.000800 0.000000 255 255 255 255
|
||||
0.040053 0.949146 0.000000 255 255 255 255
|
||||
-0.031947 0.957146 0.000000 255 255 255 255
|
||||
-0.039947 0.949146 0.000000 255 255 255 255
|
||||
-0.031947 1.000827 0.000000 255 255 255 255
|
||||
-0.039947 1.008827 0.000000 255 255 255 255
|
||||
0.040053 1.008827 0.000000 255 255 255 255
|
||||
0.032053 1.000827 0.000000 255 255 255 255
|
||||
0.032053 0.957146 0.000000 255 255 255 255
|
||||
0.091161 0.091238 0.000000
|
||||
0.073023 -0.072006 0.000000
|
||||
0.091161 -0.090145 0.000000
|
||||
-0.072083 -0.072006 0.000000
|
||||
-0.090222 -0.090145 0.000000
|
||||
-0.090222 0.091238 0.000000
|
||||
-0.072083 0.073100 0.000000
|
||||
0.073023 0.073100 0.000000
|
||||
3 0 1 2
|
||||
3 2 3 4
|
||||
3 3 5 4
|
||||
@@ -36,11 +24,3 @@ end_header
|
||||
3 2 1 3
|
||||
3 3 6 5
|
||||
3 0 5 6
|
||||
3 8 9 10
|
||||
3 10 11 12
|
||||
3 11 13 12
|
||||
3 8 14 15
|
||||
3 8 15 9
|
||||
3 10 9 11
|
||||
3 11 14 13
|
||||
3 8 13 14
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
ply
|
||||
format ascii 1.0
|
||||
comment Created by Blender 2.82 (sub 7) - www.blender.org, source file: 'border_large_sharp.blend'
|
||||
element vertex 52
|
||||
element vertex 45
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
@@ -9,7 +9,7 @@ property uchar red
|
||||
property uchar green
|
||||
property uchar blue
|
||||
property uchar alpha
|
||||
element face 62
|
||||
element face 57
|
||||
property list uchar uint vertex_indices
|
||||
end_header
|
||||
-0.950647 -1.000000 0.000000 255 255 255 255
|
||||
@@ -57,13 +57,6 @@ end_header
|
||||
1.000000 0.000000 0.000000 255 255 255 255
|
||||
-0.000064 1.000000 0.000000 255 255 255 255
|
||||
-0.995340 1.015000 0.000000 255 255 255 255
|
||||
1.012389 -0.007651 0.000000 255 255 255 255
|
||||
1.050200 -0.000169 0.000000 255 255 255 255
|
||||
1.011916 -0.000169 0.000000 255 255 255 255
|
||||
1.050200 0.007965 0.000000 255 255 255 255
|
||||
1.011319 -0.007674 0.000000 255 255 255 255
|
||||
1.050200 -0.007651 0.000000 255 255 255 255
|
||||
1.011401 0.007965 0.000000 255 255 255 255
|
||||
3 0 1 2
|
||||
3 3 4 1
|
||||
3 4 5 1
|
||||
@@ -121,8 +114,3 @@ end_header
|
||||
3 29 31 40
|
||||
3 40 44 38
|
||||
3 19 14 22
|
||||
3 45 46 47
|
||||
3 48 47 46
|
||||
3 49 45 47
|
||||
3 45 50 46
|
||||
3 48 51 47
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user