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

This commit is contained in:
2019-12-02 21:09:33 +00:00
parent 35668c13fc
commit c2100ecbc0
8 changed files with 61 additions and 20 deletions

View File

@@ -36,7 +36,7 @@ ObjectBase::ObjectBase(Mesh * geom, Material * mat) {
blend_src = GL_SRC_ALPHA; blend_src = GL_SRC_ALPHA;
blend_dest = GL_ONE_MINUS_SRC_ALPHA; blend_dest = GL_ONE_MINUS_SRC_ALPHA;
type_ = glMesh; type_ = glMesh;
raw_matrix = false; raw_matrix = selected_aim = false;
mat_.setToIdentity(); mat_.setToIdentity();
scene_ = nullptr; scene_ = nullptr;
mesh_ = geom; mesh_ = geom;
@@ -329,6 +329,8 @@ void ObjectBase::setSelected(bool yes) {
//qDebug() << "select" << name() << view_; //qDebug() << "select" << name() << view_;
if (select_) if (select_)
selected_ = yes; selected_ = yes;
if (!selected_)
selected_aim = false;
} }
@@ -450,11 +452,10 @@ QVector3D AimedObject::worldAim() const {
void AimedObject::setAim(const QVector3D & p) { void AimedObject::setAim(const QVector3D & p) {
QVector3D dir = inParentSpace(p) - pos(), up; QVector3D dir = p - pos();
if (!QVector3D::crossProduct(QVector3D(0,0,1), dir).isNull())
up = QVector3D(0,0,1);
trans.setRotation(Transform::fromDirection(dir)); trans.setRotation(Transform::fromDirection(dir));
aim_dist = dir.length(); aim_dist = dir.length();
buildTransform();
//qDebug() << "setAim" << p << aim(); //qDebug() << "setAim" << p << aim();
} }
@@ -467,6 +468,7 @@ QVector3D AimedObject::direction() const {
void AimedObject::setDirection(const QVector3D & d) { void AimedObject::setDirection(const QVector3D & d) {
//double len = qMax(aim_.length(), 0.001f); //double len = qMax(aim_.length(), 0.001f);
//aim_ = d.normalized() * len; //aim_ = d.normalized() * len;
buildTransform();
} }

View File

@@ -32,6 +32,7 @@ class ObjectBase
friend class Renderer; friend class Renderer;
friend class RendererService; friend class RendererService;
friend class RendererSelection; friend class RendererSelection;
friend class MouseController;
friend QDataStream & operator <<(QDataStream & s, const ObjectBase * p); friend QDataStream & operator <<(QDataStream & s, const ObjectBase * p);
friend QDataStream & operator >>(QDataStream & s, ObjectBase *& p); friend QDataStream & operator >>(QDataStream & s, ObjectBase *& p);
friend QDataStream & operator >>(QDataStream & s, Scene *& p); friend QDataStream & operator >>(QDataStream & s, Scene *& p);
@@ -208,7 +209,7 @@ protected:
int pass_; // Pass 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_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; float line_width;
QColor color_; QColor color_;
uint id_; uint id_;

View File

@@ -236,7 +236,7 @@ void Scene::clearSelection() {
selected_top.clear(); selected_top.clear();
QList<ObjectBase * > ol = root_->children(true); QList<ObjectBase * > ol = root_->children(true);
foreach (ObjectBase * o, ol) { foreach (ObjectBase * o, ol) {
o->selected_ = false; o->selected_ = o->selected_aim = false;
} }
emitSelectionChanged(); emitSelectionChanged();
} }

View File

@@ -61,8 +61,18 @@ void MouseController::mouseReleaseEvent(QMouseEvent * e) {
return; return;
} }
if (canSelect_ && mouseSelect_ && e->button() == Qt::LeftButton) { if (canSelect_ && mouseSelect_ && e->button() == Qt::LeftButton) {
if ((lastPos - downPos).manhattanLength() < QApplication::startDragDistance() && !hov_objects.isEmpty()) { 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); 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; canSelect_ = e->buttons() == 0;
@@ -127,9 +137,18 @@ void MouseController::mouseMoveEvent(QMouseEvent * e) {
QMatrix4x4 pmat; QMatrix4x4 pmat;
foreach (ObjectBase * o, objects) { foreach (ObjectBase * o, objects) {
pmat.setToIdentity(); pmat.setToIdentity();
if (o->selected_aim) {
pmat = o->itransform_.inverted();
} else {
if (o->parent()) if (o->parent())
pmat = o->parent()->worldTransform().inverted(); pmat = o->parent()->worldTransform().inverted();
o->move((pmat * QVector4D(axe_vector, 0)).toVector3D()); }
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) { if (cur_action == RendererService::haRotate) {

View File

@@ -59,7 +59,7 @@ private:
QGLView * view; QGLView * view;
QPoint lastPos, downPos; QPoint lastPos, downPos;
QSet<int> keys_; QSet<int> keys_;
QVector<ObjectBase * > hov_objects; QVector<ObjectBase * > hov_objects, hov_aims;
Qt::MouseButton sel_button; Qt::MouseButton sel_button;
Qt::KeyboardModifier sel_mod; Qt::KeyboardModifier sel_mod;
RendererService::HandleAction cur_action; RendererService::HandleAction cur_action;

View File

@@ -53,6 +53,7 @@ void RendererSelection::resize(int width, int height) {
void RendererSelection::generateObjectsID(Scene & scene) { void RendererSelection::generateObjectsID(Scene & scene) {
ids.clear(); ids.clear();
aim_ids.clear();
QMapIterator<Mesh*, QList<ObjectBase*> > it(scene.geometries_used); QMapIterator<Mesh*, QList<ObjectBase*> > it(scene.geometries_used);
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
@@ -68,6 +69,7 @@ void RendererSelection::generateObjectsID(Scene & scene) {
foreach (ObjectBase * o, lit.value()) { foreach (ObjectBase * o, lit.value()) {
uint id = qHash(o); uint id = qHash(o);
ids[id] = o; ids[id] = o;
aim_ids[id + 1] = o;
o->id_ = id; o->id_ = id;
} }
} }
@@ -80,21 +82,31 @@ void RendererSelection::renderSelection(Scene & scene) {
MouseController & mc(view->mouse); MouseController & mc(view->mouse);
if (r->bindShader(Renderer::srSelectionFill, &prog)) { if (r->bindShader(Renderer::srSelectionFill, &prog)) {
mc.hov_objects.clear(); mc.hov_objects.clear();
mc.hov_aims.clear();
id_hover = 0; id_hover = 0;
if (fbo_selection.queriedPoints() > 0) { if (fbo_selection.queriedPoints() > 0) {
if (fbo_selection.queriedPoints() == 1) { if (fbo_selection.queriedPoints() == 1) {
id_hover = fbo_selection.getPoint(); id_hover = fbo_selection.getPoint();
mc.hov_objects.resize(1); ObjectBase * o = ids.value(id_hover);
mc.hov_objects[0] = 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; //qDebug() << id_hover;
} else { } else {
QVector<uint> points = fbo_selection.getPoints(); QVector<uint> points = fbo_selection.getPoints();
QSet<uint> ids_hover; QSet<uint> ids_hover;
foreach (uint i, points) foreach (uint i, points)
ids_hover << i; ids_hover << i;
mc.hov_objects.clear(); foreach (uint i, ids_hover) {
foreach (uint i, ids_hover) ObjectBase * o = ids.value(i);
mc.hov_objects << ids.value(i); if (o) mc.hov_objects << o;
o = aim_ids.value(i);
if (o) mc.hov_aims << o;
}
//qDebug() << ids_hover; //qDebug() << ids_hover;
} }
} }

View File

@@ -58,6 +58,7 @@ private:
QVector<uchar> cur_selections_; QVector<uchar> cur_selections_;
QHash<uint, ObjectBase * > ids; QHash<uint, ObjectBase * > ids;
QHash<uint, ObjectBase * > aim_ids;
uint id_hover; uint id_hover;
}; };

View File

@@ -230,13 +230,19 @@ bool RendererService::calculateCenter() {
o->calculateBoundingBox(); o->calculateBoundingBox();
bb |= o->boundingBox(); bb |= o->boundingBox();
} }
if (!bb.isEmpty()) if (!bb.isEmpty()) {
selection_center = bb.center(); selection_center = bb.center();
} }
}
axis_mat = QMatrix4x4(); axis_mat = QMatrix4x4();
if ((sol.size() == 1) && (current_action != haMove)) { 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]); axis_mat = parentRotationMatrix(sol[0]);
} }
}
return true; return true;
} }