diff --git a/qglengine/glcamera.h b/qglengine/glcamera.h index ea11a0b..3412f6f 100644 --- a/qglengine/glcamera.h +++ b/qglengine/glcamera.h @@ -91,6 +91,8 @@ public: QMatrix4x4 projectionMatrix(double aspect) const; QMatrix4x4 offsetMatrix() const; + QMatrix4x4 fullViewMatrix() const {return viewMatrix() * offsetMatrix();} + private: QVector3D aim_; mutable QVector3D offset_; diff --git a/qglengine/glprimitives.cpp b/qglengine/glprimitives.cpp index 97c4855..55d3fd7 100644 --- a/qglengine/glprimitives.cpp +++ b/qglengine/glprimitives.cpp @@ -263,6 +263,52 @@ 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 * ret = new Mesh(); + QVector & v(ret->vertices ()); + QVector & n(ret->normals ()); + QVector & t(ret->texcoords()); + QVector< Vector3i> & ind(ret->indicesTriangles()); + + QVector cv, cn; + QVector ct; + segments_second = qMax(segments_second + 1, 4); + for (int i = 0; i < segments_second; i++) { + double x = (double)i / (segments_second - 1); + double a = x * M_2PI; + cv << QVector3D(radius_second * cos(a), 0., radius_second * sin(a)); + cn << cv.back().normalized(); + ct << QVector2D(0., x); + cv.back() += QVector3D(radius_main, 0., 0.); + } + + segments_main = qMax(segments_main + 1, 4); + int ccnt = cv.size(), pcnt = 0; + for (int i = 0; i < segments_main; i++) { + double x = (double)i / (segments_main - 1); + QMatrix4x4 rm; + rm.rotate(x * 360., 0., 0., 1.); + for (int j = 0; j < ccnt; j++) { + ct[j].setX(x); + v << rm.map(cv[j]); + n << rm.map(cn[j]); + } + t.append(ct); + if (i > 0) { + for (int j = 0; j < ccnt - 1; j++) { + ind << Vector3i(pcnt + j, pcnt + j + 1, pcnt + j - ccnt); + ind << Vector3i(pcnt + j + 1, pcnt + j + 1 - ccnt, pcnt + j - ccnt); + } + } + pcnt = v.size(); + } + + return ret; +} + + + + Mesh * Primitive::cubeFrame(float width, float length, float height) { Mesh * ret = new Mesh(GL_LINES); QVector3D scale(width, length, height); diff --git a/qglengine/glprimitives.h b/qglengine/glprimitives.h index 96f8a35..2007b7a 100644 --- a/qglengine/glprimitives.h +++ b/qglengine/glprimitives.h @@ -39,6 +39,8 @@ 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 * cubeFrame(float width = 1., float length = 1., float height = 1.); diff --git a/qglengine/glscene.cpp b/qglengine/glscene.cpp index 18f4c9c..c4b70f0 100644 --- a/qglengine/glscene.cpp +++ b/qglengine/glscene.cpp @@ -417,6 +417,8 @@ void Scene::destroy() { qDeleteAll(materials); geometries.clear(); materials.clear(); + selected_.clear(); + selected_top.clear(); emit __destroyed(); emit treeChanged(); } diff --git a/qglengine/qglview.cpp b/qglengine/qglview.cpp index 7bf1ade..d3fe9eb 100644 --- a/qglengine/qglview.cpp +++ b/qglengine/qglview.cpp @@ -20,6 +20,7 @@ #include "glmesh.h" #include "gltexture_manager.h" #include +#include #include #include #include @@ -31,6 +32,8 @@ QGLView::QGLView(): OpenGLWindow(), renderer_(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); @@ -91,7 +94,7 @@ QGLView::QGLView(): OpenGLWindow(), renderer_(this) { //camera().aim_ = camera().pos_; ktm_.restart(); - Mesh * m = Primitive::ellipsoidFrame(5,5); + Mesh * m = Primitive::torus(30, 12, 1., 0.1); ObjectBase * o = new ObjectBase(m); o->setColor(Qt::cyan); scene()->addObject(o); @@ -151,6 +154,7 @@ ObjectBase * QGLView::selectedObject() const { void QGLView::resizeEvent(QResizeEvent * e) { renderLater(); + app_scale = appScale(); } @@ -227,6 +231,10 @@ 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; @@ -246,6 +254,9 @@ void QGLView::mouseReleaseEvent(QMouseEvent * e) { void QGLView::mousePressEvent(QMouseEvent * e) { + if (cur_handle != RendererService::htNoHandle && e->buttons() == Qt::LeftButton) { + return; + } if (selecting_) { downPos = e->pos(); selecting_ = false; @@ -261,6 +272,45 @@ void QGLView::mousePressEvent(QMouseEvent * 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 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.; + QVector3D center_screen = camera()->fullViewMatrix() * rs.selection_center; + QVector3D axe_screen = ((camera()->fullViewMatrix() * (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; @@ -294,6 +344,20 @@ void QGLView::mouseMoveEvent(QMouseEvent * e) { } 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; @@ -444,3 +508,8 @@ QImage QGLView::materialThumbnail(Material * m) { return renderer_.materialThumbnail(m); } + +void QGLView::setCurrentHadle(RendererService::HandleType ht) { + renderer_.rend_service.setCurrentHadle(ht); +} + diff --git a/qglengine/qglview.h b/qglengine/qglview.h index 8478ad8..4f662ba 100644 --- a/qglengine/qglview.h +++ b/qglengine/qglview.h @@ -167,6 +167,7 @@ public: void restoreFeatures(const QByteArray & ba); QImage materialThumbnail(Material * m); + void setCurrentHadle(RendererService::HandleType ht); GLfloat aspect, iaspect; @@ -211,9 +212,10 @@ private: Qt::MouseButton sel_button; Qt::KeyboardModifier sel_mod; GLRendererBase::RenderingParameters start_rp; + RendererService::HandleType cur_handle; QHash features_; QSize prev_size; - float lineWidth_; + float lineWidth_, app_scale; 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_; diff --git a/qglengine/qglview_test/qglview_window.cpp b/qglengine/qglview_test/qglview_window.cpp index 00239a1..5ad5aae 100644 --- a/qglengine/qglview_test/qglview_window.cpp +++ b/qglengine/qglview_test/qglview_window.cpp @@ -284,3 +284,39 @@ void QGLViewWindow::on_actionAdd_sphere_triggered() { view->addObject(o->clone()); delete o; } + + +void QGLViewWindow::on_actionArrow_triggered(bool on) { + actionArrow ->setChecked(true); + actionMove ->setChecked(false); + actionRotate->setChecked(false); + actionScale ->setChecked(false); + view->view()->setCurrentHadle(RendererService::htNoHandle); +} + + +void QGLViewWindow::on_actionMove_triggered(bool on) { + actionArrow ->setChecked(false); + actionMove ->setChecked(true); + actionRotate->setChecked(false); + actionScale ->setChecked(false); + view->view()->setCurrentHadle(RendererService::htMoveX); +} + + +void QGLViewWindow::on_actionRotate_triggered(bool on) { + actionArrow ->setChecked(false); + actionMove ->setChecked(false); + actionRotate->setChecked(true); + actionScale ->setChecked(false); + view->view()->setCurrentHadle(RendererService::htRotateX); +} + + +void QGLViewWindow::on_actionScale_triggered(bool on) { + actionArrow ->setChecked(false); + actionMove ->setChecked(false); + actionRotate->setChecked(false); + actionScale ->setChecked(true); + view->view()->setCurrentHadle(RendererService::htScaleX); +} diff --git a/qglengine/qglview_test/qglview_window.h b/qglengine/qglview_test/qglview_window.h index 0fce060..15ef1e8 100644 --- a/qglengine/qglview_test/qglview_window.h +++ b/qglengine/qglview_test/qglview_window.h @@ -119,6 +119,11 @@ private slots: void on_actionAdd_cube_triggered(); void on_actionAdd_sphere_triggered(); + void on_actionArrow_triggered(bool on); + void on_actionMove_triggered(bool on); + void on_actionRotate_triggered(bool on); + void on_actionScale_triggered(bool on); + public slots: signals: diff --git a/qglengine/qglview_test/qglview_window.ui b/qglengine/qglview_test/qglview_window.ui index 79f11d9..40e66f0 100644 --- a/qglengine/qglview_test/qglview_window.ui +++ b/qglengine/qglview_test/qglview_window.ui @@ -1193,8 +1193,18 @@ + + + Mode + + + + + + + @@ -1298,6 +1308,65 @@ Add plane + + + true + + + true + + + Arrow + + + Ctrl+1 + + + + + true + + + + :/icons/transform-move.png:/icons/transform-move.png + + + Move + + + Ctrl+2 + + + + + true + + + + :/icons/transform-rotate.png:/icons/transform-rotate.png + + + Rotate + + + Ctrl+3 + + + + + true + + + + :/icons/transform-scale.png:/icons/transform-scale.png + + + Scale + + + Ctrl+4 + + diff --git a/qglengine/renderer_base.cpp b/qglengine/renderer_base.cpp index 73cdbe0..86aec0f 100644 --- a/qglengine/renderer_base.cpp +++ b/qglengine/renderer_base.cpp @@ -95,7 +95,7 @@ void RendererBase::setUniformCamera(QOpenGLShaderProgram * prog, Camera * cam, b QMatrix4x4 mat_view, mat_proj; if (cam) { if (matrices) { - mat_view = cam->viewMatrix() * cam->offsetMatrix(); + mat_view = cam->fullViewMatrix(); mat_proj = cam->projectionMatrix(w / h); } prog->setUniformValue("z_near", cam->depthStart()); diff --git a/qglengine/renderer_selection.cpp b/qglengine/renderer_selection.cpp index 38fb713..48e5855 100644 --- a/qglengine/renderer_selection.cpp +++ b/qglengine/renderer_selection.cpp @@ -78,6 +78,13 @@ void RendererSelection::fillSelectionsBuffer(const QList & ol) { } +void RendererSelection::fillSelectionsBuffer(bool yes, int size) { + cur_selections_.resize(size); + for (int i = 0; i < size; ++i) + cur_selections_[i] = (yes ? 1 : 0); +} + + void RendererSelection::renderSelection(Scene & scene) { QOpenGLShaderProgram * prog = 0; QGLView * view = r->view; @@ -118,6 +125,16 @@ 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); + } + } + //mouse_rect = fbo_selection.rect(); if (r->mouse_rect.isNull()) fbo_selection.queryPoint(0, r->mouse_pos); diff --git a/qglengine/renderer_selection.h b/qglengine/renderer_selection.h index 82b5cd5..7c656bf 100644 --- a/qglengine/renderer_selection.h +++ b/qglengine/renderer_selection.h @@ -44,6 +44,7 @@ protected: void generateObjectsID(Scene & scene); void fillSelectionsBuffer(const QList & ol); + void fillSelectionsBuffer(bool yes, int size); void renderSelection(Scene & scene); void renderSelectionFrame(); void drawSelection(Framebuffer & fbo_out, int index_out = 0); diff --git a/qglengine/renderer_service.cpp b/qglengine/renderer_service.cpp index bb5cf0a..99bf80b 100644 --- a/qglengine/renderer_service.cpp +++ b/qglengine/renderer_service.cpp @@ -29,19 +29,22 @@ 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)}; + 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,1); + color_xyz[i][i] = 1.; + } axis_camera = new Camera(); axis_camera->setAim(QVector3D()); axis_camera->setFOV(45.); axis_mesh = Primitive::arrow(12); - axis_objects.resize(3); - const QVector3D _rot[3] = {QVector3D(0,1,0), QVector3D(-1,0,0), QVector3D(0,0,1)}; - for (int i = 0; i < 3; ++i) { - axis_objects[i].color = QVector4D(0,0,0,1); - axis_objects[i].color[i] = 1.; - QMatrix4x4 m; m.rotate(90., _rot[i]); - m.transposed().copyDataTo(axis_objects[i].modelmatrix); - } - box_vp_scale = box_full_scale = 1.; + size_vp_scale = size_full_scale = 1.; box_mesh = Primitive::cube(); box_mesh_f = Primitive::cubeFrame(); omni_mesh = Primitive::ellipsoid(2, 1); @@ -50,6 +53,20 @@ 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_rotate_mesh = Primitive::arrow(12, 0.03); + Mesh * 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); + 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); } @@ -60,11 +77,15 @@ RendererService::~RendererService() { delete omni_mesh_f; delete axis_camera; delete axis_mesh; + delete handle_move_mesh; + delete handle_rotate_mesh; + delete handle_scale_mesh; } void RendererService::init(int width, int height) { - axis_mesh->loadObjects(r->view, axis_objects); + fillXYZObjects(); + axis_mesh->loadObjects(r->view, cur_objects); resize(width, height); } @@ -72,30 +93,79 @@ void RendererService::init(int width, int height) { void RendererService::resize(int width, int height) { axis_viewport = preferredIconSize(10.); line_width = lineThickness(); - box_vp_scale = 25. * appScale() / qMax(qMin(width, height), 1); + size_vp_scale = 25. * appScale() / qMax(qMin(width, height), 1); //qDebug() << axis_viewport; } +QMatrix4x4 RendererService::invariantSizeMatrix(QVector3D p) { + QVector4D pos = QVector4D(p, 1.); + double dist = -(v_mat * pos).z(); + QMatrix4x4 m; + m.translate(pos.toVector3D()); + m.scale(dist * size_full_scale); + return m; +} + + +void RendererService::fillXYZObjects() { + cur_objects.resize(3); + for (int i = 0; i < 3; ++i) { + cur_objects[i].color = color_xyz[i]; + mat_xyz[i].transposed().copyDataTo(cur_objects[i].modelmatrix); + } +} + + void RendererService::fillOmniObjects() { - cur_objects.clear(); - Object o; QList ll = r->view->scene()->lights_used; - QMatrix4x4 v_mat = r->view->camera()->viewMatrix() * r->view->camera()->offsetMatrix(); - box_full_scale = tan(r->view->camera()->FOV() / 2. * deg2rad) * box_vp_scale; + Object o; + cur_objects.clear(); foreach (Light * l, ll) { - QVector4D lpos = QVector4D(l->worldPos(), 1.); - double dist = -(v_mat * lpos).z(); - QMatrix4x4 lmat; - lmat.translate(lpos.toVector3D()); - lmat.scale(dist * box_full_scale); - lmat.transposed().copyDataTo(o.modelmatrix); + QMatrix4x4 m = invariantSizeMatrix(l->worldPos()); + m.transposed().copyDataTo(o.modelmatrix); o.object_id = l->id_; cur_objects << o; } } +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); + } +} + + +bool RendererService::fillCurrentHandleObjects() { + QList 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(); + } + if (bb.isEmpty()) + selection_center = sol[0]->worldPos(); + else + selection_center = bb.center(); + QMatrix4x4 rm; + if ((sol.size() == 1) && (current_handle >= htRotateX)) { + rm.rotate(sol[0]->angles_.z(), 0., 0., 1.); + rm.rotate(sol[0]->angles_.y(), 0., 1., 0.); + rm.rotate(sol[0]->angles_.x(), 1., 0., 0.); + } + fillHandleObjects(selection_center, current_handle, rm); + return true; +} + + void RendererService::setObjectsColor(QVector & ol, QColor col) { QVector4D cv = QColor2QVector(col); for (int i = 0; i < ol.size(); ++i) @@ -106,6 +176,8 @@ void RendererService::setObjectsColor(QVector & ol, QColor col) { void RendererService::renderService() { QOpenGLShaderProgram * prog = 0; QOpenGLExtraFunctions * f = r->view; + size_full_scale = tan(r->view->camera()->FOV() / 2. * deg2rad) * size_vp_scale; + v_mat = r->view->camera()->fullViewMatrix(); f->glEnable(GL_MULTISAMPLE); glEnableDepth(); f->glClear(GL_DEPTH_BUFFER_BIT); @@ -135,15 +207,41 @@ void RendererService::renderService() { } if (r->bindShader(Renderer::srServiceFill, &prog)) { + r->setUniformCamera(prog, r->view->camera()); + + /// handles + if (fillCurrentHandleObjects()) { + Mesh * hm = currentHandleMesh(); + if (hm) { + hm->loadObjects(r->view, cur_objects); + hm->draw(f, 3); + } + } /// axis f->glViewport(0, 0, axis_viewport.width(), axis_viewport.height()); axis_camera->setPos(-r->view->camera()->direction() * 3.); r->setUniformCamera(prog, axis_camera, true, axis_viewport); - //axis_mesh->loadObjects(f, axis_objects); - axis_mesh->draw(f, axis_objects.size()); + axis_mesh->draw(f, 3); f->glViewport(0, 0, r->view->width(), r->view->height()); } f->glDisable(GL_MULTISAMPLE); } + + +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; + default: break; + } + return 0; +} diff --git a/qglengine/renderer_service.h b/qglengine/renderer_service.h index f698876..3f5fda9 100644 --- a/qglengine/renderer_service.h +++ b/qglengine/renderer_service.h @@ -33,23 +33,47 @@ public: RendererService(Renderer * r_); virtual ~RendererService(); + enum HandleType { + htNoHandle, + htMoveX, + htMoveY, + htMoveZ, + htRotateX, + htRotateY, + htRotateZ, + htScaleX, + htScaleY, + htScaleZ, + }; + void init(int width, int height); void resize(int width, int height); + QMatrix4x4 invariantSizeMatrix(QVector3D p); + void fillXYZObjects(); void fillOmniObjects(); + void fillHandleObjects(QVector3D center, HandleType first, QMatrix4x4 add_mat); + bool fillCurrentHandleObjects(); void setObjectsColor(QVector & ol, QColor col); void renderService(); + void setCurrentHadle(HandleType ht) {current_handle = ht;} + Mesh * currentHandleMesh(); private: Renderer * r; - Mesh * axis_mesh, * box_mesh_f, * omni_mesh_f; - Mesh * box_mesh, * omni_mesh; - QVector axis_objects, cur_objects; + Mesh * axis_mesh, * handle_move_mesh, * handle_rotate_mesh, * handle_scale_mesh; + Mesh * box_mesh_f, * omni_mesh_f, * box_mesh, * omni_mesh; + QMatrix4x4 v_mat; + QVector3D selection_center; + QVector mat_xyz; + QVector color_xyz; + QVector cur_objects; Camera * axis_camera; QSize axis_viewport; + HandleType current_handle; int line_width; - double box_vp_scale, box_full_scale; + double size_vp_scale, size_full_scale; };