mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
Introducing Oriented bounding box for GeometryView selection
First implementation of MixingView selection manipulation (scale and rotate)
This commit is contained in:
@@ -1,11 +1,16 @@
|
|||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/constants.hpp>
|
||||||
|
|
||||||
#include "BoundingBoxVisitor.h"
|
#include <map>
|
||||||
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "View.h"
|
||||||
#include "Primitives.h"
|
#include "Primitives.h"
|
||||||
|
#include "Source.h"
|
||||||
#include "Decorations.h"
|
#include "Decorations.h"
|
||||||
|
|
||||||
|
#include "BoundingBoxVisitor.h"
|
||||||
|
|
||||||
BoundingBoxVisitor::BoundingBoxVisitor(bool force): force_(force)
|
BoundingBoxVisitor::BoundingBoxVisitor(bool force): force_(force)
|
||||||
{
|
{
|
||||||
modelview_ = glm::identity<glm::mat4>();
|
modelview_ = glm::identity<glm::mat4>();
|
||||||
@@ -64,3 +69,47 @@ void BoundingBoxVisitor::visit(Scene &n)
|
|||||||
n.ws()->accept(*this);
|
n.ws()->accept(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GlmToolkit::AxisAlignedBoundingBox BoundingBoxVisitor::AABB(SourceList l, View *view)
|
||||||
|
{
|
||||||
|
// calculate bbox on selection
|
||||||
|
BoundingBoxVisitor selection_visitor_bbox;
|
||||||
|
for (auto it = l.begin(); it != l.end(); it++) {
|
||||||
|
// calculate bounding box of area covered by selection
|
||||||
|
selection_visitor_bbox.setModelview( view->scene.ws()->transform_ );
|
||||||
|
(*it)->group( view->mode() )->accept(selection_visitor_bbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
return selection_visitor_bbox.bbox();
|
||||||
|
}
|
||||||
|
|
||||||
|
GlmToolkit::OrientedBoundingBox BoundingBoxVisitor::OBB(SourceList l, View *view)
|
||||||
|
{
|
||||||
|
GlmToolkit::OrientedBoundingBox obb_;
|
||||||
|
|
||||||
|
// try the orientation of each source in the list
|
||||||
|
for (auto source_it = l.begin(); source_it != l.end(); source_it++) {
|
||||||
|
|
||||||
|
float angle = (*source_it)->group( view->mode() )->rotation_.z;
|
||||||
|
glm::mat4 transform = view->scene.ws()->transform_;
|
||||||
|
transform = glm::rotate(transform, -angle, glm::vec3(0.f, 0.f, 1.f) );
|
||||||
|
|
||||||
|
// calculate bbox of the list in this orientation
|
||||||
|
BoundingBoxVisitor selection_visitor_bbox;
|
||||||
|
for (auto it = l.begin(); it != l.end(); it++) {
|
||||||
|
// calculate bounding box of area covered by sources' nodes
|
||||||
|
selection_visitor_bbox.setModelview( transform );
|
||||||
|
(*it)->group( view->mode() )->accept(selection_visitor_bbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not initialized or if new bbox is smaller than previous
|
||||||
|
if ( obb_.aabb.isNull() || selection_visitor_bbox.bbox() < obb_.aabb) {
|
||||||
|
// keep this bbox as candidate
|
||||||
|
obb_.aabb = selection_visitor_bbox.bbox();
|
||||||
|
obb_.orientation = glm::vec3(0.f, 0.f, angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return obb_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
#include "GlmToolkit.h"
|
#include "GlmToolkit.h"
|
||||||
#include "Visitor.h"
|
#include "Visitor.h"
|
||||||
|
#include "SourceList.h"
|
||||||
|
class View;
|
||||||
|
|
||||||
class BoundingBoxVisitor: public Visitor
|
class BoundingBoxVisitor: public Visitor
|
||||||
{
|
{
|
||||||
@@ -11,6 +12,7 @@ class BoundingBoxVisitor: public Visitor
|
|||||||
bool force_;
|
bool force_;
|
||||||
GlmToolkit::AxisAlignedBoundingBox bbox_;
|
GlmToolkit::AxisAlignedBoundingBox bbox_;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BoundingBoxVisitor(bool force = false);
|
BoundingBoxVisitor(bool force = false);
|
||||||
|
|
||||||
@@ -24,6 +26,8 @@ public:
|
|||||||
void visit(Switch& n) override;
|
void visit(Switch& n) override;
|
||||||
void visit(Primitive& n) override;
|
void visit(Primitive& n) override;
|
||||||
|
|
||||||
|
static GlmToolkit::AxisAlignedBoundingBox AABB(SourceList l, View *view);
|
||||||
|
static GlmToolkit::OrientedBoundingBox OBB(SourceList l, View *view);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BOUNDINGBOXVISITOR_H
|
#endif // BOUNDINGBOXVISITOR_H
|
||||||
|
|||||||
142
GeometryView.cpp
142
GeometryView.cpp
@@ -20,6 +20,7 @@
|
|||||||
#include "DrawVisitor.h"
|
#include "DrawVisitor.h"
|
||||||
#include "Decorations.h"
|
#include "Decorations.h"
|
||||||
#include "UserInterfaceManager.h"
|
#include "UserInterfaceManager.h"
|
||||||
|
#include "BoundingBoxVisitor.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
#include "GeometryView.h"
|
#include "GeometryView.h"
|
||||||
@@ -117,6 +118,11 @@ GeometryView::GeometryView() : View(GEOMETRY)
|
|||||||
scene.fg()->attach(overlay_crop_);
|
scene.fg()->attach(overlay_crop_);
|
||||||
overlay_crop_->visible_ = false;
|
overlay_crop_->visible_ = false;
|
||||||
|
|
||||||
|
// will be init later
|
||||||
|
overlay_selection_scale_ = nullptr;
|
||||||
|
overlay_selection_rotate_ = nullptr;
|
||||||
|
overlay_selection_stored_status_ = nullptr;
|
||||||
|
overlay_selection_active_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryView::update(float dt)
|
void GeometryView::update(float dt)
|
||||||
@@ -374,6 +380,19 @@ std::pair<Node *, glm::vec2> GeometryView::pick(glm::vec2 P)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// no source picked
|
||||||
|
else {
|
||||||
|
// picked on selection handles
|
||||||
|
if ( (*itp).first == overlay_selection_scale_ || (*itp).first == overlay_selection_rotate_ ) {
|
||||||
|
pick = (*itp);
|
||||||
|
// initiate selection manipulation
|
||||||
|
if (overlay_selection_stored_status_) {
|
||||||
|
overlay_selection_stored_status_->copyTransform(overlay_selection_);
|
||||||
|
overlay_selection_active_ = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,17 +411,88 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
|||||||
{
|
{
|
||||||
View::Cursor ret = Cursor();
|
View::Cursor ret = Cursor();
|
||||||
|
|
||||||
// work on the given source
|
|
||||||
if (!s)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
Group *sourceNode = s->group(mode_); // groups_[View::GEOMETRY]
|
|
||||||
|
|
||||||
// grab coordinates in scene-View reference frame
|
// grab coordinates in scene-View reference frame
|
||||||
glm::vec3 scene_from = Rendering::manager().unProject(from, scene.root()->transform_);
|
glm::vec3 scene_from = Rendering::manager().unProject(from, scene.root()->transform_);
|
||||||
glm::vec3 scene_to = Rendering::manager().unProject(to, scene.root()->transform_);
|
glm::vec3 scene_to = Rendering::manager().unProject(to, scene.root()->transform_);
|
||||||
glm::vec3 scene_translation = scene_to - scene_from;
|
glm::vec3 scene_translation = scene_to - scene_from;
|
||||||
|
|
||||||
|
// No source is given
|
||||||
|
if (!s) {
|
||||||
|
|
||||||
|
// possibly grabing the selection overlay handles
|
||||||
|
if (overlay_selection_ && overlay_selection_active_ ) {
|
||||||
|
|
||||||
|
// rotation center to selection position
|
||||||
|
glm::mat4 T = glm::translate(glm::identity<glm::mat4>(), overlay_selection_stored_status_->translation_);
|
||||||
|
glm::vec4 selection_from = glm::inverse(T) * glm::vec4( scene_from, 1.f );
|
||||||
|
glm::vec4 selection_to = glm::inverse(T) * glm::vec4( scene_to, 1.f );
|
||||||
|
|
||||||
|
// calculate scaling of selection
|
||||||
|
float factor = glm::length( glm::vec2( selection_to ) ) / glm::length( glm::vec2( selection_from ) );
|
||||||
|
glm::mat4 S = glm::scale(glm::identity<glm::mat4>(), glm::vec3(factor, factor, 1.f));
|
||||||
|
|
||||||
|
// if interaction with selection
|
||||||
|
if (pick.first == overlay_selection_scale_) {
|
||||||
|
|
||||||
|
// apply to overlay
|
||||||
|
glm::vec4 vec = S * glm::vec4( overlay_selection_stored_status_->scale_, 0.f );
|
||||||
|
overlay_selection_->scale_ = glm::vec3(vec);
|
||||||
|
|
||||||
|
// Transform sources
|
||||||
|
// complete transform matrix (right to left) : move to center, scale and move back
|
||||||
|
glm::mat4 M = T * S * glm::inverse(T);
|
||||||
|
// apply to every sources in selection
|
||||||
|
for (auto sit = Mixer::selection().begin(); sit != Mixer::selection().end(); sit++){
|
||||||
|
// displacement
|
||||||
|
vec = M * glm::vec4( (*sit)->stored_status_->translation_, 1.f );
|
||||||
|
(*sit)->group(mode_)->translation_ = glm::vec3(vec);
|
||||||
|
// scale
|
||||||
|
vec = M * glm::vec4( (*sit)->stored_status_->scale_, 0.f );
|
||||||
|
(*sit)->group(mode_)->scale_ = glm::vec3(vec);
|
||||||
|
// will have to be updated
|
||||||
|
(*sit)->touch();
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.type = Cursor_ResizeNWSE;
|
||||||
|
}
|
||||||
|
else if (pick.first == overlay_selection_rotate_) {
|
||||||
|
|
||||||
|
// compute rotation angle
|
||||||
|
float angle = glm::orientedAngle( glm::normalize(glm::vec2(selection_from)), glm::normalize(glm::vec2(selection_to)));
|
||||||
|
glm::mat4 R = glm::rotate(glm::identity<glm::mat4>(), angle, glm::vec3(0.f, 0.f, 1.f) );
|
||||||
|
|
||||||
|
// apply to overlay
|
||||||
|
glm::vec4 vec = S * glm::vec4( overlay_selection_stored_status_->scale_, 0.f );
|
||||||
|
overlay_selection_->scale_ = glm::vec3(vec);
|
||||||
|
overlay_selection_->rotation_.z = overlay_selection_stored_status_->rotation_.z + angle;
|
||||||
|
|
||||||
|
// Transform sources
|
||||||
|
// complete transform matrix (right to left) : move to center, rotate, scale and move back
|
||||||
|
glm::mat4 M = T * S * R * glm::inverse(T);
|
||||||
|
// apply to every sources in selection:
|
||||||
|
for (auto sit = Mixer::selection().begin(); sit != Mixer::selection().end(); sit++){
|
||||||
|
|
||||||
|
glm::mat4 transform = M * (*sit)->stored_status_->transform_;
|
||||||
|
glm::vec3 tra, rot, sca;
|
||||||
|
GlmToolkit::inverse_transform(transform, tra, rot, sca);
|
||||||
|
(*sit)->group(mode_)->translation_ = tra;
|
||||||
|
(*sit)->group(mode_)->scale_ = sca;
|
||||||
|
(*sit)->group(mode_)->rotation_ = rot;
|
||||||
|
|
||||||
|
// will have to be updated
|
||||||
|
(*sit)->touch();
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.type = Cursor_Hand;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update cursor
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Group *sourceNode = s->group(mode_); // groups_[View::GEOMETRY]
|
||||||
|
|
||||||
// make sure matrix transform of stored status is updated
|
// make sure matrix transform of stored status is updated
|
||||||
s->stored_status_->update(0);
|
s->stored_status_->update(0);
|
||||||
// grab coordinates in source-root reference frame
|
// grab coordinates in source-root reference frame
|
||||||
@@ -619,7 +709,6 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
|||||||
s->handles_[mode_][Handles::ROTATE]->visible_ = false;
|
s->handles_[mode_][Handles::ROTATE]->visible_ = false;
|
||||||
s->handles_[mode_][Handles::SCALE]->visible_ = false;
|
s->handles_[mode_][Handles::SCALE]->visible_ = false;
|
||||||
s->handles_[mode_][Handles::MENU]->visible_ = false;
|
s->handles_[mode_][Handles::MENU]->visible_ = false;
|
||||||
|
|
||||||
// prepare overlay
|
// prepare overlay
|
||||||
overlay_crop_->scale_ = s->stored_status_->scale_ / s->stored_status_->crop_;
|
overlay_crop_->scale_ = s->stored_status_->scale_ / s->stored_status_->crop_;
|
||||||
overlay_crop_->scale_.x *= s->frame()->aspectRatio();
|
overlay_crop_->scale_.x *= s->frame()->aspectRatio();
|
||||||
@@ -628,7 +717,6 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
|||||||
overlay_crop_->rotation_.z = s->stored_status_->rotation_.z;
|
overlay_crop_->rotation_.z = s->stored_status_->rotation_.z;
|
||||||
overlay_crop_->update(0);
|
overlay_crop_->update(0);
|
||||||
overlay_crop_->visible_ = true;
|
overlay_crop_->visible_ = true;
|
||||||
|
|
||||||
// PROPORTIONAL ONLY
|
// PROPORTIONAL ONLY
|
||||||
if (UserInterface::manager().shiftModifier()) {
|
if (UserInterface::manager().shiftModifier()) {
|
||||||
float factor = glm::length( glm::vec2( source_to ) ) / glm::length( glm::vec2( source_from ) );
|
float factor = glm::length( glm::vec2( source_to ) ) / glm::length( glm::vec2( source_from ) );
|
||||||
@@ -763,8 +851,6 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GeometryView::terminate()
|
void GeometryView::terminate()
|
||||||
{
|
{
|
||||||
View::terminate();
|
View::terminate();
|
||||||
@@ -798,6 +884,7 @@ void GeometryView::terminate()
|
|||||||
(*sit)->handles_[mode_][Handles::MENU]->visible_ = true;
|
(*sit)->handles_[mode_][Handles::MENU]->visible_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overlay_selection_active_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryView::arrow (glm::vec2 movement)
|
void GeometryView::arrow (glm::vec2 movement)
|
||||||
@@ -822,3 +909,38 @@ void GeometryView::arrow (glm::vec2 movement)
|
|||||||
s->touch();
|
s->touch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GeometryView::updateSelectionOverlay()
|
||||||
|
{
|
||||||
|
View::updateSelectionOverlay();
|
||||||
|
|
||||||
|
// create first
|
||||||
|
if (overlay_selection_scale_ == nullptr) {
|
||||||
|
|
||||||
|
overlay_selection_stored_status_ = new Group;
|
||||||
|
overlay_selection_scale_ = new Handles(Handles::SCALE);
|
||||||
|
overlay_selection_->attach(overlay_selection_scale_);
|
||||||
|
overlay_selection_rotate_ = new Handles(Handles::ROTATE);
|
||||||
|
overlay_selection_->attach(overlay_selection_rotate_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overlay_selection_->visible_) {
|
||||||
|
|
||||||
|
if ( !overlay_selection_active_) {
|
||||||
|
|
||||||
|
// calculate ORIENTED bbox on selection
|
||||||
|
GlmToolkit::OrientedBoundingBox selection_box = BoundingBoxVisitor::OBB(Mixer::selection().getCopy(), this);
|
||||||
|
|
||||||
|
// apply transform
|
||||||
|
overlay_selection_->rotation_ = selection_box.orientation;
|
||||||
|
overlay_selection_->scale_ = selection_box.aabb.scale();
|
||||||
|
glm::mat4 rot = glm::rotate(glm::identity<glm::mat4>(), selection_box.orientation.z, glm::vec3(0.f, 0.f, 1.f) );
|
||||||
|
glm::vec4 vec = rot * glm::vec4(selection_box.aabb.center(), 1.f);
|
||||||
|
overlay_selection_->translation_ = glm::vec3(vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cosmetics
|
||||||
|
overlay_selection_scale_->color = overlay_selection_icon_->color;
|
||||||
|
overlay_selection_rotate_->color = overlay_selection_icon_->color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ private:
|
|||||||
Node *overlay_scaling_cross_;
|
Node *overlay_scaling_cross_;
|
||||||
Node *overlay_scaling_grid_;
|
Node *overlay_scaling_grid_;
|
||||||
Node *overlay_crop_;
|
Node *overlay_crop_;
|
||||||
|
|
||||||
|
void updateSelectionOverlay() override;
|
||||||
|
bool overlay_selection_active_;
|
||||||
|
Group *overlay_selection_stored_status_;
|
||||||
|
Handles *overlay_selection_scale_;
|
||||||
|
Handles *overlay_selection_rotate_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,17 @@ void GlmToolkit::inverse_transform(glm::mat4 M, glm::vec3 &translation, glm::vec
|
|||||||
translation = glm::vec3(vec);
|
translation = glm::vec3(vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//float rewrapAngleRestricted(float angle)
|
||||||
|
//// This function takes an angle in the range [-3*pi, 3*pi] and
|
||||||
|
//// wraps it to the range [-pi, pi].
|
||||||
|
//{
|
||||||
|
// if (angle > glm::pi<float>() )
|
||||||
|
// return angle - glm::two_pi<float>();
|
||||||
|
// else if (angle < - glm::pi<float>())
|
||||||
|
// return angle + glm::two_pi<float>();
|
||||||
|
// else
|
||||||
|
// return angle;
|
||||||
|
//}
|
||||||
|
|
||||||
GlmToolkit::AxisAlignedBoundingBox::AxisAlignedBoundingBox() {
|
GlmToolkit::AxisAlignedBoundingBox::AxisAlignedBoundingBox() {
|
||||||
mMin = glm::vec3(1.f);
|
mMin = glm::vec3(1.f);
|
||||||
@@ -195,10 +206,10 @@ GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::transform
|
|||||||
glm::vec4 vec;
|
glm::vec4 vec;
|
||||||
|
|
||||||
// Apply transform to all four corners (can be rotated) and update bbox accordingly
|
// 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.x, mMin.y, 0.f, 1.f);
|
||||||
bb.extend(glm::vec3(vec));
|
bb.extend(glm::vec3(vec));
|
||||||
|
|
||||||
vec = m * glm::vec4(mMax, 1.f);
|
vec = m * glm::vec4(mMax.x, mMax.y, 0.f, 1.f);
|
||||||
bb.extend(glm::vec3(vec));
|
bb.extend(glm::vec3(vec));
|
||||||
|
|
||||||
vec = m * glm::vec4(mMin.x, mMax.y, 0.f, 1.f);
|
vec = m * glm::vec4(mMin.x, mMax.y, 0.f, 1.f);
|
||||||
@@ -210,6 +221,14 @@ GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::transform
|
|||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GlmToolkit::operator< (const GlmToolkit::AxisAlignedBoundingBox& A, const GlmToolkit::AxisAlignedBoundingBox& B )
|
||||||
|
{
|
||||||
|
if (A.isNull())
|
||||||
|
return true;
|
||||||
|
if (B.isNull())
|
||||||
|
return false;
|
||||||
|
return ( glm::length2(A.mMax-A.mMin) < glm::length2(B.mMax-B.mMin) );
|
||||||
|
}
|
||||||
|
|
||||||
glm::ivec2 GlmToolkit::resolutionFromDescription(int aspectratio, int height)
|
glm::ivec2 GlmToolkit::resolutionFromDescription(int aspectratio, int height)
|
||||||
{
|
{
|
||||||
|
|||||||
25
GlmToolkit.h
25
GlmToolkit.h
@@ -17,13 +17,10 @@ void inverse_transform(glm::mat4 M, glm::vec3 &translation, glm::vec3 &rotation,
|
|||||||
|
|
||||||
class AxisAlignedBoundingBox
|
class AxisAlignedBoundingBox
|
||||||
{
|
{
|
||||||
glm::vec3 mMin;
|
|
||||||
glm::vec3 mMax;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AxisAlignedBoundingBox();
|
AxisAlignedBoundingBox();
|
||||||
|
|
||||||
void operator = (const AxisAlignedBoundingBox &D ) {
|
inline void operator = (const AxisAlignedBoundingBox &D ) {
|
||||||
mMin = D.mMin;
|
mMin = D.mMin;
|
||||||
mMax = D.mMax;
|
mMax = D.mMax;
|
||||||
}
|
}
|
||||||
@@ -46,8 +43,28 @@ public:
|
|||||||
AxisAlignedBoundingBox translated(glm::vec3 t) const;
|
AxisAlignedBoundingBox translated(glm::vec3 t) const;
|
||||||
AxisAlignedBoundingBox scaled(glm::vec3 s) const;
|
AxisAlignedBoundingBox scaled(glm::vec3 s) const;
|
||||||
AxisAlignedBoundingBox transformed(glm::mat4 m) const;
|
AxisAlignedBoundingBox transformed(glm::mat4 m) const;
|
||||||
|
|
||||||
|
friend bool operator<(const AxisAlignedBoundingBox& A, const AxisAlignedBoundingBox& B );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
glm::vec3 mMin;
|
||||||
|
glm::vec3 mMax;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// a bbox A is < from bbox B if its diagonal is shorter
|
||||||
|
bool operator< (const AxisAlignedBoundingBox& A, const AxisAlignedBoundingBox& B );
|
||||||
|
|
||||||
|
|
||||||
|
class OrientedBoundingBox
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OrientedBoundingBox() : orientation(glm::vec3(0.f,0.f,0.f)) {}
|
||||||
|
|
||||||
|
AxisAlignedBoundingBox aabb;
|
||||||
|
glm::vec3 orientation;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const char* aspect_ratio_names[6] = { "1:1", "4:3", "3:2", "16:10", "16:9", "21:9" };
|
static const char* aspect_ratio_names[6] = { "1:1", "4:3", "3:2", "16:10", "16:9", "21:9" };
|
||||||
static const char* height_names[10] = { "16", "64", "200", "320", "480", "576", "720p", "1080p", "1440", "4K" };
|
static const char* height_names[10] = { "16", "64", "200", "320", "480", "576", "720p", "1080p", "1440", "4K" };
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "Decorations.h"
|
#include "Decorations.h"
|
||||||
#include "UserInterfaceManager.h"
|
#include "UserInterfaceManager.h"
|
||||||
|
#include "BoundingBoxVisitor.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
#include "LayerView.h"
|
#include "LayerView.h"
|
||||||
@@ -329,6 +330,11 @@ void LayerView::updateSelectionOverlay()
|
|||||||
View::updateSelectionOverlay();
|
View::updateSelectionOverlay();
|
||||||
|
|
||||||
if (overlay_selection_->visible_) {
|
if (overlay_selection_->visible_) {
|
||||||
|
// calculate bbox on selection
|
||||||
|
GlmToolkit::AxisAlignedBoundingBox selection_box = BoundingBoxVisitor::AABB(Mixer::selection().getCopy(), this);
|
||||||
|
overlay_selection_->scale_ = selection_box.scale();
|
||||||
|
overlay_selection_->translation_ = selection_box.center();
|
||||||
|
|
||||||
// slightly extend the boundary of the selection
|
// slightly extend the boundary of the selection
|
||||||
overlay_selection_frame_->scale_ = glm::vec3(1.f) + glm::vec3(0.07f, 0.07f, 1.f) / overlay_selection_->scale_;
|
overlay_selection_frame_->scale_ = glm::vec3(1.f) + glm::vec3(0.07f, 0.07f, 1.f) / overlay_selection_->scale_;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,14 +12,15 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
#include "Log.h"
|
|
||||||
#include "Mixer.h"
|
#include "Mixer.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "Decorations.h"
|
#include "Decorations.h"
|
||||||
#include "UserInterfaceManager.h"
|
#include "UserInterfaceManager.h"
|
||||||
|
#include "BoundingBoxVisitor.h"
|
||||||
#include "ActionManager.h"
|
#include "ActionManager.h"
|
||||||
#include "MixingGroup.h"
|
#include "MixingGroup.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
#include "MixingView.h"
|
#include "MixingView.h"
|
||||||
|
|
||||||
@@ -331,6 +332,9 @@ std::pair<Node *, glm::vec2> MixingView::pick(glm::vec2 P)
|
|||||||
|
|
||||||
View::Cursor MixingView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick)
|
View::Cursor MixingView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick)
|
||||||
{
|
{
|
||||||
|
View::Cursor ret = Cursor();
|
||||||
|
ret.type = Cursor_ResizeAll;
|
||||||
|
|
||||||
// unproject
|
// unproject
|
||||||
glm::vec3 gl_Position_from = Rendering::manager().unProject(from, scene.root()->transform_);
|
glm::vec3 gl_Position_from = Rendering::manager().unProject(from, scene.root()->transform_);
|
||||||
glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_);
|
glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_);
|
||||||
@@ -371,8 +375,11 @@ View::Cursor MixingView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pai
|
|||||||
// manage mixing group
|
// manage mixing group
|
||||||
if (s->mixinggroup_ != nullptr ) {
|
if (s->mixinggroup_ != nullptr ) {
|
||||||
// inform mixing groups to follow the current source
|
// inform mixing groups to follow the current source
|
||||||
if (Source::isCurrent(s) && s->mixinggroup_->action() > MixingGroup::ACTION_UPDATE)
|
if (Source::isCurrent(s) && s->mixinggroup_->action() > MixingGroup::ACTION_UPDATE) {
|
||||||
s->mixinggroup_->follow(s);
|
s->mixinggroup_->follow(s);
|
||||||
|
if (s->mixinggroup_->action() == MixingGroup::ACTION_ROTATE_ALL)
|
||||||
|
ret.type = Cursor_Hand;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
s->mixingGroup()->setAction(MixingGroup::ACTION_NONE);
|
s->mixingGroup()->setAction(MixingGroup::ACTION_NONE);
|
||||||
}
|
}
|
||||||
@@ -409,7 +416,9 @@ View::Cursor MixingView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pai
|
|||||||
current_action_ = s->name() + ": " + info.str();
|
current_action_ = s->name() + ": " + info.str();
|
||||||
current_id_ = s->id();
|
current_id_ = s->id();
|
||||||
|
|
||||||
return Cursor(Cursor_ResizeAll, info.str() );
|
// update cursor
|
||||||
|
ret.info = info.str();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixingView::terminate()
|
void MixingView::terminate()
|
||||||
@@ -475,9 +484,13 @@ void MixingView::updateSelectionOverlay()
|
|||||||
View::updateSelectionOverlay();
|
View::updateSelectionOverlay();
|
||||||
|
|
||||||
if (overlay_selection_->visible_) {
|
if (overlay_selection_->visible_) {
|
||||||
|
// calculate bbox on selection
|
||||||
|
GlmToolkit::AxisAlignedBoundingBox selection_box = BoundingBoxVisitor::AABB(Mixer::selection().getCopy(), this);
|
||||||
|
overlay_selection_->scale_ = selection_box.scale();
|
||||||
|
overlay_selection_->translation_ = selection_box.center();
|
||||||
|
|
||||||
// slightly extend the boundary of the selection
|
// slightly extend the boundary of the selection
|
||||||
overlay_selection_frame_->scale_ = glm::vec3(1.f) + glm::vec3(0.01f, 0.01f, 1.f) / overlay_selection_->scale_;
|
overlay_selection_frame_->scale_ = glm::vec3(1.f) + glm::vec3(0.01f, 0.01f, 1.f) / overlay_selection_->scale_;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <tinyxml2.h>
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "SessionVisitor.h"
|
#include "SessionVisitor.h"
|
||||||
#include <tinyxml2.h>
|
#include "Source.h"
|
||||||
|
|
||||||
#include "Selection.h"
|
#include "Selection.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef SELECTION_H
|
#ifndef SELECTION_H
|
||||||
#define SELECTION_H
|
#define SELECTION_H
|
||||||
|
|
||||||
#include "Source.h"
|
#include "SourceList.h"
|
||||||
|
|
||||||
class Selection
|
class Selection
|
||||||
{
|
{
|
||||||
|
|||||||
16
View.cpp
16
View.cpp
@@ -15,10 +15,10 @@
|
|||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "Source.h"
|
#include "Source.h"
|
||||||
#include "PickingVisitor.h"
|
#include "PickingVisitor.h"
|
||||||
#include "BoundingBoxVisitor.h"
|
|
||||||
#include "Decorations.h"
|
#include "Decorations.h"
|
||||||
#include "Mixer.h"
|
#include "Mixer.h"
|
||||||
#include "UserInterfaceManager.h"
|
#include "UserInterfaceManager.h"
|
||||||
|
#include "BoundingBoxVisitor.h"
|
||||||
#include "ActionManager.h"
|
#include "ActionManager.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
@@ -119,6 +119,7 @@ void View::initiate()
|
|||||||
|
|
||||||
(*sit)->stored_status_->copyTransform((*sit)->group(mode_));
|
(*sit)->stored_status_->copyTransform((*sit)->group(mode_));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::terminate()
|
void View::terminate()
|
||||||
@@ -242,7 +243,6 @@ void View::updateSelectionOverlay()
|
|||||||
overlay_selection_icon_ = new Handles(Handles::MENU);
|
overlay_selection_icon_ = new Handles(Handles::MENU);
|
||||||
overlay_selection_->attach(overlay_selection_icon_);
|
overlay_selection_->attach(overlay_selection_icon_);
|
||||||
overlay_selection_frame_ = new Frame(Frame::SHARP, Frame::LARGE, Frame::NONE);
|
overlay_selection_frame_ = new Frame(Frame::SHARP, Frame::LARGE, Frame::NONE);
|
||||||
// overlay_selection_frame_->scale_ = glm::vec3(1.05f, 1.05f, 1.f);
|
|
||||||
overlay_selection_->attach(overlay_selection_frame_);
|
overlay_selection_->attach(overlay_selection_frame_);
|
||||||
scene.fg()->attach(overlay_selection_);
|
scene.fg()->attach(overlay_selection_);
|
||||||
}
|
}
|
||||||
@@ -252,18 +252,6 @@ void View::updateSelectionOverlay()
|
|||||||
|
|
||||||
// potential selection if more than 1 source selected
|
// potential selection if more than 1 source selected
|
||||||
if (Mixer::selection().size() > 1) {
|
if (Mixer::selection().size() > 1) {
|
||||||
// calculate bbox on selection
|
|
||||||
BoundingBoxVisitor selection_visitor_bbox;
|
|
||||||
SourceList::iterator it = Mixer::selection().begin();
|
|
||||||
for (; it != Mixer::selection().end(); it++) {
|
|
||||||
// calculate bounding box of area covered by selection
|
|
||||||
selection_visitor_bbox.setModelview( scene.ws()->transform_ );
|
|
||||||
(*it)->group(mode_)->accept(selection_visitor_bbox);
|
|
||||||
}
|
|
||||||
// adjust group overlay to selection
|
|
||||||
GlmToolkit::AxisAlignedBoundingBox selection_box = selection_visitor_bbox.bbox();
|
|
||||||
overlay_selection_->scale_ = selection_box.scale();
|
|
||||||
overlay_selection_->translation_ = selection_box.center();
|
|
||||||
// show group overlay
|
// show group overlay
|
||||||
overlay_selection_->visible_ = true;
|
overlay_selection_->visible_ = true;
|
||||||
ImVec4 c = ImGuiToolkit::HighlightColor();
|
ImVec4 c = ImGuiToolkit::HighlightColor();
|
||||||
|
|||||||
Reference in New Issue
Block a user