git-svn-id: svn://db.shs.com.ru/libs@631 a8b55f48-bf90-11e4-a774-851b48703e85
This commit is contained in:
@@ -310,20 +310,33 @@ uint Mesh::hash() const {
|
|||||||
|
|
||||||
|
|
||||||
void Mesh::translatePoints(const QVector3D & dp) {
|
void Mesh::translatePoints(const QVector3D & dp) {
|
||||||
if (vertices_.isEmpty()) return;
|
QMatrix4x4 m;
|
||||||
int vcnt = vertices_.size();
|
m.translate(dp);
|
||||||
for (int i = 0; i < vcnt; ++i) {
|
transformPoints(m);
|
||||||
vertices_[i] += dp;
|
|
||||||
}
|
|
||||||
changed = hash_changed = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Mesh::scalePoints(const QVector3D & dp) {
|
void Mesh::scalePoints(const QVector3D & dp) {
|
||||||
|
QMatrix4x4 m;
|
||||||
|
m.scale(dp);
|
||||||
|
transformPoints(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Mesh::rotatePoints(const double & angle, const QVector3D & a) {
|
||||||
|
QMatrix4x4 m;
|
||||||
|
m.rotate(angle, a);
|
||||||
|
transformPoints(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Mesh::transformPoints(const QMatrix4x4 & mat) {
|
||||||
if (vertices_.isEmpty()) return;
|
if (vertices_.isEmpty()) return;
|
||||||
int vcnt = vertices_.size();
|
int vcnt = vertices_.size(), ncnt = normals_.size();
|
||||||
for (int i = 0; i < vcnt; ++i) {
|
for (int i = 0; i < vcnt; ++i) {
|
||||||
vertices_[i] *= dp;
|
vertices_[i] = (mat * QVector4D(vertices_[i], 1)).toVector3D();
|
||||||
|
if (i < ncnt)
|
||||||
|
normals_[i] = (mat * QVector4D(normals_[i], 0)).toVector3D();
|
||||||
}
|
}
|
||||||
changed = hash_changed = true;
|
changed = hash_changed = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,8 +62,12 @@ public:
|
|||||||
QVector< Vector2i> & indicesLines () {changed = hash_changed = true; return lines_;}
|
QVector< Vector2i> & indicesLines () {changed = hash_changed = true; return lines_;}
|
||||||
|
|
||||||
void translatePoints(const QVector3D & dp);
|
void translatePoints(const QVector3D & dp);
|
||||||
|
void translatePoints(const double & x, const double & y, const double & z) {translatePoints(QVector3D(x, y, z));}
|
||||||
void scalePoints (const QVector3D & dp);
|
void scalePoints (const QVector3D & dp);
|
||||||
void scalePoints (const double & s) {scalePoints(QVector3D(s, s, s));}
|
void scalePoints (const double & s) {scalePoints(QVector3D(s, s, s));}
|
||||||
|
void rotatePoints (const double & angle, const QVector3D & a);
|
||||||
|
void rotatePoints (const double & angle, const double & x, const double & y, const double & z) {rotatePoints(angle, QVector3D(x, y, z));}
|
||||||
|
void transformPoints(const QMatrix4x4 & mat);
|
||||||
void append(const Mesh * m);
|
void append(const Mesh * m);
|
||||||
|
|
||||||
bool saveToFile(const QString & filename);
|
bool saveToFile(const QString & filename);
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ Mesh * Primitive::ellipsoid(int segments_wl, int segments_h, float width, float
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Mesh * Primitive::disc(int segments, float width, float length, bool up) {
|
Mesh * Primitive::disc(int segments, float width, float length, bool up, float end_angle) {
|
||||||
Mesh * ret = new Mesh();
|
Mesh * ret = new Mesh();
|
||||||
QVector<QVector3D> & v(ret->vertices ());
|
QVector<QVector3D> & v(ret->vertices ());
|
||||||
QVector<QVector3D> & n(ret->normals ());
|
QVector<QVector3D> & n(ret->normals ());
|
||||||
@@ -137,8 +137,9 @@ Mesh * Primitive::disc(int segments, float width, float length, bool up) {
|
|||||||
QVector3D cp;
|
QVector3D cp;
|
||||||
v << QVector3D();
|
v << QVector3D();
|
||||||
t << QVector2D(0.5f, 0.5f);
|
t << QVector2D(0.5f, 0.5f);
|
||||||
|
end_angle *= deg2rad;
|
||||||
for (int i = 0; i < segments; i++) {
|
for (int i = 0; i < segments; i++) {
|
||||||
double a = (double)i / (segments - 1) * M_2PI;
|
double a = (double)i / (segments - 1) * end_angle;
|
||||||
cp.setX(length / 2. * cos(a));
|
cp.setX(length / 2. * cos(a));
|
||||||
cp.setY(width / 2. * sin(a));
|
cp.setY(width / 2. * sin(a));
|
||||||
v << cp;
|
v << cp;
|
||||||
@@ -263,7 +264,7 @@ Mesh * Primitive::arrow(int segments, float thick, float angle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Mesh * Primitive::torus(int segments_main, int segments_second, float radius_main, float radius_second) {
|
Mesh * Primitive::torus(int segments_main, int segments_second, float radius_main, float radius_second, float end_angle) {
|
||||||
Mesh * ret = new Mesh();
|
Mesh * ret = new Mesh();
|
||||||
QVector<QVector3D> & v(ret->vertices ());
|
QVector<QVector3D> & v(ret->vertices ());
|
||||||
QVector<QVector3D> & n(ret->normals ());
|
QVector<QVector3D> & n(ret->normals ());
|
||||||
@@ -287,7 +288,7 @@ Mesh * Primitive::torus(int segments_main, int segments_second, float radius_mai
|
|||||||
for (int i = 0; i < segments_main; i++) {
|
for (int i = 0; i < segments_main; i++) {
|
||||||
double x = (double)i / (segments_main - 1);
|
double x = (double)i / (segments_main - 1);
|
||||||
QMatrix4x4 rm;
|
QMatrix4x4 rm;
|
||||||
rm.rotate(x * 360., 0., 0., 1.);
|
rm.rotate(x * end_angle, 0., 0., 1.);
|
||||||
for (int j = 0; j < ccnt; j++) {
|
for (int j = 0; j < ccnt; j++) {
|
||||||
ct[j].setX(x);
|
ct[j].setX(x);
|
||||||
v << rm.map(cv[j]);
|
v << rm.map(cv[j]);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ Mesh * cube(float width = 1., float length = 1., float height = 1.);
|
|||||||
|
|
||||||
Mesh * ellipsoid(int segments_wl, int segments_h, float width = 1., float length = 1., float height = 1.);
|
Mesh * ellipsoid(int segments_wl, int segments_h, float width = 1., float length = 1., float height = 1.);
|
||||||
|
|
||||||
Mesh * disc(int segments, float width = 1., float length = 1., bool up = true);
|
Mesh * disc(int segments, float width = 1., float length = 1., bool up = true, float end_angle = 360.);
|
||||||
|
|
||||||
Mesh * cone(int segments, float width = 1., float length = 1., float height = 1.);
|
Mesh * cone(int segments, float width = 1., float length = 1., float height = 1.);
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ Mesh * cylinder(int segments, float width = 1., float length = 1., float height
|
|||||||
|
|
||||||
Mesh * arrow(int segments = 16, float thick = 0.04, float angle = 30.); // length = 1
|
Mesh * arrow(int segments = 16, float thick = 0.04, float angle = 30.); // length = 1
|
||||||
|
|
||||||
Mesh * torus(int segments_main = 30, int segments_second = 16, float radius_main = 2.5, float radius_second = 0.5);
|
Mesh * torus(int segments_main = 30, int segments_second = 16, float radius_main = 2.5, float radius_second = 0.5, float end_angle = 360.);
|
||||||
|
|
||||||
|
|
||||||
Mesh * cubeFrame(float width = 1., float length = 1., float height = 1.);
|
Mesh * cubeFrame(float width = 1., float length = 1., float height = 1.);
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ void Scene::selectObjects(QList<ObjectBase *> ol, bool add_to_selection) {
|
|||||||
|
|
||||||
void Scene::clearSelection() {
|
void Scene::clearSelection() {
|
||||||
selected_.clear();
|
selected_.clear();
|
||||||
|
selected_top.clear();
|
||||||
QList<ObjectBase * > ol = root_->children(true);
|
QList<ObjectBase * > ol = root_->children(true);
|
||||||
foreach (ObjectBase * o, ol) {
|
foreach (ObjectBase * o, ol) {
|
||||||
o->selected_ = false;
|
o->selected_ = false;
|
||||||
@@ -412,13 +413,14 @@ bool Scene::prepare() {
|
|||||||
|
|
||||||
|
|
||||||
void Scene::destroy() {
|
void Scene::destroy() {
|
||||||
|
selected_.clear();
|
||||||
|
selected_top.clear();
|
||||||
|
emitSelectionChanged();
|
||||||
root_->clearChildren(true);
|
root_->clearChildren(true);
|
||||||
qDeleteAll(geometries);
|
qDeleteAll(geometries);
|
||||||
qDeleteAll(materials);
|
qDeleteAll(materials);
|
||||||
geometries.clear();
|
geometries.clear();
|
||||||
materials.clear();
|
materials.clear();
|
||||||
selected_.clear();
|
|
||||||
selected_top.clear();
|
|
||||||
emit __destroyed();
|
emit __destroyed();
|
||||||
emit treeChanged();
|
emit treeChanged();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ QImage rotateQImageRight(const QImage & im);
|
|||||||
inline QImage rotateQImage180(const QImage & im) {return im.mirrored(true, true);}
|
inline QImage rotateQImage180(const QImage & im) {return im.mirrored(true, true);}
|
||||||
|
|
||||||
class QGLView;
|
class QGLView;
|
||||||
|
class MouseController;
|
||||||
class ObjectBase;
|
class ObjectBase;
|
||||||
class Light;
|
class Light;
|
||||||
class Camera;
|
class Camera;
|
||||||
|
|||||||
271
qglengine/mouse_controller.cpp
Normal file
271
qglengine/mouse_controller.cpp
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
/*
|
||||||
|
MouseController
|
||||||
|
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mouse_controller.h"
|
||||||
|
#include "glmesh.h"
|
||||||
|
#include "qglview.h"
|
||||||
|
#include <qad_types.h>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
|
||||||
|
using namespace QGLEngineShaders;
|
||||||
|
|
||||||
|
|
||||||
|
MouseController::MouseController(QGLView * view_): view(view_) {
|
||||||
|
app_scale = 1;
|
||||||
|
lastPos = QPoint(-1, -1);
|
||||||
|
cur_action = RendererService::haNoAction;
|
||||||
|
sel_button = Qt::LeftButton;
|
||||||
|
sel_mod = Qt::ControlModifier;
|
||||||
|
mouse_first = mouseSelect_ = mouseRotate_ = cameraOrbit_ = canSelect_ = true;
|
||||||
|
grabMouse_ = mouse_sec = selecting_ = customMouseMove_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MouseController::~MouseController() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MouseController::resize() {
|
||||||
|
mouse_first = true;
|
||||||
|
app_scale = appScale();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MouseController::mouseReleaseEvent(QMouseEvent * e) {
|
||||||
|
if (cur_action != RendererService::haNoAction) {
|
||||||
|
mouseMoveEvent(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool add_ts = e->modifiers().testFlag(sel_mod);
|
||||||
|
if (selecting_) {
|
||||||
|
selecting_ = false;
|
||||||
|
canSelect_ = true;
|
||||||
|
view->renderer_.mouse_rect = QRect();
|
||||||
|
view->scene_->selectObjects(hov_objects.toList(), add_ts);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (canSelect_ && mouseSelect_ && e->button() == Qt::LeftButton) {
|
||||||
|
if ((lastPos - downPos).manhattanLength() < QApplication::startDragDistance() && !hov_objects.isEmpty()) {
|
||||||
|
view->scene_->selectObject(hov_objects[0], add_ts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
canSelect_ = e->buttons() == 0;
|
||||||
|
emit view->glMouseReleaseEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MouseController::mousePressEvent(QMouseEvent * e) {
|
||||||
|
downPos = e->pos();
|
||||||
|
if (cur_action != RendererService::haNoAction && e->buttons() == Qt::LeftButton) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (selecting_) {
|
||||||
|
selecting_ = false;
|
||||||
|
view->renderer_.mouse_rect = QRect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!QRect(QPoint(), view->size()).contains(e->pos())) return;
|
||||||
|
lastPos = e->pos();
|
||||||
|
downPos = lastPos;
|
||||||
|
emit view->glMousePressEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MouseController::mouseMoveEvent(QMouseEvent * e) {
|
||||||
|
QPoint cpos = e->pos();
|
||||||
|
if (cur_action != RendererService::haNoAction && (e->buttons() == Qt::LeftButton)) {
|
||||||
|
RendererService & rs(view->renderer_.rend_service);
|
||||||
|
QList<ObjectBase*> objects = view->scene_->selectedObjects(true);
|
||||||
|
QVector<int> axis;
|
||||||
|
switch (cur_action) {
|
||||||
|
case RendererService::haMove:
|
||||||
|
if (cur_handle.testFlag(RendererService::hmMoveX)) axis << 0;
|
||||||
|
if (cur_handle.testFlag(RendererService::hmMoveY)) axis << 1;
|
||||||
|
if (cur_handle.testFlag(RendererService::hmMoveZ)) axis << 2;
|
||||||
|
break;
|
||||||
|
case RendererService::haRotate:
|
||||||
|
if (cur_handle.testFlag(RendererService::hmRotateX)) axis << 0;
|
||||||
|
if (cur_handle.testFlag(RendererService::hmRotateY)) axis << 1;
|
||||||
|
if (cur_handle.testFlag(RendererService::hmRotateZ)) axis << 2;
|
||||||
|
break;
|
||||||
|
case RendererService::haScale:
|
||||||
|
if (cur_handle.testFlag(RendererService::hmScaleX)) axis << 0;
|
||||||
|
if (cur_handle.testFlag(RendererService::hmScaleY)) axis << 1;
|
||||||
|
if (cur_handle.testFlag(RendererService::hmScaleZ)) axis << 2;
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
QVector<QVector3D> scales;
|
||||||
|
foreach (int a, axis) {
|
||||||
|
QVector3D axe_vector; axe_vector[a] = 1.;
|
||||||
|
QMatrix4x4 axis_mat = view->camera()->fullViewMatrix() * rs.axis_mat;
|
||||||
|
QVector3D center_screen = axis_mat * rs.selection_center;
|
||||||
|
QVector3D axe_screen = ((axis_mat * (rs.selection_center + axe_vector)) - center_screen).normalized();
|
||||||
|
QVector3D mouse_vector(cpos - lastPos);
|
||||||
|
mouse_vector[1] *= -1.;
|
||||||
|
if (cur_action == RendererService::haMove) {
|
||||||
|
double len_scl = 1. / QVector3D(axe_screen.x(), axe_screen.y(), 1.E-6).length();
|
||||||
|
mouse_vector /= QVector3D(view->width(), view->height(), 1);
|
||||||
|
mouse_vector *= -center_screen.z() * len_scl;
|
||||||
|
axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector);
|
||||||
|
QMatrix4x4 pmat;
|
||||||
|
foreach (ObjectBase * o, objects) {
|
||||||
|
pmat.setToIdentity();
|
||||||
|
if (o->parent()) {
|
||||||
|
pmat = o->parent()->worldTransform();
|
||||||
|
pmat.setColumn(3, QVector4D(0,0,0,1));
|
||||||
|
double det = pmat.determinant();
|
||||||
|
if (det > 0.) pmat /= sqrt(det);
|
||||||
|
}
|
||||||
|
o->move((QVector4D(axe_vector, 0) * pmat).toVector3D());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cur_action == RendererService::haRotate) {
|
||||||
|
axe_screen.setZ(0.);
|
||||||
|
axe_screen.normalize();
|
||||||
|
QVector3D norm = QVector3D(axe_screen.y(), -axe_screen.x(), 0.);
|
||||||
|
axe_vector *= QVector3D::dotProduct(mouse_vector, norm) / 2. / app_scale;
|
||||||
|
foreach (ObjectBase * o, objects)
|
||||||
|
o->setRotation(o->rotation() + axe_vector);
|
||||||
|
}
|
||||||
|
if (cur_action == RendererService::haScale) {
|
||||||
|
mouse_vector /= QVector3D(view->width(), view->height(), 1);
|
||||||
|
mouse_vector *= 3. / app_scale;
|
||||||
|
axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector);
|
||||||
|
scales << axe_vector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if (cur_handle >= RendererService::htScaleX && cur_handle <= RendererService::htScaleZ ) cs = Qt::SplitHCursor;
|
||||||
|
if (cur_action == RendererService::haScale) {
|
||||||
|
double sc = 0., max = 0.;
|
||||||
|
foreach (const QVector3D & s, scales) {
|
||||||
|
double v = QVector3D::dotProduct(s, QVector3D(1,1,1));
|
||||||
|
sc += v;
|
||||||
|
max = qMax(max, qAbs(v));
|
||||||
|
}
|
||||||
|
sc = max * (sc > 0. ? 1. : -1);
|
||||||
|
QVector3D axe_vector;
|
||||||
|
foreach (int a, axis)
|
||||||
|
axe_vector[a] = 1.;
|
||||||
|
foreach (ObjectBase * o, objects)
|
||||||
|
o->scale(QVector3D(1,1,1) + (axe_vector * sc));
|
||||||
|
QCursor::setPos(view->mapToGlobal(downPos));
|
||||||
|
} else
|
||||||
|
lastPos = e->pos();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (selecting_) {
|
||||||
|
view->renderer_.mouse_rect = QRect(downPos, cpos).normalized();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e->buttons().testFlag(Qt::LeftButton)) {
|
||||||
|
if ((cpos - downPos).manhattanLength() >= QApplication::startDragDistance()) {
|
||||||
|
selecting_ = true;
|
||||||
|
canSelect_ = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QRect g_rect(QPoint(), view->size());
|
||||||
|
if (mouseRotate_) {
|
||||||
|
float dx = e->x() - lastPos.x();
|
||||||
|
float dy = e->y() - lastPos.y();
|
||||||
|
if (e->buttons().testFlag(Qt::MidButton)) {
|
||||||
|
if (cameraOrbit_) {
|
||||||
|
view->camera()->orbitZ(dx / 4.f);
|
||||||
|
view->camera()->orbitXY(dy / 4.f);
|
||||||
|
} else {
|
||||||
|
view->camera()->rotateZ(dx / 4.f);
|
||||||
|
view->camera()->rotateXY(dy / 4.f);
|
||||||
|
}
|
||||||
|
emit view->cameraPosChanged(view->camera()->pos());
|
||||||
|
} else if (e->buttons().testFlag(Qt::RightButton)) {
|
||||||
|
float ad = view->camera()->distance();
|
||||||
|
view->camera()->moveLeft(dx / 1000.f * ad);
|
||||||
|
view->camera()->moveUp(dy / 1000.f * ad);
|
||||||
|
emit view->cameraPosChanged(view->camera()->pos());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastPos = e->pos();
|
||||||
|
if (customMouseMove_) emit view->customMouseMoveEvent(e->pos(), lastPos, e->buttons());
|
||||||
|
if (e->buttons() == 0) {
|
||||||
|
cur_handle = 0;
|
||||||
|
cur_action = RendererService::haNoAction;
|
||||||
|
Qt::CursorShape cs = Qt::CrossCursor;
|
||||||
|
if (view->renderer_.edit_mode) {
|
||||||
|
uint hid = view->renderer_.rend_selection.id_hover;
|
||||||
|
cur_handle = (RendererService::HandleMesh)hid;
|
||||||
|
if (hid >= RendererService::hmMoveX && hid <= RendererService::hmMaxMove ) {
|
||||||
|
cur_action = RendererService::haMove;
|
||||||
|
cs = Qt::SizeAllCursor;
|
||||||
|
}
|
||||||
|
if (hid >= RendererService::hmRotateX && hid <= RendererService::hmMaxRotate) {
|
||||||
|
cur_action = RendererService::haRotate;
|
||||||
|
cs = Qt::PointingHandCursor;
|
||||||
|
}
|
||||||
|
if (hid >= RendererService::hmScaleX && hid <= RendererService::hmMaxScale ) {
|
||||||
|
cur_action = RendererService::haScale;
|
||||||
|
cs = Qt::SplitHCursor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cur_action == RendererService::haNoAction)
|
||||||
|
cur_handle = 0;
|
||||||
|
view->setCursor(cs);
|
||||||
|
view->renderer_.rend_service.current_handle = cur_handle;
|
||||||
|
}
|
||||||
|
if (grabMouse_) {
|
||||||
|
QCursor::setPos(view->mapToGlobal(QRect(QPoint(), view->size()).center()));
|
||||||
|
if (mouse_sec) {
|
||||||
|
mouse_sec = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mouse_first) {
|
||||||
|
mouse_first = false;
|
||||||
|
mouse_sec = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastPos = g_rect.center();
|
||||||
|
int dx = e->x() - lastPos.x();
|
||||||
|
int dy = e->y() - lastPos.y();
|
||||||
|
emit view->glMouseMoveEvent(new QMouseEvent(QEvent::MouseMove, QPoint(dx, dy), e->button(), e->buttons(), e->modifiers()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit view->glMouseMoveEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MouseController::wheelEvent(QWheelEvent * e) {
|
||||||
|
if (mouseRotate_) {
|
||||||
|
if (e->delta() > 0) view->camera()->flyCloser(0.1f);
|
||||||
|
if (e->delta() < 0) view->camera()->flyFarer(0.1f);
|
||||||
|
emit view->cameraPosChanged(view->camera()->pos());
|
||||||
|
}
|
||||||
|
emit view->glWheelEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MouseController::leaveEvent(QEvent * ) {
|
||||||
|
lastPos = QPoint(-1, -1);
|
||||||
|
//qDebug() << lastPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MouseController::mouseDoubleClickEvent(QMouseEvent * e) {
|
||||||
|
if (e->buttons().testFlag(Qt::MidButton))
|
||||||
|
emit view->doubleClick();
|
||||||
|
}
|
||||||
84
qglengine/mouse_controller.h
Normal file
84
qglengine/mouse_controller.h
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
QGLView
|
||||||
|
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MOUSE_CONTROLLER_H
|
||||||
|
#define MOUSE_CONTROLLER_H
|
||||||
|
|
||||||
|
#include "glprimitives.h"
|
||||||
|
#include "glcamera.h"
|
||||||
|
#include "renderer_service.h"
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QTime>
|
||||||
|
|
||||||
|
|
||||||
|
class MouseController: public QObject
|
||||||
|
{
|
||||||
|
friend class QGLView;
|
||||||
|
friend class RendererSelection;
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
MouseController(QGLView * view_);
|
||||||
|
virtual ~MouseController();
|
||||||
|
|
||||||
|
bool isGrabMouseEnabled() const {return grabMouse_;}
|
||||||
|
bool isMouseRotateEnabled() const {return mouseRotate_;}
|
||||||
|
bool isMouseSelectionEnabled() const {return mouseSelect_;}
|
||||||
|
bool isCameraOrbit() const {return cameraOrbit_;}
|
||||||
|
|
||||||
|
Qt::MouseButton selectionButton() const {return sel_button;}
|
||||||
|
Qt::KeyboardModifier selectionModifier() const {return sel_mod;}
|
||||||
|
|
||||||
|
void setSelectionButton(Qt::MouseButton v) {sel_button = v;}
|
||||||
|
void setSelectionModifier(Qt::KeyboardModifier v) {sel_mod = v;}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void resize();
|
||||||
|
void mousePressEvent(QMouseEvent * e);
|
||||||
|
void mouseMoveEvent(QMouseEvent * e);
|
||||||
|
void mouseReleaseEvent(QMouseEvent * e);
|
||||||
|
void wheelEvent(QWheelEvent * e);
|
||||||
|
void leaveEvent(QEvent * );
|
||||||
|
void mouseDoubleClickEvent(QMouseEvent * e);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QGLView * view;
|
||||||
|
QPoint lastPos, downPos;
|
||||||
|
QSet<int> keys_;
|
||||||
|
QVector<ObjectBase * > hov_objects;
|
||||||
|
Qt::MouseButton sel_button;
|
||||||
|
Qt::KeyboardModifier sel_mod;
|
||||||
|
RendererService::HandleAction cur_action;
|
||||||
|
QFlags<RendererService::HandleMesh> cur_handle;
|
||||||
|
float app_scale;
|
||||||
|
bool grabMouse_, mouse_first, mouseRotate_, mouseSelect_, customMouseMove_, canSelect_;
|
||||||
|
bool cameraOrbit_, selecting_, mouse_sec;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setGrabMouseEnabled(const bool & arg) {grabMouse_ = arg; mouse_first = true;}
|
||||||
|
void setMouseRotateEnabled(const bool & arg) {mouseRotate_ = arg;}
|
||||||
|
void setMouseSelectionEnabled(const bool & arg) {mouseSelect_ = arg;}
|
||||||
|
void setCustomMouseMove(const bool & arg) {customMouseMove_ = arg;}
|
||||||
|
void setCameraOrbit(const bool & arg) {cameraOrbit_ = arg;}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QGLVIEW_H
|
||||||
@@ -28,25 +28,20 @@
|
|||||||
using namespace QGLEngineShaders;
|
using namespace QGLEngineShaders;
|
||||||
|
|
||||||
|
|
||||||
QGLView::QGLView(): OpenGLWindow(), renderer_(this) {
|
QGLView::QGLView(): OpenGLWindow(), renderer_(this), mouse(this) {
|
||||||
setIcon(QIcon(":/icons/qglview.png"));
|
setIcon(QIcon(":/icons/qglview.png"));
|
||||||
deleting_ = false;
|
deleting_ = false;
|
||||||
timer = 0;
|
timer = 0;
|
||||||
app_scale = 1;
|
|
||||||
cur_handle = RendererService::htNoHandle;
|
|
||||||
need_init_ = is_first_draw = true;
|
need_init_ = is_first_draw = true;
|
||||||
backColor_ = Qt::darkGray;
|
backColor_ = Qt::darkGray;
|
||||||
hoverHaloColor_ = QColor(195, 140, 255);
|
hoverHaloColor_ = QColor(195, 140, 255);
|
||||||
selectionHaloColor_ = QColor(175, 255, 140);
|
selectionHaloColor_ = QColor(175, 255, 140);
|
||||||
ambientColor_ = QColor(10, 10, 10);
|
ambientColor_ = QColor(10, 10, 10);
|
||||||
lastPos = QPoint(-1, -1);
|
|
||||||
lineWidth_ = 1.;
|
lineWidth_ = 1.;
|
||||||
max_anisotropic = 1;
|
max_anisotropic = 1;
|
||||||
max_texture_chanels = 8;
|
max_texture_chanels = 8;
|
||||||
cameraOrbit_ = lightEnabled_ = canSelect_ = true;
|
lightEnabled_ = true;
|
||||||
shaders_supported = selecting_ = customMouseMove_ = false;
|
shaders_supported = false;
|
||||||
sel_button = Qt::LeftButton;
|
|
||||||
sel_mod = Qt::ControlModifier;
|
|
||||||
fps_cnt = 0;
|
fps_cnt = 0;
|
||||||
fps_tm = fps_ = 0.;
|
fps_tm = fps_ = 0.;
|
||||||
fogDensity_ = fogEnd_ = 1.;
|
fogDensity_ = fogEnd_ = 1.;
|
||||||
@@ -77,9 +72,8 @@ QGLView::QGLView(): OpenGLWindow(), renderer_(this) {
|
|||||||
setFeature(qglDepthOfFieldAutoFocusSpeed, 0.1);
|
setFeature(qglDepthOfFieldAutoFocusSpeed, 0.1);
|
||||||
setFeature(qglDepthOfFieldFocus, 1.);
|
setFeature(qglDepthOfFieldFocus, 1.);
|
||||||
setFeature(qglDepthOfFieldDiaphragm, 8.);
|
setFeature(qglDepthOfFieldDiaphragm, 8.);
|
||||||
mouse_first = mouseSelect_ = hoverHalo_ = selectionHalo_ = true;
|
hoverHalo_ = selectionHalo_ = true;
|
||||||
mouseRotate_ = true;
|
fogEnabled_ = is_init = shaders_bind = changed_ = false;
|
||||||
fogEnabled_ = is_init = grabMouse_ = shaders_bind = changed_ = false;
|
|
||||||
rmode = ObjectBase::Fill;
|
rmode = ObjectBase::Fill;
|
||||||
// sel_pen = QPen(Qt::black, 1, Qt::DashLine);
|
// sel_pen = QPen(Qt::black, 1, Qt::DashLine);
|
||||||
// sel_brush = QBrush(QColor(170, 100, 255, 120));
|
// sel_brush = QBrush(QColor(170, 100, 255, 120));
|
||||||
@@ -94,7 +88,10 @@ QGLView::QGLView(): OpenGLWindow(), renderer_(this) {
|
|||||||
//camera().aim_ = camera().pos_;
|
//camera().aim_ = camera().pos_;
|
||||||
ktm_.restart();
|
ktm_.restart();
|
||||||
|
|
||||||
Mesh * m = Primitive::torus(30, 12, 1., 0.1);
|
//Mesh * m = Primitive::torus(30, 12, 1., 0.1, 90);
|
||||||
|
Mesh * m = Primitive::disc(10, 1, 1., true, 90);
|
||||||
|
QMatrix4x4 mat; mat.rotate(90, 1,0,0);
|
||||||
|
//m->transformPoints(mat);
|
||||||
ObjectBase * o = new ObjectBase(m);
|
ObjectBase * o = new ObjectBase(m);
|
||||||
o->setColor(Qt::cyan);
|
o->setColor(Qt::cyan);
|
||||||
scene()->addObject(o);
|
scene()->addObject(o);
|
||||||
@@ -121,40 +118,10 @@ void QGLView::start(float freq) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Scene::SelectionMode QGLView::selectionMode() const {
|
|
||||||
return scene_->selectionMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QGLView::setSelectionMode(Scene::SelectionMode m) {
|
|
||||||
scene_->setSelectionMode(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QGLView::selectObject(ObjectBase * o, bool add_to_selection) {
|
|
||||||
scene_->selectObject(o, add_to_selection);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QGLView::clearSelection() {
|
|
||||||
scene_->clearSelection();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QList<ObjectBase * > QGLView::selectedObjects() const {
|
|
||||||
return scene_->selectedObjects();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ObjectBase * QGLView::selectedObject() const {
|
|
||||||
return scene_->selectedObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void QGLView::resizeEvent(QResizeEvent * e) {
|
void QGLView::resizeEvent(QResizeEvent * e) {
|
||||||
renderLater();
|
renderLater();
|
||||||
app_scale = appScale();
|
mouse.resize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -211,7 +178,7 @@ void QGLView::checkCaps() {
|
|||||||
|
|
||||||
void QGLView::__destroyed() {
|
void QGLView::__destroyed() {
|
||||||
renderer_.rend_mat.mat_thumbnails.clear();
|
renderer_.rend_mat.mat_thumbnails.clear();
|
||||||
hov_objects.clear();
|
mouse.hov_objects.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -222,7 +189,6 @@ void QGLView::resizeGL(int width, int height) {
|
|||||||
prev_size = QSize(width, height);
|
prev_size = QSize(width, height);
|
||||||
aspect = float(width) / float(height);
|
aspect = float(width) / float(height);
|
||||||
renderer_.resize(width, height);
|
renderer_.resize(width, height);
|
||||||
mouse_first = true;
|
|
||||||
//qDebug() << "resize" << width << height;
|
//qDebug() << "resize" << width << height;
|
||||||
iaspect = (aspect == 0.f) ? 0. : 1 / aspect;
|
iaspect = (aspect == 0.f) ? 0. : 1 / aspect;
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
@@ -230,173 +196,6 @@ void QGLView::resizeGL(int width, int height) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QGLView::mouseReleaseEvent(QMouseEvent * e) {
|
|
||||||
if (cur_handle != RendererService::htNoHandle) {
|
|
||||||
mouseMoveEvent(e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bool add_ts = e->modifiers().testFlag(sel_mod);
|
|
||||||
if (selecting_) {
|
|
||||||
selecting_ = false;
|
|
||||||
canSelect_ = true;
|
|
||||||
renderer_.mouse_rect = QRect();
|
|
||||||
scene_->selectObjects(hov_objects.toList(), add_ts);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (canSelect_ && mouseSelect_ && e->button() == Qt::LeftButton) {
|
|
||||||
if ((lastPos - downPos).manhattanLength() < QApplication::startDragDistance() && !hov_objects.isEmpty()) {
|
|
||||||
scene_->selectObject(hov_objects[0], add_ts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
canSelect_ = e->buttons() == 0;
|
|
||||||
emit glMouseReleaseEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QGLView::mousePressEvent(QMouseEvent * e) {
|
|
||||||
if (cur_handle != RendererService::htNoHandle && e->buttons() == Qt::LeftButton) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (selecting_) {
|
|
||||||
downPos = e->pos();
|
|
||||||
selecting_ = false;
|
|
||||||
renderer_.mouse_rect = QRect();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!QRect(QPoint(), size()).contains(e->pos())) return;
|
|
||||||
lastPos = e->pos();
|
|
||||||
downPos = lastPos;
|
|
||||||
emit glMousePressEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QGLView::mouseMoveEvent(QMouseEvent * e) {
|
|
||||||
QPoint cpos = e->pos();
|
|
||||||
if (cur_handle != RendererService::htNoHandle && (e->buttons() == Qt::LeftButton)) {
|
|
||||||
RendererService & rs(renderer_.rend_service);
|
|
||||||
QList<ObjectBase*> objects = scene()->selectedObjects(true);
|
|
||||||
int axis = cur_handle;
|
|
||||||
if (cur_handle >= RendererService::htMoveX && cur_handle <= RendererService::htMoveZ ) axis -= RendererService::htMoveX;
|
|
||||||
if (cur_handle >= RendererService::htRotateX && cur_handle <= RendererService::htRotateZ) axis -= RendererService::htRotateX;
|
|
||||||
if (cur_handle >= RendererService::htScaleX && cur_handle <= RendererService::htScaleZ ) axis -= RendererService::htScaleX;
|
|
||||||
QVector3D axe_vector; axe_vector[axis] = 1.;
|
|
||||||
QMatrix4x4 axis_mat = camera()->fullViewMatrix() * rs.axis_mat;
|
|
||||||
QVector3D center_screen = axis_mat * rs.selection_center;
|
|
||||||
QVector3D axe_screen = ((axis_mat * (rs.selection_center + axe_vector)) - center_screen).normalized();
|
|
||||||
QVector3D mouse_vector(cpos - lastPos);
|
|
||||||
mouse_vector[1] *= -1.;
|
|
||||||
if (cur_handle >= RendererService::htMoveX && cur_handle <= RendererService::htMoveZ) {
|
|
||||||
double len_scl = 1. / QVector3D(axe_screen.x(), axe_screen.y(), 1.E-6).length();
|
|
||||||
mouse_vector /= QVector3D(width(), height(), 1);
|
|
||||||
mouse_vector *= -center_screen.z() * len_scl;
|
|
||||||
axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector);
|
|
||||||
foreach (ObjectBase * o, objects)
|
|
||||||
o->move(axe_vector);
|
|
||||||
}
|
|
||||||
if (cur_handle >= RendererService::htRotateX && cur_handle <= RendererService::htRotateZ) {
|
|
||||||
axe_screen.setZ(0.);
|
|
||||||
axe_screen.normalize();
|
|
||||||
QVector3D norm = QVector3D(axe_screen.y(), -axe_screen.x(), 0.);
|
|
||||||
axe_vector *= QVector3D::dotProduct(mouse_vector, norm) / 2. / app_scale;
|
|
||||||
foreach (ObjectBase * o, objects)
|
|
||||||
o->setRotation(o->rotation() + axe_vector);
|
|
||||||
}
|
|
||||||
if (cur_handle >= RendererService::htScaleX && cur_handle <= RendererService::htScaleZ) {
|
|
||||||
mouse_vector /= QVector3D(width(), height(), 1);
|
|
||||||
mouse_vector *= 3. / app_scale;
|
|
||||||
axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector);
|
|
||||||
foreach (ObjectBase * o, objects)
|
|
||||||
o->scale(QVector3D(1,1,1) + axe_vector);
|
|
||||||
}
|
|
||||||
//if (cur_handle >= RendererService::htScaleX && cur_handle <= RendererService::htScaleZ ) cs = Qt::SplitHCursor;
|
|
||||||
lastPos = e->pos();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (selecting_) {
|
|
||||||
renderer_.mouse_rect = QRect(downPos, cpos).normalized();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (e->buttons().testFlag(Qt::LeftButton)) {
|
|
||||||
if ((cpos - downPos).manhattanLength() >= QApplication::startDragDistance()) {
|
|
||||||
selecting_ = true;
|
|
||||||
canSelect_ = false;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QRect g_rect(QPoint(), size());
|
|
||||||
if (mouseRotate_) {
|
|
||||||
float dx = e->x() - lastPos.x();
|
|
||||||
float dy = e->y() - lastPos.y();
|
|
||||||
if (e->buttons().testFlag(Qt::MidButton)) {
|
|
||||||
if (cameraOrbit_) {
|
|
||||||
camera()->orbitZ(dx / 4.f);
|
|
||||||
camera()->orbitXY(dy / 4.f);
|
|
||||||
} else {
|
|
||||||
camera()->rotateZ(dx / 4.f);
|
|
||||||
camera()->rotateXY(dy / 4.f);
|
|
||||||
}
|
|
||||||
emit cameraPosChanged(camera()->pos());
|
|
||||||
} else if (e->buttons().testFlag(Qt::RightButton)) {
|
|
||||||
float ad = camera()->distance();
|
|
||||||
camera()->moveLeft(dx / 1000.f * ad);
|
|
||||||
camera()->moveUp(dy / 1000.f * ad);
|
|
||||||
emit cameraPosChanged(camera()->pos());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastPos = e->pos();
|
|
||||||
if (customMouseMove_) emit customMouseMoveEvent(e->pos(), lastPos, e->buttons());
|
|
||||||
if (e->buttons() == 0) {
|
|
||||||
cur_handle = RendererService::htNoHandle;
|
|
||||||
Qt::CursorShape cs = Qt::CrossCursor;
|
|
||||||
if (renderer_.edit_mode) {
|
|
||||||
uint hid = renderer_.rend_selection.id_hover;
|
|
||||||
if (hid >= RendererService::htMoveX && hid <= RendererService::htScaleZ) {
|
|
||||||
cur_handle = (RendererService::HandleType)hid;
|
|
||||||
if (hid >= RendererService::htMoveX && hid <= RendererService::htMoveZ ) cs = Qt::SizeAllCursor;
|
|
||||||
if (hid >= RendererService::htRotateX && hid <= RendererService::htRotateZ) cs = Qt::PointingHandCursor;
|
|
||||||
if (hid >= RendererService::htScaleX && hid <= RendererService::htScaleZ ) cs = Qt::SplitHCursor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setCursor(cs);
|
|
||||||
}
|
|
||||||
if (grabMouse_) {
|
|
||||||
QCursor::setPos(mapToGlobal(QRect(QPoint(), size()).center()));
|
|
||||||
static bool mouse_sec = false;
|
|
||||||
if (mouse_sec) {
|
|
||||||
mouse_sec = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mouse_first) {
|
|
||||||
mouse_first = false;
|
|
||||||
mouse_sec = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lastPos = g_rect.center();
|
|
||||||
int dx = e->x() - lastPos.x();
|
|
||||||
int dy = e->y() - lastPos.y();
|
|
||||||
emit glMouseMoveEvent(new QMouseEvent(QEvent::MouseMove, QPoint(dx, dy), e->button(), e->buttons(), e->modifiers()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
emit glMouseMoveEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QGLView::wheelEvent(QWheelEvent * e) {
|
|
||||||
if (mouseRotate_) {
|
|
||||||
if (e->delta() > 0) camera()->flyCloser(0.1f);
|
|
||||||
if (e->delta() < 0) camera()->flyFarer(0.1f);
|
|
||||||
emit cameraPosChanged(camera()->pos());
|
|
||||||
}
|
|
||||||
emit glWheelEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QGLView::leaveEvent(QEvent * ) {
|
|
||||||
lastPos = QPoint(-1, -1);
|
|
||||||
//qDebug() << lastPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QGLView::keyPressEvent(QKeyEvent * e) {
|
void QGLView::keyPressEvent(QKeyEvent * e) {
|
||||||
emit glKeyPressEvent(e);
|
emit glKeyPressEvent(e);
|
||||||
if (e->key() > 0) keys_.insert(e->key());
|
if (e->key() > 0) keys_.insert(e->key());
|
||||||
@@ -417,37 +216,6 @@ void QGLView::focusOutEvent(QFocusEvent *) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QGLView::mouseDoubleClickEvent(QMouseEvent * e) {
|
|
||||||
if (e->buttons().testFlag(Qt::MidButton))
|
|
||||||
emit doubleClick();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Camera * QGLView::camera() {
|
|
||||||
return camera_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const Camera * QGLView::camera() const {
|
|
||||||
return camera_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QGLView::setCamera(Camera * camera) {
|
|
||||||
camera_ = camera;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TextureManager * QGLView::textureManager() {
|
|
||||||
return renderer_.textures_manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QGLView::reloadTextures() {
|
|
||||||
renderer_.markReloadTextures();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QGLView::focusOn(const Box3D & bb) {
|
void QGLView::focusOn(const Box3D & bb) {
|
||||||
if (bb.isEmpty() || !camera()) return;
|
if (bb.isEmpty() || !camera()) return;
|
||||||
double size = qMax(qMax(bb.width, bb.length), bb.height);
|
double size = qMax(qMax(bb.width, bb.length), bb.height);
|
||||||
@@ -456,16 +224,6 @@ void QGLView::focusOn(const Box3D & bb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QGLView::setCameraLightOn(bool on) {
|
|
||||||
renderer_.setCameraLightOn(on);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool QGLView::isCameraLightOn() const {
|
|
||||||
return renderer_.isCameraLightOn();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QByteArray QGLView::saveCamera() {
|
QByteArray QGLView::saveCamera() {
|
||||||
ChunkStream cs;
|
ChunkStream cs;
|
||||||
const Camera * c = camera();
|
const Camera * c = camera();
|
||||||
@@ -503,14 +261,3 @@ void QGLView::restoreFeatures(const QByteArray & ba) {
|
|||||||
ds >> f;
|
ds >> f;
|
||||||
features_ = f;
|
features_ = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QImage QGLView::materialThumbnail(Material * m) {
|
|
||||||
return renderer_.materialThumbnail(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void QGLView::setCurrentHadle(RendererService::HandleType ht) {
|
|
||||||
renderer_.rend_service.setCurrentHadle(ht);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,11 +26,13 @@
|
|||||||
#include "glscene.h"
|
#include "glscene.h"
|
||||||
#include "glrendererbase.h"
|
#include "glrendererbase.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
#include "mouse_controller.h"
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
|
||||||
|
|
||||||
class QGLView: public OpenGLWindow
|
class QGLView: public OpenGLWindow
|
||||||
{
|
{
|
||||||
|
friend class MouseController;
|
||||||
friend class GLRendererBase;
|
friend class GLRendererBase;
|
||||||
friend class TextureManager;
|
friend class TextureManager;
|
||||||
friend class ObjectBase;
|
friend class ObjectBase;
|
||||||
@@ -117,10 +119,10 @@ public:
|
|||||||
float fogEnd() const {return fogEnd_;}
|
float fogEnd() const {return fogEnd_;}
|
||||||
bool isFogEnabled() const {return fogEnabled_;}
|
bool isFogEnabled() const {return fogEnabled_;}
|
||||||
bool isLightEnabled() const {return lightEnabled_;}
|
bool isLightEnabled() const {return lightEnabled_;}
|
||||||
bool isGrabMouseEnabled() const {return grabMouse_;}
|
bool isGrabMouseEnabled() const {return mouse.isGrabMouseEnabled();}
|
||||||
bool isMouseRotateEnabled() const {return mouseRotate_;}
|
bool isMouseRotateEnabled() const {return mouse.isMouseRotateEnabled();}
|
||||||
bool isMouseSelectionEnabled() const {return mouseSelect_;}
|
bool isMouseSelectionEnabled() const {return mouse.isMouseSelectionEnabled();}
|
||||||
bool isCameraOrbit() const {return cameraOrbit_;}
|
bool isCameraOrbit() const {return mouse.isCameraOrbit();}
|
||||||
bool isHoverHaloEnabled() const {return hoverHalo_;}
|
bool isHoverHaloEnabled() const {return hoverHalo_;}
|
||||||
QColor hoverHaloColor() const {return hoverHaloColor_;}
|
QColor hoverHaloColor() const {return hoverHaloColor_;}
|
||||||
float hoverHaloFillAlpha() const {return hoverHaloFill_;}
|
float hoverHaloFillAlpha() const {return hoverHaloFill_;}
|
||||||
@@ -137,37 +139,37 @@ public:
|
|||||||
|
|
||||||
// void addObject(GLObjectBase & o) {addObject(&o);}
|
// void addObject(GLObjectBase & o) {addObject(&o);}
|
||||||
|
|
||||||
Scene::SelectionMode selectionMode() const;
|
Scene::SelectionMode selectionMode() const {return scene_->selectionMode();}
|
||||||
Qt::MouseButton selectionButton() const {return sel_button;}
|
Qt::MouseButton selectionButton() const {return mouse.selectionButton();}
|
||||||
Qt::KeyboardModifier selectionModifier() const {return sel_mod;}
|
Qt::KeyboardModifier selectionModifier() const {return mouse.selectionModifier();}
|
||||||
|
|
||||||
void setSelectionMode(Scene::SelectionMode m);
|
void setSelectionMode(Scene::SelectionMode m) {scene_->setSelectionMode(m);}
|
||||||
void setSelectionButton(Qt::MouseButton v) {sel_button = v;}
|
void setSelectionButton(Qt::MouseButton v) {mouse.setSelectionButton(v);}
|
||||||
void setSelectionModifier(Qt::KeyboardModifier v) {sel_mod = v;}
|
void setSelectionModifier(Qt::KeyboardModifier v) {mouse.setSelectionModifier(v);}
|
||||||
|
|
||||||
void selectObject(ObjectBase * o, bool add_to_selection = false);
|
void selectObject(ObjectBase * o, bool add_to_selection = false) {scene_->selectObject(o, add_to_selection);}
|
||||||
void clearSelection();
|
void clearSelection() {scene_->clearSelection();}
|
||||||
QList<ObjectBase * > selectedObjects() const;
|
QList<ObjectBase * > selectedObjects() const {return scene_->selectedObjects();}
|
||||||
ObjectBase * selectedObject() const;
|
ObjectBase * selectedObject() const {return scene_->selectedObject();}
|
||||||
|
|
||||||
TextureManager * textureManager();
|
TextureManager * textureManager() {return renderer_.textures_manager;}
|
||||||
void reloadTextures();
|
void reloadTextures() {renderer_.markReloadTextures();}
|
||||||
|
|
||||||
Scene * scene() {return scene_;}
|
Scene * scene() {return scene_;}
|
||||||
void focusOn(const Box3D & bb);
|
void focusOn(const Box3D & bb);
|
||||||
void setCameraLightOn(bool on);
|
void setCameraLightOn(bool on) {renderer_.setCameraLightOn(on);}
|
||||||
bool isCameraLightOn() const;
|
bool isCameraLightOn() const {return renderer_.isCameraLightOn();}
|
||||||
|
|
||||||
Camera * camera();
|
Camera * camera() {return camera_;}
|
||||||
const Camera * camera() const;
|
const Camera * camera() const {return camera_;}
|
||||||
void setCamera(Camera * camera);
|
void setCamera(Camera * camera) {camera_ = camera;}
|
||||||
QByteArray saveCamera();
|
QByteArray saveCamera();
|
||||||
void restoreCamera(const QByteArray & ba);
|
void restoreCamera(const QByteArray & ba);
|
||||||
QByteArray saveFeatures();
|
QByteArray saveFeatures();
|
||||||
void restoreFeatures(const QByteArray & ba);
|
void restoreFeatures(const QByteArray & ba);
|
||||||
|
|
||||||
QImage materialThumbnail(Material * m);
|
QImage materialThumbnail(Material * m) {return renderer_.materialThumbnail(m);}
|
||||||
void setCurrentHadle(RendererService::HandleType ht);
|
void setCurrentAction(RendererService::HandleAction ha) {renderer_.rend_service.setCurrentAction(ha);}
|
||||||
|
|
||||||
|
|
||||||
GLfloat aspect, iaspect;
|
GLfloat aspect, iaspect;
|
||||||
@@ -180,12 +182,12 @@ protected:
|
|||||||
void timerEvent(QTimerEvent * );
|
void timerEvent(QTimerEvent * );
|
||||||
void initialize();
|
void initialize();
|
||||||
void resizeGL(int width, int height);
|
void resizeGL(int width, int height);
|
||||||
void mousePressEvent(QMouseEvent * e);
|
void mousePressEvent(QMouseEvent * e) {mouse.mousePressEvent(e);}
|
||||||
void mouseMoveEvent(QMouseEvent * e);
|
void mouseMoveEvent(QMouseEvent * e) {mouse.mouseMoveEvent(e);}
|
||||||
void mouseReleaseEvent(QMouseEvent * e);
|
void mouseReleaseEvent(QMouseEvent * e) {mouse.mouseReleaseEvent(e);}
|
||||||
void wheelEvent(QWheelEvent * e);
|
void wheelEvent(QWheelEvent * e) {mouse.wheelEvent(e);}
|
||||||
|
void mouseDoubleClickEvent(QMouseEvent * e) {mouse.mouseDoubleClickEvent(e);}
|
||||||
void leaveEvent(QEvent * );
|
void leaveEvent(QEvent * );
|
||||||
void mouseDoubleClickEvent(QMouseEvent * e);
|
|
||||||
|
|
||||||
void keyPressEvent(QKeyEvent * e);
|
void keyPressEvent(QKeyEvent * e);
|
||||||
void keyReleaseEvent(QKeyEvent * e);
|
void keyReleaseEvent(QKeyEvent * e);
|
||||||
@@ -199,28 +201,24 @@ private:
|
|||||||
void processKeys();
|
void processKeys();
|
||||||
bool setupViewport();
|
bool setupViewport();
|
||||||
|
|
||||||
QPoint lastPos, downPos;
|
|
||||||
Scene * scene_;
|
Scene * scene_;
|
||||||
Camera * camera_;
|
Camera * camera_;
|
||||||
|
MouseController mouse;
|
||||||
// uint cid;
|
// uint cid;
|
||||||
QSet<int> keys_;
|
QSet<int> keys_;
|
||||||
QColor backColor_, fogColor_, ambientColor_, hoverHaloColor_, selectionHaloColor_;
|
QColor backColor_, fogColor_, ambientColor_, hoverHaloColor_, selectionHaloColor_;
|
||||||
QTime time, ktm_;
|
QTime time, ktm_;
|
||||||
GLint max_anisotropic, max_texture_chanels;
|
GLint max_anisotropic, max_texture_chanels;
|
||||||
ObjectBase::RenderMode rmode;
|
ObjectBase::RenderMode rmode;
|
||||||
QVector<ObjectBase * > hov_objects;
|
|
||||||
Qt::MouseButton sel_button;
|
|
||||||
Qt::KeyboardModifier sel_mod;
|
|
||||||
GLRendererBase::RenderingParameters start_rp;
|
GLRendererBase::RenderingParameters start_rp;
|
||||||
RendererService::HandleType cur_handle;
|
|
||||||
QHash<int, QVariant> features_;
|
QHash<int, QVariant> features_;
|
||||||
QSize prev_size;
|
QSize prev_size;
|
||||||
float lineWidth_, app_scale;
|
float lineWidth_;
|
||||||
float fogDensity_, fogStart_, fogEnd_, fps_, fps_tm, hoverHaloFill_, selectionHaloFill_, m_motionBlurFactor;
|
float fogDensity_, fogStart_, fogEnd_, fps_, fps_tm, hoverHaloFill_, selectionHaloFill_, m_motionBlurFactor;
|
||||||
int timer, fps_cnt, sh_id_loc, deleting_;
|
int timer, fps_cnt, sh_id_loc, deleting_;
|
||||||
bool is_first_draw, is_init, fogEnabled_, lightEnabled_, grabMouse_, mouse_first, mouseRotate_, mouseSelect_, customMouseMove_, canSelect_;
|
bool is_first_draw, is_init, fogEnabled_, lightEnabled_;
|
||||||
bool shaders_supported, changed_, cameraOrbit_, need_init_;
|
bool shaders_supported, changed_, need_init_;
|
||||||
bool hoverHalo_, selectionHalo_, shaders_bind, selecting_;
|
bool hoverHalo_, selectionHalo_, shaders_bind;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void __destroyed();
|
void __destroyed();
|
||||||
@@ -238,11 +236,11 @@ public slots:
|
|||||||
void setFogEnd(const float & arg) {fogEnd_ = arg;}
|
void setFogEnd(const float & arg) {fogEnd_ = arg;}
|
||||||
void setFogEnabled(const bool & arg) {fogEnabled_ = arg;}
|
void setFogEnabled(const bool & arg) {fogEnabled_ = arg;}
|
||||||
void setLightEnabled(const bool & arg) {lightEnabled_ = arg;}
|
void setLightEnabled(const bool & arg) {lightEnabled_ = arg;}
|
||||||
void setGrabMouseEnabled(const bool & arg) {grabMouse_ = arg; mouse_first = true;}
|
void setGrabMouseEnabled(const bool & arg) {mouse.setGrabMouseEnabled(arg);}
|
||||||
void setMouseRotateEnabled(const bool & arg) {mouseRotate_ = arg;}
|
void setMouseRotateEnabled(const bool & arg) {mouse.setMouseRotateEnabled(arg);}
|
||||||
void setMouseSelectionEnabled(const bool & arg) {mouseSelect_ = arg;}
|
void setMouseSelectionEnabled(const bool & arg) {mouse.setMouseSelectionEnabled(arg);}
|
||||||
void setCustomMouseMove(const bool & arg) {customMouseMove_ = arg;}
|
void setCustomMouseMove(const bool & arg) {mouse.setCustomMouseMove(arg);}
|
||||||
void setCameraOrbit(const bool & arg) {cameraOrbit_ = arg;}
|
void setCameraOrbit(const bool & arg) {mouse.setCameraOrbit(arg);}
|
||||||
void setHoverHaloEnabled(const bool & arg) {hoverHalo_ = arg;}
|
void setHoverHaloEnabled(const bool & arg) {hoverHalo_ = arg;}
|
||||||
void setHoverHaloColor(const QColor & arg) {hoverHaloColor_ = arg;}
|
void setHoverHaloColor(const QColor & arg) {hoverHaloColor_ = arg;}
|
||||||
void setHoverHaloFillAlpha(const float & arg) {hoverHaloFill_ = arg;}
|
void setHoverHaloFillAlpha(const float & arg) {hoverHaloFill_ = arg;}
|
||||||
|
|||||||
@@ -291,7 +291,7 @@ void QGLViewWindow::on_actionArrow_triggered(bool on) {
|
|||||||
actionMove ->setChecked(false);
|
actionMove ->setChecked(false);
|
||||||
actionRotate->setChecked(false);
|
actionRotate->setChecked(false);
|
||||||
actionScale ->setChecked(false);
|
actionScale ->setChecked(false);
|
||||||
view->view()->setCurrentHadle(RendererService::htNoHandle);
|
view->view()->setCurrentAction(RendererService::haNoAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -300,7 +300,7 @@ void QGLViewWindow::on_actionMove_triggered(bool on) {
|
|||||||
actionMove ->setChecked(true);
|
actionMove ->setChecked(true);
|
||||||
actionRotate->setChecked(false);
|
actionRotate->setChecked(false);
|
||||||
actionScale ->setChecked(false);
|
actionScale ->setChecked(false);
|
||||||
view->view()->setCurrentHadle(RendererService::htMoveX);
|
view->view()->setCurrentAction(RendererService::haMove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -309,7 +309,7 @@ void QGLViewWindow::on_actionRotate_triggered(bool on) {
|
|||||||
actionMove ->setChecked(false);
|
actionMove ->setChecked(false);
|
||||||
actionRotate->setChecked(true);
|
actionRotate->setChecked(true);
|
||||||
actionScale ->setChecked(false);
|
actionScale ->setChecked(false);
|
||||||
view->view()->setCurrentHadle(RendererService::htRotateX);
|
view->view()->setCurrentAction(RendererService::haRotate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -318,5 +318,5 @@ void QGLViewWindow::on_actionScale_triggered(bool on) {
|
|||||||
actionMove ->setChecked(false);
|
actionMove ->setChecked(false);
|
||||||
actionRotate->setChecked(false);
|
actionRotate->setChecked(false);
|
||||||
actionScale ->setChecked(true);
|
actionScale ->setChecked(true);
|
||||||
view->view()->setCurrentHadle(RendererService::htScaleX);
|
view->view()->setCurrentAction(RendererService::haScale);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
class Renderer: public RendererBase {
|
class Renderer: public RendererBase {
|
||||||
friend class QGLView;
|
friend class QGLView;
|
||||||
|
friend class MouseController;
|
||||||
friend class RendererMaterial;
|
friend class RendererMaterial;
|
||||||
friend class RendererService;
|
friend class RendererService;
|
||||||
friend class RendererSelection;
|
friend class RendererSelection;
|
||||||
|
|||||||
@@ -88,23 +88,24 @@ void RendererSelection::fillSelectionsBuffer(bool yes, int size) {
|
|||||||
void RendererSelection::renderSelection(Scene & scene) {
|
void RendererSelection::renderSelection(Scene & scene) {
|
||||||
QOpenGLShaderProgram * prog = 0;
|
QOpenGLShaderProgram * prog = 0;
|
||||||
QGLView * view = r->view;
|
QGLView * view = r->view;
|
||||||
|
MouseController & mc(view->mouse);
|
||||||
if (r->bindShader(Renderer::srSelectionFill, &prog)) {
|
if (r->bindShader(Renderer::srSelectionFill, &prog)) {
|
||||||
view->hov_objects.clear();
|
mc.hov_objects.clear();
|
||||||
id_hover = 0;
|
id_hover = 0;
|
||||||
if (fbo_selection.queriedPoints() > 0) {
|
if (fbo_selection.queriedPoints() > 0) {
|
||||||
if (fbo_selection.queriedPoints() == 1) {
|
if (fbo_selection.queriedPoints() == 1) {
|
||||||
id_hover = fbo_selection.getPoint();
|
id_hover = fbo_selection.getPoint();
|
||||||
view->hov_objects.resize(1);
|
mc.hov_objects.resize(1);
|
||||||
view->hov_objects[0] = ids.value(id_hover);
|
mc.hov_objects[0] = ids.value(id_hover);
|
||||||
//qDebug() << id_hover;
|
//qDebug() << id_hover;
|
||||||
} else {
|
} else {
|
||||||
QVector<uint> points = fbo_selection.getPoints();
|
QVector<uint> points = fbo_selection.getPoints();
|
||||||
QSet<uint> ids_hover;
|
QSet<uint> ids_hover;
|
||||||
foreach (uint i, points)
|
foreach (uint i, points)
|
||||||
ids_hover << i;
|
ids_hover << i;
|
||||||
view->hov_objects.clear();
|
mc.hov_objects.clear();
|
||||||
foreach (uint i, ids_hover)
|
foreach (uint i, ids_hover)
|
||||||
view->hov_objects << ids.value(i);
|
mc.hov_objects << ids.value(i);
|
||||||
//qDebug() << ids_hover;
|
//qDebug() << ids_hover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,15 +126,7 @@ void RendererSelection::renderSelection(Scene & scene) {
|
|||||||
rs.omni_mesh->loadSelections(view, cur_selections_);
|
rs.omni_mesh->loadSelections(view, cur_selections_);
|
||||||
rs.omni_mesh->draw(view, rs.cur_objects.size());
|
rs.omni_mesh->draw(view, rs.cur_objects.size());
|
||||||
|
|
||||||
if (rs.fillCurrentHandleObjects()) {
|
rs.drawCurrentHandleObjects();
|
||||||
Mesh * hm = rs.currentHandleMesh();
|
|
||||||
if (hm) {
|
|
||||||
hm->loadObjects(view, rs.cur_objects);
|
|
||||||
fillSelectionsBuffer(false, 3);
|
|
||||||
hm->loadSelections(view, cur_selections_);
|
|
||||||
hm->draw(view, 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//mouse_rect = fbo_selection.rect();
|
//mouse_rect = fbo_selection.rect();
|
||||||
if (r->mouse_rect.isNull())
|
if (r->mouse_rect.isNull())
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
class RendererSelection {
|
class RendererSelection {
|
||||||
friend class QGLView;
|
friend class QGLView;
|
||||||
|
friend class MouseController;
|
||||||
friend class Renderer;
|
friend class Renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -29,17 +29,26 @@ using namespace QGLEngineShaders;
|
|||||||
|
|
||||||
RendererService::RendererService(Renderer * r_): r(r_) {
|
RendererService::RendererService(Renderer * r_): r(r_) {
|
||||||
line_width = 1;
|
line_width = 1;
|
||||||
current_handle = htNoHandle;
|
current_action = haNoAction;
|
||||||
mat_xyz.resize(3);
|
current_handle = 0;
|
||||||
color_xyz.resize(3);
|
mat_xyz.resize(3); mat_ms2.resize(3);
|
||||||
const QVector3D _rot[3] = {QVector3D(0,1,0), QVector3D(-1,0,0), QVector3D(0,0,1)};
|
color_xyz.resize(3); color_ms2.resize(3);
|
||||||
|
const QVector3D _rot [3] = {QVector3D(0,1,0), QVector3D(-1,0,0), QVector3D(0, 0,1)};
|
||||||
|
const QVector3D _rot2[3] = {QVector3D(0,0,0), QVector3D( 1,0,0), QVector3D(0,-1,0)};
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
QMatrix4x4 m;
|
QMatrix4x4 m;
|
||||||
m.rotate(90., _rot[i]);
|
m.rotate(90., _rot[i]);
|
||||||
mat_xyz[i] = m;
|
mat_xyz[i] = m;
|
||||||
color_xyz[i] = QVector4D(0,0,0,0.667);
|
m.setToIdentity();
|
||||||
|
if (!_rot2[i].isNull())
|
||||||
|
m.rotate(90., _rot2[i]);
|
||||||
|
mat_ms2[i] = m;
|
||||||
|
color_xyz[i] = color_ms2[i] = QVector4D(0,0,0,0.8);
|
||||||
color_xyz[i][i] = 1.;
|
color_xyz[i][i] = 1.;
|
||||||
}
|
}
|
||||||
|
color_ms2[0] = (color_xyz[0] + color_xyz[1]) / 2.;
|
||||||
|
color_ms2[1] = (color_xyz[0] + color_xyz[2]) / 2.;
|
||||||
|
color_ms2[2] = (color_xyz[1] + color_xyz[2]) / 2.;
|
||||||
axis_camera = new Camera();
|
axis_camera = new Camera();
|
||||||
axis_camera->setAim(QVector3D());
|
axis_camera->setAim(QVector3D());
|
||||||
axis_camera->setFOV(45.);
|
axis_camera->setFOV(45.);
|
||||||
@@ -53,20 +62,34 @@ RendererService::RendererService(Renderer * r_): r(r_) {
|
|||||||
omni_mesh_f->scalePoints(1.5);
|
omni_mesh_f->scalePoints(1.5);
|
||||||
box_mesh ->scalePoints(1.3);
|
box_mesh ->scalePoints(1.3);
|
||||||
omni_mesh ->scalePoints(1.3);
|
omni_mesh ->scalePoints(1.3);
|
||||||
handle_move_mesh = Primitive::arrow(12, 0.06);
|
|
||||||
|
handle_move_mesh = Primitive::arrow(12, 0.06);
|
||||||
|
handle_ms_2_mesh = Primitive::torus(8, 12, 0.5, 0.025, 90);
|
||||||
|
Mesh * m = Primitive::disc(8, 1., 1., true, 90);
|
||||||
|
handle_ms_2_mesh->append(m);
|
||||||
|
delete m;
|
||||||
|
m = Primitive::disc(8, 1., 1., false, 90);
|
||||||
|
handle_ms_2_mesh->append(m);
|
||||||
|
delete m;
|
||||||
|
|
||||||
handle_rotate_mesh = Primitive::arrow(12, 0.03);
|
handle_rotate_mesh = Primitive::arrow(12, 0.03);
|
||||||
Mesh * m = Primitive::torus(30, 12, 0.5, 0.06);
|
m = Primitive::torus(30, 12, 0.5, 0.06);
|
||||||
m->translatePoints(QVector3D(0., 0., 0.75));
|
m->translatePoints(QVector3D(0., 0., 0.75));
|
||||||
handle_rotate_mesh->append(m);
|
handle_rotate_mesh->append(m);
|
||||||
delete m;
|
delete m;
|
||||||
handle_scale_mesh = Primitive::cylinder(12, 0.06, 0.06, 0.85);
|
|
||||||
|
handle_scale_mesh = Primitive::cylinder(12, 0.06, 0.06, 0.85);
|
||||||
m = Primitive::ellipsoid(12, 12, 0.3, 0.3, 0.3);
|
m = Primitive::ellipsoid(12, 12, 0.3, 0.3, 0.3);
|
||||||
m->translatePoints(QVector3D(0., 0., 0.85));
|
m->translatePoints(QVector3D(0., 0., 0.85));
|
||||||
handle_scale_mesh->append(m);
|
handle_scale_mesh->append(m);
|
||||||
delete m;
|
delete m;
|
||||||
handle_move_mesh ->scalePoints(7.5);
|
handle_scale_3_mesh = Primitive::ellipsoid(12, 12, 0.4, 0.4, 0.4);
|
||||||
handle_rotate_mesh->scalePoints(7.5);
|
|
||||||
handle_scale_mesh ->scalePoints(7.5);
|
handle_move_mesh ->scalePoints(7.5);
|
||||||
|
handle_ms_2_mesh ->scalePoints(7.5);
|
||||||
|
handle_rotate_mesh ->scalePoints(7.5);
|
||||||
|
handle_scale_mesh ->scalePoints(7.5);
|
||||||
|
handle_scale_3_mesh ->scalePoints(7.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -78,8 +101,10 @@ RendererService::~RendererService() {
|
|||||||
delete axis_camera;
|
delete axis_camera;
|
||||||
delete axis_mesh;
|
delete axis_mesh;
|
||||||
delete handle_move_mesh;
|
delete handle_move_mesh;
|
||||||
|
delete handle_ms_2_mesh;
|
||||||
delete handle_rotate_mesh;
|
delete handle_rotate_mesh;
|
||||||
delete handle_scale_mesh;
|
delete handle_scale_mesh;
|
||||||
|
delete handle_scale_3_mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -130,42 +155,98 @@ void RendererService::fillOmniObjects() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RendererService::fillHandleObjects(QVector3D center, HandleType first, QMatrix4x4 add_mat) {
|
void RendererService::fillHandleObjects(QVector3D center, HandleMesh ids[], const QVector<QMatrix4x4> & mats, const QVector<QVector4D> & colors, QMatrix4x4 add_mat, int count) {
|
||||||
cur_objects.resize(3);
|
QMatrix4x4 m = invariantSizeMatrix(center) * add_mat;
|
||||||
for (int i = 0; i < 3; ++i) {
|
cur_objects.resize(count);
|
||||||
cur_objects[i].color = color_xyz[i];
|
for (int i = 0; i < count; ++i) {
|
||||||
QMatrix4x4 m = invariantSizeMatrix(center);
|
cur_objects[i].color = colors[i];
|
||||||
m = m * add_mat * mat_xyz[i];
|
QMatrix4x4 omat = m * mats[i];
|
||||||
cur_objects[i].object_id = first + i;
|
cur_objects[i].object_id = ids[i];
|
||||||
m.transposed().copyDataTo(cur_objects[i].modelmatrix);
|
if (current_handle.testFlag(ids[i])) {
|
||||||
|
cur_objects[i].color = QVector4D(0,1,1,1);
|
||||||
|
}
|
||||||
|
omat.transposed().copyDataTo(cur_objects[i].modelmatrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool RendererService::fillCurrentHandleObjects() {
|
bool RendererService::calculateCenter() {
|
||||||
QList<ObjectBase*> sol = r->view->scene()->selectedObjects(true);
|
QList<ObjectBase*> sol = r->view->scene()->selectedObjects(true);
|
||||||
if (sol.isEmpty()) return false;
|
if (sol.isEmpty()) return false;
|
||||||
selection_center = QVector3D();
|
selection_center = sol[0]->worldPos();
|
||||||
Box3D bb;
|
if (sol.size() > 1) {
|
||||||
foreach (ObjectBase * o, sol) {
|
Box3D bb;
|
||||||
o->calculateBoundingBox();
|
foreach (ObjectBase * o, sol) {
|
||||||
bb |= o->boundingBox();
|
o->calculateBoundingBox();
|
||||||
|
bb |= o->boundingBox();
|
||||||
|
}
|
||||||
|
if (!bb.isEmpty())
|
||||||
|
selection_center = bb.center();
|
||||||
}
|
}
|
||||||
if (bb.isEmpty())
|
|
||||||
selection_center = sol[0]->worldPos();
|
|
||||||
else
|
|
||||||
selection_center = bb.center();
|
|
||||||
axis_mat = QMatrix4x4();
|
axis_mat = QMatrix4x4();
|
||||||
if ((sol.size() == 1) && (current_handle >= htRotateX)) {
|
if ((sol.size() == 1) && (current_action != haMove)) {
|
||||||
axis_mat.rotate(sol[0]->angles_.z(), 0., 0., 1.);
|
ObjectBase * o = sol[0];
|
||||||
axis_mat.rotate(sol[0]->angles_.y(), 0., 1., 0.);
|
QMatrix4x4 pmat;
|
||||||
axis_mat.rotate(sol[0]->angles_.x(), 1., 0., 0.);
|
if (o->parent()) {
|
||||||
|
pmat = o->parent()->worldTransform();
|
||||||
|
pmat.setColumn(3, QVector4D(0,0,0,1));
|
||||||
|
double det = pmat.determinant();
|
||||||
|
if (det > 0.) pmat /= sqrt(det);
|
||||||
|
}
|
||||||
|
axis_mat.rotate(o->angles_.z(), 0., 0., 1.);
|
||||||
|
axis_mat.rotate(o->angles_.y(), 0., 1., 0.);
|
||||||
|
axis_mat.rotate(o->angles_.x(), 1., 0., 0.);
|
||||||
|
axis_mat = pmat * axis_mat;
|
||||||
}
|
}
|
||||||
fillHandleObjects(selection_center, current_handle, axis_mat);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RendererService::drawCurrentHandleObjects() {
|
||||||
|
if (current_action == haNoAction) return;
|
||||||
|
if (calculateCenter()) {
|
||||||
|
HandleMesh ids[3];
|
||||||
|
switch (current_action) {
|
||||||
|
case haMove : ids[0] = hmMoveX ; ids[1] = hmMoveY ; ids[2] = hmMoveZ ; break;
|
||||||
|
case haRotate: ids[0] = hmRotateX; ids[1] = hmRotateY; ids[2] = hmRotateZ; break;
|
||||||
|
case haScale : ids[0] = hmScaleX ; ids[1] = hmScaleY ; ids[2] = hmScaleZ ; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
fillHandleObjects(selection_center, ids, mat_xyz, color_xyz, axis_mat);
|
||||||
|
Mesh * hm = currentHandleMesh();
|
||||||
|
QVector<uchar> sel;
|
||||||
|
sel.fill(0, 3);
|
||||||
|
if (hm) {
|
||||||
|
hm->loadObjects(r->view, cur_objects);
|
||||||
|
hm->loadSelections(r->view, sel);
|
||||||
|
hm->draw(r->view, 3);
|
||||||
|
}
|
||||||
|
if (current_action == haMove || current_action == haScale) {
|
||||||
|
switch (current_action) {
|
||||||
|
case haMove : ids[0] = hmMoveXY ; ids[1] = hmMoveXZ ; ids[2] = hmMoveYZ ; break;
|
||||||
|
case haScale : ids[0] = hmScaleXY ; ids[1] = hmScaleXZ ; ids[2] = hmScaleYZ ; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
hm = handle_ms_2_mesh;
|
||||||
|
fillHandleObjects(selection_center, ids, mat_ms2, color_ms2, axis_mat);
|
||||||
|
hm->loadObjects(r->view, cur_objects);
|
||||||
|
hm->loadSelections(r->view, sel);
|
||||||
|
hm->draw(r->view, 3);
|
||||||
|
if (current_action == haScale) {
|
||||||
|
hm = handle_scale_3_mesh;
|
||||||
|
QVector<QMatrix4x4> mv; mv.resize(1);
|
||||||
|
QVector<QVector4D> cv; cv.fill(QVector4D(0.9, 0.9, 0.7, 1), 1);
|
||||||
|
ids[0] = hmMaxScale;
|
||||||
|
fillHandleObjects(selection_center, ids, mv, cv, axis_mat, 1);
|
||||||
|
hm->loadObjects(r->view, cur_objects);
|
||||||
|
hm->loadSelections(r->view, sel);
|
||||||
|
hm->draw(r->view, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void RendererService::setObjectsColor(QVector<Object> & ol, QColor col) {
|
void RendererService::setObjectsColor(QVector<Object> & ol, QColor col) {
|
||||||
QVector4D cv = QColor2QVector(col);
|
QVector4D cv = QColor2QVector(col);
|
||||||
for (int i = 0; i < ol.size(); ++i)
|
for (int i = 0; i < ol.size(); ++i)
|
||||||
@@ -210,16 +291,10 @@ void RendererService::renderService() {
|
|||||||
r->setUniformCamera(prog, r->view->camera());
|
r->setUniformCamera(prog, r->view->camera());
|
||||||
|
|
||||||
/// handles
|
/// handles
|
||||||
if (fillCurrentHandleObjects()) {
|
f->glEnable(GL_BLEND);
|
||||||
f->glEnable(GL_BLEND);
|
f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
drawCurrentHandleObjects();
|
||||||
Mesh * hm = currentHandleMesh();
|
f->glDisable(GL_BLEND);
|
||||||
if (hm) {
|
|
||||||
hm->loadObjects(r->view, cur_objects);
|
|
||||||
hm->draw(f, 3);
|
|
||||||
}
|
|
||||||
f->glDisable(GL_BLEND);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// axis
|
/// axis
|
||||||
f->glViewport(0, 0, axis_viewport.width(), axis_viewport.height());
|
f->glViewport(0, 0, axis_viewport.width(), axis_viewport.height());
|
||||||
@@ -234,16 +309,10 @@ void RendererService::renderService() {
|
|||||||
|
|
||||||
|
|
||||||
Mesh * RendererService::currentHandleMesh() {
|
Mesh * RendererService::currentHandleMesh() {
|
||||||
switch (current_handle) {
|
switch (current_action) {
|
||||||
case htMoveX :
|
case haMove : return handle_move_mesh;
|
||||||
case htMoveY :
|
case haRotate: return handle_rotate_mesh;
|
||||||
case htMoveZ : return handle_move_mesh;
|
case haScale : return handle_scale_mesh;
|
||||||
case htRotateX:
|
|
||||||
case htRotateY:
|
|
||||||
case htRotateZ: return handle_rotate_mesh;
|
|
||||||
case htScaleX :
|
|
||||||
case htScaleY :
|
|
||||||
case htScaleZ : return handle_scale_mesh;
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
class RendererService {
|
class RendererService {
|
||||||
friend class QGLView;
|
friend class QGLView;
|
||||||
|
friend class MouseController;
|
||||||
friend class Renderer;
|
friend class Renderer;
|
||||||
friend class RendererSelection;
|
friend class RendererSelection;
|
||||||
|
|
||||||
@@ -33,17 +34,32 @@ public:
|
|||||||
RendererService(Renderer * r_);
|
RendererService(Renderer * r_);
|
||||||
virtual ~RendererService();
|
virtual ~RendererService();
|
||||||
|
|
||||||
enum HandleType {
|
enum HandleAction {
|
||||||
htNoHandle,
|
haNoAction,
|
||||||
htMoveX,
|
haMove,
|
||||||
htMoveY,
|
haRotate,
|
||||||
htMoveZ,
|
haScale,
|
||||||
htRotateX,
|
};
|
||||||
htRotateY,
|
|
||||||
htRotateZ,
|
enum HandleMesh {
|
||||||
htScaleX,
|
hmMoveX = 0x01,
|
||||||
htScaleY,
|
hmMoveY = 0x02,
|
||||||
htScaleZ,
|
hmMoveZ = 0x04,
|
||||||
|
hmMoveXY = hmMoveX | hmMoveY,
|
||||||
|
hmMoveXZ = hmMoveX | hmMoveZ,
|
||||||
|
hmMoveYZ = hmMoveY | hmMoveZ,
|
||||||
|
hmMaxMove = hmMoveX | hmMoveY | hmMoveZ,
|
||||||
|
hmRotateX = 0x08,
|
||||||
|
hmRotateY = 0x10,
|
||||||
|
hmRotateZ = 0x20,
|
||||||
|
hmMaxRotate = hmRotateX | hmRotateY | hmRotateZ,
|
||||||
|
hmScaleX = 0x40,
|
||||||
|
hmScaleY = 0x80,
|
||||||
|
hmScaleZ = 0x100,
|
||||||
|
hmScaleXY = hmScaleX | hmScaleY,
|
||||||
|
hmScaleXZ = hmScaleX | hmScaleZ,
|
||||||
|
hmScaleYZ = hmScaleY | hmScaleZ,
|
||||||
|
hmMaxScale = hmScaleX | hmScaleY | hmScaleZ,
|
||||||
};
|
};
|
||||||
|
|
||||||
void init(int width, int height);
|
void init(int width, int height);
|
||||||
@@ -52,26 +68,29 @@ public:
|
|||||||
QMatrix4x4 invariantSizeMatrix(QVector3D p);
|
QMatrix4x4 invariantSizeMatrix(QVector3D p);
|
||||||
void fillXYZObjects();
|
void fillXYZObjects();
|
||||||
void fillOmniObjects();
|
void fillOmniObjects();
|
||||||
void fillHandleObjects(QVector3D center, HandleType first, QMatrix4x4 add_mat);
|
void fillHandleObjects(QVector3D center, HandleMesh ids[], const QVector<QMatrix4x4> & mats, const QVector<QVector4D> & colors, QMatrix4x4 add_mat, int count = 3);
|
||||||
bool fillCurrentHandleObjects();
|
bool calculateCenter();
|
||||||
|
void drawCurrentHandleObjects();
|
||||||
void setObjectsColor(QVector<QGLEngineShaders::Object> & ol, QColor col);
|
void setObjectsColor(QVector<QGLEngineShaders::Object> & ol, QColor col);
|
||||||
void renderService();
|
void renderService();
|
||||||
void setCurrentHadle(HandleType ht) {current_handle = ht;}
|
void setCurrentAction(HandleAction ha) {current_action = ha;}
|
||||||
Mesh * currentHandleMesh();
|
Mesh * currentHandleMesh();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Renderer * r;
|
Renderer * r;
|
||||||
|
|
||||||
Mesh * axis_mesh, * handle_move_mesh, * handle_rotate_mesh, * handle_scale_mesh;
|
Mesh * axis_mesh, * handle_move_mesh, * handle_rotate_mesh, * handle_scale_mesh;
|
||||||
|
Mesh * handle_ms_2_mesh, * handle_scale_3_mesh;
|
||||||
Mesh * box_mesh_f, * omni_mesh_f, * box_mesh, * omni_mesh;
|
Mesh * box_mesh_f, * omni_mesh_f, * box_mesh, * omni_mesh;
|
||||||
QMatrix4x4 v_mat, axis_mat;
|
QMatrix4x4 v_mat, axis_mat;
|
||||||
QVector3D selection_center;
|
QVector3D selection_center;
|
||||||
QVector<QMatrix4x4> mat_xyz;
|
QVector<QMatrix4x4> mat_xyz, mat_ms2;
|
||||||
QVector<QVector4D> color_xyz;
|
QVector<QVector4D> color_xyz, color_ms2;
|
||||||
QVector<QGLEngineShaders::Object> cur_objects;
|
QVector<QGLEngineShaders::Object> cur_objects;
|
||||||
Camera * axis_camera;
|
Camera * axis_camera;
|
||||||
QSize axis_viewport;
|
QSize axis_viewport;
|
||||||
HandleType current_handle;
|
HandleAction current_action;
|
||||||
|
QFlags<HandleMesh> current_handle;
|
||||||
int line_width;
|
int line_width;
|
||||||
double size_vp_scale, size_full_scale;
|
double size_vp_scale, size_full_scale;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user