git-svn-id: svn://db.shs.com.ru/libs@631 a8b55f48-bf90-11e4-a774-851b48703e85

This commit is contained in:
2019-11-26 21:20:59 +00:00
parent 9059a17cd0
commit 5eaf516eae
16 changed files with 615 additions and 411 deletions

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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]);

View File

@@ -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.);

View File

@@ -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();
}

View File

@@ -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;

View 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();
}

View 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

View File

@@ -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);
}

View File

@@ -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;}

View File

@@ -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);
}

View File

@@ -28,6 +28,7 @@
class Renderer: public RendererBase {
friend class QGLView;
friend class MouseController;
friend class RendererMaterial;
friend class RendererService;
friend class RendererSelection;

View File

@@ -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())

View File

@@ -25,6 +25,7 @@
class RendererSelection {
friend class QGLView;
friend class MouseController;
friend class Renderer;
public:

View File

@@ -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;

View File

@@ -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;