diff --git a/qglengine/globject.cpp b/qglengine/globject.cpp index 87ca22f..4f00cf2 100644 --- a/qglengine/globject.cpp +++ b/qglengine/globject.cpp @@ -36,7 +36,7 @@ ObjectBase::ObjectBase(Mesh * geom, Material * mat) { blend_src = GL_SRC_ALPHA; blend_dest = GL_ONE_MINUS_SRC_ALPHA; type_ = glMesh; - raw_matrix = false; + raw_matrix = selected_aim = false; mat_.setToIdentity(); scene_ = nullptr; mesh_ = geom; @@ -329,6 +329,8 @@ void ObjectBase::setSelected(bool yes) { //qDebug() << "select" << name() << view_; if (select_) selected_ = yes; + if (!selected_) + selected_aim = false; } @@ -450,11 +452,10 @@ QVector3D AimedObject::worldAim() const { void AimedObject::setAim(const QVector3D & p) { - QVector3D dir = inParentSpace(p) - pos(), up; - if (!QVector3D::crossProduct(QVector3D(0,0,1), dir).isNull()) - up = QVector3D(0,0,1); + QVector3D dir = p - pos(); trans.setRotation(Transform::fromDirection(dir)); aim_dist = dir.length(); + buildTransform(); //qDebug() << "setAim" << p << aim(); } @@ -467,6 +468,7 @@ QVector3D AimedObject::direction() const { void AimedObject::setDirection(const QVector3D & d) { //double len = qMax(aim_.length(), 0.001f); //aim_ = d.normalized() * len; + buildTransform(); } diff --git a/qglengine/globject.h b/qglengine/globject.h index 2ec07ce..00be145 100644 --- a/qglengine/globject.h +++ b/qglengine/globject.h @@ -32,6 +32,7 @@ class ObjectBase friend class Renderer; friend class RendererService; friend class RendererSelection; + friend class MouseController; friend QDataStream & operator <<(QDataStream & s, const ObjectBase * p); friend QDataStream & operator >>(QDataStream & s, ObjectBase *& p); friend QDataStream & operator >>(QDataStream & s, Scene *& p); @@ -208,7 +209,7 @@ protected: int pass_; // Pass bool is_init, is_tex_loaded, accept_light, accept_fog, /*write_depth_,*/ visible_, cast_shadow, rec_shadow, select_, selected_, raw_matrix; - bool is_root; + bool is_root, selected_aim; float line_width; QColor color_; uint id_; diff --git a/qglengine/glscene.cpp b/qglengine/glscene.cpp index 48a0021..eae2cbc 100644 --- a/qglengine/glscene.cpp +++ b/qglengine/glscene.cpp @@ -236,7 +236,7 @@ void Scene::clearSelection() { selected_top.clear(); QList ol = root_->children(true); foreach (ObjectBase * o, ol) { - o->selected_ = false; + o->selected_ = o->selected_aim = false; } emitSelectionChanged(); } diff --git a/qglengine/mouse_controller.cpp b/qglengine/mouse_controller.cpp index 81aed7c..3ae62c9 100644 --- a/qglengine/mouse_controller.cpp +++ b/qglengine/mouse_controller.cpp @@ -61,8 +61,18 @@ void MouseController::mouseReleaseEvent(QMouseEvent * e) { 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); + if ((lastPos - downPos).manhattanLength() < QApplication::startDragDistance()) { + qDebug() << hov_objects << hov_aims; + if (hov_objects.isEmpty() && hov_aims.isEmpty()) { + view->scene()->clearSelection(); + } else { + if (!hov_objects.isEmpty()) + view->scene_->selectObject(hov_objects[0], add_ts); + if (!hov_aims.isEmpty()) { + view->scene_->selectObject(hov_aims[0], add_ts); + hov_aims[0]->selected_aim = true; + } + } } } canSelect_ = e->buttons() == 0; @@ -127,9 +137,18 @@ void MouseController::mouseMoveEvent(QMouseEvent * e) { QMatrix4x4 pmat; foreach (ObjectBase * o, objects) { pmat.setToIdentity(); - if (o->parent()) - pmat = o->parent()->worldTransform().inverted(); - o->move((pmat * QVector4D(axe_vector, 0)).toVector3D()); + if (o->selected_aim) { + pmat = o->itransform_.inverted(); + } else { + if (o->parent()) + pmat = o->parent()->worldTransform().inverted(); + } + QVector3D dv = (pmat * QVector4D(axe_vector, 0)).toVector3D(); + if (o->selected_aim) { + AimedObject * ao = (AimedObject*)o; + ao->setAim(ao->aim() + dv); + } else + o->move(dv); } } if (cur_action == RendererService::haRotate) { diff --git a/qglengine/mouse_controller.h b/qglengine/mouse_controller.h index 564f34c..89cbd79 100644 --- a/qglengine/mouse_controller.h +++ b/qglengine/mouse_controller.h @@ -59,7 +59,7 @@ private: QGLView * view; QPoint lastPos, downPos; QSet keys_; - QVector hov_objects; + QVector hov_objects, hov_aims; Qt::MouseButton sel_button; Qt::KeyboardModifier sel_mod; RendererService::HandleAction cur_action; diff --git a/qglengine/renderer_selection.cpp b/qglengine/renderer_selection.cpp index 935bfbd..ebf42ae 100644 --- a/qglengine/renderer_selection.cpp +++ b/qglengine/renderer_selection.cpp @@ -53,6 +53,7 @@ void RendererSelection::resize(int width, int height) { void RendererSelection::generateObjectsID(Scene & scene) { ids.clear(); + aim_ids.clear(); QMapIterator > it(scene.geometries_used); while (it.hasNext()) { it.next(); @@ -68,6 +69,7 @@ void RendererSelection::generateObjectsID(Scene & scene) { foreach (ObjectBase * o, lit.value()) { uint id = qHash(o); ids[id] = o; + aim_ids[id + 1] = o; o->id_ = id; } } @@ -80,21 +82,31 @@ void RendererSelection::renderSelection(Scene & scene) { MouseController & mc(view->mouse); if (r->bindShader(Renderer::srSelectionFill, &prog)) { mc.hov_objects.clear(); + mc.hov_aims.clear(); id_hover = 0; if (fbo_selection.queriedPoints() > 0) { if (fbo_selection.queriedPoints() == 1) { id_hover = fbo_selection.getPoint(); - mc.hov_objects.resize(1); - mc.hov_objects[0] = ids.value(id_hover); + ObjectBase * o = ids.value(id_hover); + if (o) + mc.hov_objects << o; + else { + o = aim_ids.value(id_hover); + if (o) + mc.hov_aims << o; + } //qDebug() << id_hover; } else { QVector points = fbo_selection.getPoints(); QSet ids_hover; foreach (uint i, points) ids_hover << i; - mc.hov_objects.clear(); - foreach (uint i, ids_hover) - mc.hov_objects << ids.value(i); + foreach (uint i, ids_hover) { + ObjectBase * o = ids.value(i); + if (o) mc.hov_objects << o; + o = aim_ids.value(i); + if (o) mc.hov_aims << o; + } //qDebug() << ids_hover; } } diff --git a/qglengine/renderer_selection.h b/qglengine/renderer_selection.h index 1295004..ec406e4 100644 --- a/qglengine/renderer_selection.h +++ b/qglengine/renderer_selection.h @@ -58,6 +58,7 @@ private: QVector cur_selections_; QHash ids; + QHash aim_ids; uint id_hover; }; diff --git a/qglengine/renderer_service.cpp b/qglengine/renderer_service.cpp index b9d3f52..2f69e6e 100644 --- a/qglengine/renderer_service.cpp +++ b/qglengine/renderer_service.cpp @@ -230,12 +230,18 @@ bool RendererService::calculateCenter() { o->calculateBoundingBox(); bb |= o->boundingBox(); } - if (!bb.isEmpty()) + if (!bb.isEmpty()) { selection_center = bb.center(); + } } axis_mat = QMatrix4x4(); - if ((sol.size() == 1) && (current_action != haMove)) { - axis_mat = parentRotationMatrix(sol[0]); + if ((sol.size() == 1)) { + if (current_action == haMove) { + if (sol[0]->selected_aim) + selection_center = ((AimedObject*)sol[0])->worldAim(); + } else { + axis_mat = parentRotationMatrix(sol[0]); + } } return true; }