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) {
|
||||
if (vertices_.isEmpty()) return;
|
||||
int vcnt = vertices_.size();
|
||||
for (int i = 0; i < vcnt; ++i) {
|
||||
vertices_[i] += dp;
|
||||
}
|
||||
changed = hash_changed = true;
|
||||
QMatrix4x4 m;
|
||||
m.translate(dp);
|
||||
transformPoints(m);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
int vcnt = vertices_.size();
|
||||
int vcnt = vertices_.size(), ncnt = normals_.size();
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -62,8 +62,12 @@ public:
|
||||
QVector< Vector2i> & indicesLines () {changed = hash_changed = true; return lines_;}
|
||||
|
||||
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 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);
|
||||
|
||||
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();
|
||||
QVector<QVector3D> & v(ret->vertices ());
|
||||
QVector<QVector3D> & n(ret->normals ());
|
||||
@@ -137,8 +137,9 @@ Mesh * Primitive::disc(int segments, float width, float length, bool up) {
|
||||
QVector3D cp;
|
||||
v << QVector3D();
|
||||
t << QVector2D(0.5f, 0.5f);
|
||||
end_angle *= deg2rad;
|
||||
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.setY(width / 2. * sin(a));
|
||||
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();
|
||||
QVector<QVector3D> & v(ret->vertices ());
|
||||
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++) {
|
||||
double x = (double)i / (segments_main - 1);
|
||||
QMatrix4x4 rm;
|
||||
rm.rotate(x * 360., 0., 0., 1.);
|
||||
rm.rotate(x * end_angle, 0., 0., 1.);
|
||||
for (int j = 0; j < ccnt; j++) {
|
||||
ct[j].setX(x);
|
||||
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 * 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.);
|
||||
|
||||
@@ -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 * 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.);
|
||||
|
||||
@@ -205,6 +205,7 @@ void Scene::selectObjects(QList<ObjectBase *> ol, bool add_to_selection) {
|
||||
|
||||
void Scene::clearSelection() {
|
||||
selected_.clear();
|
||||
selected_top.clear();
|
||||
QList<ObjectBase * > ol = root_->children(true);
|
||||
foreach (ObjectBase * o, ol) {
|
||||
o->selected_ = false;
|
||||
@@ -412,13 +413,14 @@ bool Scene::prepare() {
|
||||
|
||||
|
||||
void Scene::destroy() {
|
||||
selected_.clear();
|
||||
selected_top.clear();
|
||||
emitSelectionChanged();
|
||||
root_->clearChildren(true);
|
||||
qDeleteAll(geometries);
|
||||
qDeleteAll(materials);
|
||||
geometries.clear();
|
||||
materials.clear();
|
||||
selected_.clear();
|
||||
selected_top.clear();
|
||||
emit __destroyed();
|
||||
emit treeChanged();
|
||||
}
|
||||
|
||||
@@ -163,6 +163,7 @@ QImage rotateQImageRight(const QImage & im);
|
||||
inline QImage rotateQImage180(const QImage & im) {return im.mirrored(true, true);}
|
||||
|
||||
class QGLView;
|
||||
class MouseController;
|
||||
class ObjectBase;
|
||||
class Light;
|
||||
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;
|
||||
|
||||
|
||||
QGLView::QGLView(): OpenGLWindow(), renderer_(this) {
|
||||
QGLView::QGLView(): OpenGLWindow(), renderer_(this), mouse(this) {
|
||||
setIcon(QIcon(":/icons/qglview.png"));
|
||||
deleting_ = false;
|
||||
timer = 0;
|
||||
app_scale = 1;
|
||||
cur_handle = RendererService::htNoHandle;
|
||||
need_init_ = is_first_draw = true;
|
||||
backColor_ = Qt::darkGray;
|
||||
hoverHaloColor_ = QColor(195, 140, 255);
|
||||
selectionHaloColor_ = QColor(175, 255, 140);
|
||||
ambientColor_ = QColor(10, 10, 10);
|
||||
lastPos = QPoint(-1, -1);
|
||||
lineWidth_ = 1.;
|
||||
max_anisotropic = 1;
|
||||
max_texture_chanels = 8;
|
||||
cameraOrbit_ = lightEnabled_ = canSelect_ = true;
|
||||
shaders_supported = selecting_ = customMouseMove_ = false;
|
||||
sel_button = Qt::LeftButton;
|
||||
sel_mod = Qt::ControlModifier;
|
||||
lightEnabled_ = true;
|
||||
shaders_supported = false;
|
||||
fps_cnt = 0;
|
||||
fps_tm = fps_ = 0.;
|
||||
fogDensity_ = fogEnd_ = 1.;
|
||||
@@ -77,9 +72,8 @@ QGLView::QGLView(): OpenGLWindow(), renderer_(this) {
|
||||
setFeature(qglDepthOfFieldAutoFocusSpeed, 0.1);
|
||||
setFeature(qglDepthOfFieldFocus, 1.);
|
||||
setFeature(qglDepthOfFieldDiaphragm, 8.);
|
||||
mouse_first = mouseSelect_ = hoverHalo_ = selectionHalo_ = true;
|
||||
mouseRotate_ = true;
|
||||
fogEnabled_ = is_init = grabMouse_ = shaders_bind = changed_ = false;
|
||||
hoverHalo_ = selectionHalo_ = true;
|
||||
fogEnabled_ = is_init = shaders_bind = changed_ = false;
|
||||
rmode = ObjectBase::Fill;
|
||||
// sel_pen = QPen(Qt::black, 1, Qt::DashLine);
|
||||
// sel_brush = QBrush(QColor(170, 100, 255, 120));
|
||||
@@ -94,7 +88,10 @@ QGLView::QGLView(): OpenGLWindow(), renderer_(this) {
|
||||
//camera().aim_ = camera().pos_;
|
||||
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);
|
||||
o->setColor(Qt::cyan);
|
||||
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) {
|
||||
renderLater();
|
||||
app_scale = appScale();
|
||||
mouse.resize();
|
||||
}
|
||||
|
||||
|
||||
@@ -211,7 +178,7 @@ void QGLView::checkCaps() {
|
||||
|
||||
void QGLView::__destroyed() {
|
||||
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);
|
||||
aspect = float(width) / float(height);
|
||||
renderer_.resize(width, height);
|
||||
mouse_first = true;
|
||||
//qDebug() << "resize" << width << height;
|
||||
iaspect = (aspect == 0.f) ? 0. : 1 / aspect;
|
||||
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) {
|
||||
emit glKeyPressEvent(e);
|
||||
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) {
|
||||
if (bb.isEmpty() || !camera()) return;
|
||||
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() {
|
||||
ChunkStream cs;
|
||||
const Camera * c = camera();
|
||||
@@ -503,14 +261,3 @@ void QGLView::restoreFeatures(const QByteArray & ba) {
|
||||
ds >> 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 "glrendererbase.h"
|
||||
#include "renderer.h"
|
||||
#include "mouse_controller.h"
|
||||
#include <QTime>
|
||||
|
||||
|
||||
class QGLView: public OpenGLWindow
|
||||
{
|
||||
friend class MouseController;
|
||||
friend class GLRendererBase;
|
||||
friend class TextureManager;
|
||||
friend class ObjectBase;
|
||||
@@ -117,10 +119,10 @@ public:
|
||||
float fogEnd() const {return fogEnd_;}
|
||||
bool isFogEnabled() const {return fogEnabled_;}
|
||||
bool isLightEnabled() const {return lightEnabled_;}
|
||||
bool isGrabMouseEnabled() const {return grabMouse_;}
|
||||
bool isMouseRotateEnabled() const {return mouseRotate_;}
|
||||
bool isMouseSelectionEnabled() const {return mouseSelect_;}
|
||||
bool isCameraOrbit() const {return cameraOrbit_;}
|
||||
bool isGrabMouseEnabled() const {return mouse.isGrabMouseEnabled();}
|
||||
bool isMouseRotateEnabled() const {return mouse.isMouseRotateEnabled();}
|
||||
bool isMouseSelectionEnabled() const {return mouse.isMouseSelectionEnabled();}
|
||||
bool isCameraOrbit() const {return mouse.isCameraOrbit();}
|
||||
bool isHoverHaloEnabled() const {return hoverHalo_;}
|
||||
QColor hoverHaloColor() const {return hoverHaloColor_;}
|
||||
float hoverHaloFillAlpha() const {return hoverHaloFill_;}
|
||||
@@ -137,37 +139,37 @@ public:
|
||||
|
||||
// void addObject(GLObjectBase & o) {addObject(&o);}
|
||||
|
||||
Scene::SelectionMode selectionMode() const;
|
||||
Qt::MouseButton selectionButton() const {return sel_button;}
|
||||
Qt::KeyboardModifier selectionModifier() const {return sel_mod;}
|
||||
Scene::SelectionMode selectionMode() const {return scene_->selectionMode();}
|
||||
Qt::MouseButton selectionButton() const {return mouse.selectionButton();}
|
||||
Qt::KeyboardModifier selectionModifier() const {return mouse.selectionModifier();}
|
||||
|
||||
void setSelectionMode(Scene::SelectionMode m);
|
||||
void setSelectionButton(Qt::MouseButton v) {sel_button = v;}
|
||||
void setSelectionModifier(Qt::KeyboardModifier v) {sel_mod = v;}
|
||||
void setSelectionMode(Scene::SelectionMode m) {scene_->setSelectionMode(m);}
|
||||
void setSelectionButton(Qt::MouseButton v) {mouse.setSelectionButton(v);}
|
||||
void setSelectionModifier(Qt::KeyboardModifier v) {mouse.setSelectionModifier(v);}
|
||||
|
||||
void selectObject(ObjectBase * o, bool add_to_selection = false);
|
||||
void clearSelection();
|
||||
QList<ObjectBase * > selectedObjects() const;
|
||||
ObjectBase * selectedObject() const;
|
||||
void selectObject(ObjectBase * o, bool add_to_selection = false) {scene_->selectObject(o, add_to_selection);}
|
||||
void clearSelection() {scene_->clearSelection();}
|
||||
QList<ObjectBase * > selectedObjects() const {return scene_->selectedObjects();}
|
||||
ObjectBase * selectedObject() const {return scene_->selectedObject();}
|
||||
|
||||
TextureManager * textureManager();
|
||||
void reloadTextures();
|
||||
TextureManager * textureManager() {return renderer_.textures_manager;}
|
||||
void reloadTextures() {renderer_.markReloadTextures();}
|
||||
|
||||
Scene * scene() {return scene_;}
|
||||
void focusOn(const Box3D & bb);
|
||||
void setCameraLightOn(bool on);
|
||||
bool isCameraLightOn() const;
|
||||
void setCameraLightOn(bool on) {renderer_.setCameraLightOn(on);}
|
||||
bool isCameraLightOn() const {return renderer_.isCameraLightOn();}
|
||||
|
||||
Camera * camera();
|
||||
const Camera * camera() const;
|
||||
void setCamera(Camera * camera);
|
||||
Camera * camera() {return camera_;}
|
||||
const Camera * camera() const {return camera_;}
|
||||
void setCamera(Camera * camera) {camera_ = camera;}
|
||||
QByteArray saveCamera();
|
||||
void restoreCamera(const QByteArray & ba);
|
||||
QByteArray saveFeatures();
|
||||
void restoreFeatures(const QByteArray & ba);
|
||||
|
||||
QImage materialThumbnail(Material * m);
|
||||
void setCurrentHadle(RendererService::HandleType ht);
|
||||
QImage materialThumbnail(Material * m) {return renderer_.materialThumbnail(m);}
|
||||
void setCurrentAction(RendererService::HandleAction ha) {renderer_.rend_service.setCurrentAction(ha);}
|
||||
|
||||
|
||||
GLfloat aspect, iaspect;
|
||||
@@ -180,12 +182,12 @@ protected:
|
||||
void timerEvent(QTimerEvent * );
|
||||
void initialize();
|
||||
void resizeGL(int width, int height);
|
||||
void mousePressEvent(QMouseEvent * e);
|
||||
void mouseMoveEvent(QMouseEvent * e);
|
||||
void mouseReleaseEvent(QMouseEvent * e);
|
||||
void wheelEvent(QWheelEvent * e);
|
||||
void mousePressEvent(QMouseEvent * e) {mouse.mousePressEvent(e);}
|
||||
void mouseMoveEvent(QMouseEvent * e) {mouse.mouseMoveEvent(e);}
|
||||
void mouseReleaseEvent(QMouseEvent * e) {mouse.mouseReleaseEvent(e);}
|
||||
void wheelEvent(QWheelEvent * e) {mouse.wheelEvent(e);}
|
||||
void mouseDoubleClickEvent(QMouseEvent * e) {mouse.mouseDoubleClickEvent(e);}
|
||||
void leaveEvent(QEvent * );
|
||||
void mouseDoubleClickEvent(QMouseEvent * e);
|
||||
|
||||
void keyPressEvent(QKeyEvent * e);
|
||||
void keyReleaseEvent(QKeyEvent * e);
|
||||
@@ -199,28 +201,24 @@ private:
|
||||
void processKeys();
|
||||
bool setupViewport();
|
||||
|
||||
QPoint lastPos, downPos;
|
||||
Scene * scene_;
|
||||
Camera * camera_;
|
||||
MouseController mouse;
|
||||
// uint cid;
|
||||
QSet<int> keys_;
|
||||
QColor backColor_, fogColor_, ambientColor_, hoverHaloColor_, selectionHaloColor_;
|
||||
QTime time, ktm_;
|
||||
GLint max_anisotropic, max_texture_chanels;
|
||||
ObjectBase::RenderMode rmode;
|
||||
QVector<ObjectBase * > hov_objects;
|
||||
Qt::MouseButton sel_button;
|
||||
Qt::KeyboardModifier sel_mod;
|
||||
GLRendererBase::RenderingParameters start_rp;
|
||||
RendererService::HandleType cur_handle;
|
||||
QHash<int, QVariant> features_;
|
||||
QSize prev_size;
|
||||
float lineWidth_, app_scale;
|
||||
float lineWidth_;
|
||||
float fogDensity_, fogStart_, fogEnd_, fps_, fps_tm, hoverHaloFill_, selectionHaloFill_, m_motionBlurFactor;
|
||||
int timer, fps_cnt, sh_id_loc, deleting_;
|
||||
bool is_first_draw, is_init, fogEnabled_, lightEnabled_, grabMouse_, mouse_first, mouseRotate_, mouseSelect_, customMouseMove_, canSelect_;
|
||||
bool shaders_supported, changed_, cameraOrbit_, need_init_;
|
||||
bool hoverHalo_, selectionHalo_, shaders_bind, selecting_;
|
||||
bool is_first_draw, is_init, fogEnabled_, lightEnabled_;
|
||||
bool shaders_supported, changed_, need_init_;
|
||||
bool hoverHalo_, selectionHalo_, shaders_bind;
|
||||
|
||||
private slots:
|
||||
void __destroyed();
|
||||
@@ -238,11 +236,11 @@ public slots:
|
||||
void setFogEnd(const float & arg) {fogEnd_ = arg;}
|
||||
void setFogEnabled(const bool & arg) {fogEnabled_ = arg;}
|
||||
void setLightEnabled(const bool & arg) {lightEnabled_ = arg;}
|
||||
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;}
|
||||
void setGrabMouseEnabled(const bool & arg) {mouse.setGrabMouseEnabled(arg);}
|
||||
void setMouseRotateEnabled(const bool & arg) {mouse.setMouseRotateEnabled(arg);}
|
||||
void setMouseSelectionEnabled(const bool & arg) {mouse.setMouseSelectionEnabled(arg);}
|
||||
void setCustomMouseMove(const bool & arg) {mouse.setCustomMouseMove(arg);}
|
||||
void setCameraOrbit(const bool & arg) {mouse.setCameraOrbit(arg);}
|
||||
void setHoverHaloEnabled(const bool & arg) {hoverHalo_ = arg;}
|
||||
void setHoverHaloColor(const QColor & arg) {hoverHaloColor_ = arg;}
|
||||
void setHoverHaloFillAlpha(const float & arg) {hoverHaloFill_ = arg;}
|
||||
|
||||
@@ -291,7 +291,7 @@ void QGLViewWindow::on_actionArrow_triggered(bool on) {
|
||||
actionMove ->setChecked(false);
|
||||
actionRotate->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);
|
||||
actionRotate->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);
|
||||
actionRotate->setChecked(true);
|
||||
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);
|
||||
actionRotate->setChecked(false);
|
||||
actionScale ->setChecked(true);
|
||||
view->view()->setCurrentHadle(RendererService::htScaleX);
|
||||
view->view()->setCurrentAction(RendererService::haScale);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
class Renderer: public RendererBase {
|
||||
friend class QGLView;
|
||||
friend class MouseController;
|
||||
friend class RendererMaterial;
|
||||
friend class RendererService;
|
||||
friend class RendererSelection;
|
||||
|
||||
@@ -88,23 +88,24 @@ void RendererSelection::fillSelectionsBuffer(bool yes, int size) {
|
||||
void RendererSelection::renderSelection(Scene & scene) {
|
||||
QOpenGLShaderProgram * prog = 0;
|
||||
QGLView * view = r->view;
|
||||
MouseController & mc(view->mouse);
|
||||
if (r->bindShader(Renderer::srSelectionFill, &prog)) {
|
||||
view->hov_objects.clear();
|
||||
mc.hov_objects.clear();
|
||||
id_hover = 0;
|
||||
if (fbo_selection.queriedPoints() > 0) {
|
||||
if (fbo_selection.queriedPoints() == 1) {
|
||||
id_hover = fbo_selection.getPoint();
|
||||
view->hov_objects.resize(1);
|
||||
view->hov_objects[0] = ids.value(id_hover);
|
||||
mc.hov_objects.resize(1);
|
||||
mc.hov_objects[0] = ids.value(id_hover);
|
||||
//qDebug() << id_hover;
|
||||
} else {
|
||||
QVector<uint> points = fbo_selection.getPoints();
|
||||
QSet<uint> ids_hover;
|
||||
foreach (uint i, points)
|
||||
ids_hover << i;
|
||||
view->hov_objects.clear();
|
||||
mc.hov_objects.clear();
|
||||
foreach (uint i, ids_hover)
|
||||
view->hov_objects << ids.value(i);
|
||||
mc.hov_objects << ids.value(i);
|
||||
//qDebug() << ids_hover;
|
||||
}
|
||||
}
|
||||
@@ -125,15 +126,7 @@ void RendererSelection::renderSelection(Scene & scene) {
|
||||
rs.omni_mesh->loadSelections(view, cur_selections_);
|
||||
rs.omni_mesh->draw(view, rs.cur_objects.size());
|
||||
|
||||
if (rs.fillCurrentHandleObjects()) {
|
||||
Mesh * hm = rs.currentHandleMesh();
|
||||
if (hm) {
|
||||
hm->loadObjects(view, rs.cur_objects);
|
||||
fillSelectionsBuffer(false, 3);
|
||||
hm->loadSelections(view, cur_selections_);
|
||||
hm->draw(view, 3);
|
||||
}
|
||||
}
|
||||
rs.drawCurrentHandleObjects();
|
||||
|
||||
//mouse_rect = fbo_selection.rect();
|
||||
if (r->mouse_rect.isNull())
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
class RendererSelection {
|
||||
friend class QGLView;
|
||||
friend class MouseController;
|
||||
friend class Renderer;
|
||||
|
||||
public:
|
||||
|
||||
@@ -29,17 +29,26 @@ using namespace QGLEngineShaders;
|
||||
|
||||
RendererService::RendererService(Renderer * r_): r(r_) {
|
||||
line_width = 1;
|
||||
current_handle = htNoHandle;
|
||||
mat_xyz.resize(3);
|
||||
color_xyz.resize(3);
|
||||
const QVector3D _rot[3] = {QVector3D(0,1,0), QVector3D(-1,0,0), QVector3D(0,0,1)};
|
||||
current_action = haNoAction;
|
||||
current_handle = 0;
|
||||
mat_xyz.resize(3); mat_ms2.resize(3);
|
||||
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) {
|
||||
QMatrix4x4 m;
|
||||
m.rotate(90., _rot[i]);
|
||||
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_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->setAim(QVector3D());
|
||||
axis_camera->setFOV(45.);
|
||||
@@ -53,20 +62,34 @@ RendererService::RendererService(Renderer * r_): r(r_) {
|
||||
omni_mesh_f->scalePoints(1.5);
|
||||
box_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);
|
||||
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));
|
||||
handle_rotate_mesh->append(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->translatePoints(QVector3D(0., 0., 0.85));
|
||||
handle_scale_mesh->append(m);
|
||||
delete m;
|
||||
handle_move_mesh ->scalePoints(7.5);
|
||||
handle_rotate_mesh->scalePoints(7.5);
|
||||
handle_scale_mesh ->scalePoints(7.5);
|
||||
handle_scale_3_mesh = Primitive::ellipsoid(12, 12, 0.4, 0.4, 0.4);
|
||||
|
||||
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_mesh;
|
||||
delete handle_move_mesh;
|
||||
delete handle_ms_2_mesh;
|
||||
delete handle_rotate_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) {
|
||||
cur_objects.resize(3);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
cur_objects[i].color = color_xyz[i];
|
||||
QMatrix4x4 m = invariantSizeMatrix(center);
|
||||
m = m * add_mat * mat_xyz[i];
|
||||
cur_objects[i].object_id = first + i;
|
||||
m.transposed().copyDataTo(cur_objects[i].modelmatrix);
|
||||
void RendererService::fillHandleObjects(QVector3D center, HandleMesh ids[], const QVector<QMatrix4x4> & mats, const QVector<QVector4D> & colors, QMatrix4x4 add_mat, int count) {
|
||||
QMatrix4x4 m = invariantSizeMatrix(center) * add_mat;
|
||||
cur_objects.resize(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
cur_objects[i].color = colors[i];
|
||||
QMatrix4x4 omat = m * mats[i];
|
||||
cur_objects[i].object_id = ids[i];
|
||||
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);
|
||||
if (sol.isEmpty()) return false;
|
||||
selection_center = QVector3D();
|
||||
Box3D bb;
|
||||
foreach (ObjectBase * o, sol) {
|
||||
o->calculateBoundingBox();
|
||||
bb |= o->boundingBox();
|
||||
selection_center = sol[0]->worldPos();
|
||||
if (sol.size() > 1) {
|
||||
Box3D bb;
|
||||
foreach (ObjectBase * o, sol) {
|
||||
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();
|
||||
if ((sol.size() == 1) && (current_handle >= htRotateX)) {
|
||||
axis_mat.rotate(sol[0]->angles_.z(), 0., 0., 1.);
|
||||
axis_mat.rotate(sol[0]->angles_.y(), 0., 1., 0.);
|
||||
axis_mat.rotate(sol[0]->angles_.x(), 1., 0., 0.);
|
||||
if ((sol.size() == 1) && (current_action != haMove)) {
|
||||
ObjectBase * o = sol[0];
|
||||
QMatrix4x4 pmat;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
QVector4D cv = QColor2QVector(col);
|
||||
for (int i = 0; i < ol.size(); ++i)
|
||||
@@ -210,16 +291,10 @@ void RendererService::renderService() {
|
||||
r->setUniformCamera(prog, r->view->camera());
|
||||
|
||||
/// handles
|
||||
if (fillCurrentHandleObjects()) {
|
||||
f->glEnable(GL_BLEND);
|
||||
f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
Mesh * hm = currentHandleMesh();
|
||||
if (hm) {
|
||||
hm->loadObjects(r->view, cur_objects);
|
||||
hm->draw(f, 3);
|
||||
}
|
||||
f->glDisable(GL_BLEND);
|
||||
}
|
||||
f->glEnable(GL_BLEND);
|
||||
f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
drawCurrentHandleObjects();
|
||||
f->glDisable(GL_BLEND);
|
||||
|
||||
/// axis
|
||||
f->glViewport(0, 0, axis_viewport.width(), axis_viewport.height());
|
||||
@@ -234,16 +309,10 @@ void RendererService::renderService() {
|
||||
|
||||
|
||||
Mesh * RendererService::currentHandleMesh() {
|
||||
switch (current_handle) {
|
||||
case htMoveX :
|
||||
case htMoveY :
|
||||
case htMoveZ : return handle_move_mesh;
|
||||
case htRotateX:
|
||||
case htRotateY:
|
||||
case htRotateZ: return handle_rotate_mesh;
|
||||
case htScaleX :
|
||||
case htScaleY :
|
||||
case htScaleZ : return handle_scale_mesh;
|
||||
switch (current_action) {
|
||||
case haMove : return handle_move_mesh;
|
||||
case haRotate: return handle_rotate_mesh;
|
||||
case haScale : return handle_scale_mesh;
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
class RendererService {
|
||||
friend class QGLView;
|
||||
friend class MouseController;
|
||||
friend class Renderer;
|
||||
friend class RendererSelection;
|
||||
|
||||
@@ -33,17 +34,32 @@ public:
|
||||
RendererService(Renderer * r_);
|
||||
virtual ~RendererService();
|
||||
|
||||
enum HandleType {
|
||||
htNoHandle,
|
||||
htMoveX,
|
||||
htMoveY,
|
||||
htMoveZ,
|
||||
htRotateX,
|
||||
htRotateY,
|
||||
htRotateZ,
|
||||
htScaleX,
|
||||
htScaleY,
|
||||
htScaleZ,
|
||||
enum HandleAction {
|
||||
haNoAction,
|
||||
haMove,
|
||||
haRotate,
|
||||
haScale,
|
||||
};
|
||||
|
||||
enum HandleMesh {
|
||||
hmMoveX = 0x01,
|
||||
hmMoveY = 0x02,
|
||||
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);
|
||||
@@ -52,26 +68,29 @@ public:
|
||||
QMatrix4x4 invariantSizeMatrix(QVector3D p);
|
||||
void fillXYZObjects();
|
||||
void fillOmniObjects();
|
||||
void fillHandleObjects(QVector3D center, HandleType first, QMatrix4x4 add_mat);
|
||||
bool fillCurrentHandleObjects();
|
||||
void fillHandleObjects(QVector3D center, HandleMesh ids[], const QVector<QMatrix4x4> & mats, const QVector<QVector4D> & colors, QMatrix4x4 add_mat, int count = 3);
|
||||
bool calculateCenter();
|
||||
void drawCurrentHandleObjects();
|
||||
void setObjectsColor(QVector<QGLEngineShaders::Object> & ol, QColor col);
|
||||
void renderService();
|
||||
void setCurrentHadle(HandleType ht) {current_handle = ht;}
|
||||
void setCurrentAction(HandleAction ha) {current_action = ha;}
|
||||
Mesh * currentHandleMesh();
|
||||
|
||||
private:
|
||||
Renderer * r;
|
||||
|
||||
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;
|
||||
QMatrix4x4 v_mat, axis_mat;
|
||||
QVector3D selection_center;
|
||||
QVector<QMatrix4x4> mat_xyz;
|
||||
QVector<QVector4D> color_xyz;
|
||||
QVector<QMatrix4x4> mat_xyz, mat_ms2;
|
||||
QVector<QVector4D> color_xyz, color_ms2;
|
||||
QVector<QGLEngineShaders::Object> cur_objects;
|
||||
Camera * axis_camera;
|
||||
QSize axis_viewport;
|
||||
HandleType current_handle;
|
||||
HandleAction current_action;
|
||||
QFlags<HandleMesh> current_handle;
|
||||
int line_width;
|
||||
double size_vp_scale, size_full_scale;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user