void Camera::handleCursorMoveEvent(window::CursorMoveEvent e) { if (dragging) { // vec2f offset = (dragPosition - e.location).array() * dragSensitivity.array(); vec2f offset = dragPosition - e.location; offset = offset.array() * dragSensitivity.array(); dragPosition = e.location; rotateAroundTarget(quat4f( Eigen::AngleAxisf(-offset.y(), vec3f::UnitX()) * Eigen::AngleAxisf(-offset.x(), vec3f::UnitY()) )); } }
void AutoBlend::init() { // Add widget auto toolsWidgetContainer = new QWidget(); widget = new Ui::AutoBlendWidget(); widget->setupUi(toolsWidgetContainer); widgetProxy = new QGraphicsProxyWidget(this); widgetProxy->setWidget(toolsWidgetContainer); // Place at bottom left corner auto delta = widgetProxy->sceneBoundingRect().bottomLeft() - scene()->views().front()->rect().bottomLeft(); widgetProxy->moveBy(-delta.x(), -delta.y()); // Fill categories box { for(auto cat : document->categories.keys()){ widget->categoriesBox->insertItem(widget->categoriesBox->count(), cat); } int idx = widget->categoriesBox->findText(document->categoryOf(document->firstModelName())); widget->categoriesBox->setCurrentIndex(idx); } // Create gallery of shapes gallery = new Gallery(this, QRectF(0,0,this->bounds.width(), 220)); // Create container that holds results results = new Gallery(this, QRectF(0,0, this->bounds.width(), bounds.height() - gallery->boundingRect().height()), QRectF(0,0,256,256), true); results->moveBy(0, gallery->boundingRect().height()); // Gallery on top of results gallery->setZValue(results->zValue() + 10); auto dropShadow = new QGraphicsDropShadowEffect(); dropShadow->setOffset(0, 5); dropShadow->setColor(QColor(0, 0, 0, 150)); dropShadow->setBlurRadius(10); gallery->setGraphicsEffect(dropShadow); // Connect UI with actions { connect(widget->categoriesBox, &QComboBox::currentTextChanged, [&](QString text){ document->currentCategory = text; }); connect(widget->analyzeButton, &QPushButton::pressed, [&](){ document->computePairwise(widget->categoriesBox->currentText()); }); // Default view angle { // Camera target and initial position auto camera = new Eigen::Camera(); auto frame = camera->frame(); frame.position = Eigen::Vector3f(-1, 0, 0.5); camera->setTarget(Eigen::Vector3f(0, 0, 0.5)); camera->setFrame(frame); int deltaZoom = document->extent().length() * 1.0; // Default view angle double theta1 = acos(-1) * 0.75; double theta2 = acos(-1) * 0.10; camera->rotateAroundTarget(Eigen::Quaternionf(Eigen::AngleAxisf(theta1, Eigen::Vector3f::UnitY()))); camera->zoom(-(4+deltaZoom)); camera->rotateAroundTarget(Eigen::Quaternionf(Eigen::AngleAxisf(theta2, Eigen::Vector3f::UnitX()))); auto cp = camera->position(); cameraPos = QVector3D(cp[0], cp[1], cp[2]); // Camera settings camera->setViewport(128, 128); Eigen::Matrix4f p = camera->projectionMatrix(); Eigen::Matrix4f v = camera->viewMatrix().matrix(); p.transposeInPlace(); v.transposeInPlace(); cameraMatrix = QMatrix4x4(p.data()) * QMatrix4x4(v.data()); } connect(document, &Document::categoryAnalysisDone, [=](){ if (gallery == nullptr) return; // Fill gallery gallery->clearThumbnails(); auto catModels = document->categories[document->currentCategory].toStringList(); for (auto targetName : catModels) { auto targetModel = document->cacheModel(targetName); auto t = gallery->addTextItem(targetName); QVariantMap data = t->data; data["targetName"].setValue(targetName); t->setData(data); t->setCamera(cameraPos, cameraMatrix); t->setFlag(QGraphicsItem::ItemIsSelectable); // Add parts of target shape for (auto n : targetModel->nodes){ t->addAuxMesh(toBasicMesh(targetModel->getMesh(n->id), n->vis_property["color"].value<QColor>())); } scene()->update(t->sceneBoundingRect()); } scene()->update(this->sceneBoundingRect()); QTimer::singleShot(500, [=]{ gallery->update(); }); }); // Do blend connect(widget->blendButton, SIGNAL(pressed()), SLOT(doBlend())); } }
// TODO: switch camera to using a physics/velocity model // so that interactions are consistent. // the current method could be unstable to framerate // and event processing speeds. void Camera::handleKeyEvent(window::KeyEvent e) { if (e.action == window::action::PRESSED || e.action == window::action::REPEAT) { switch (e.key) { default: break; // zoom = move forward/back case window::key::W: zoom(0.2f); break; case window::key::S: zoom(-0.2f); break; // move (slide) case window::key::C: localTranslate({0, -0.2f, 0}); break; case window::key::E: localTranslate({0, 0.2f, 0}); break; case window::key::A: localTranslate({-0.2f,0,0}); break; case window::key::D: localTranslate({0.2f,0,0}); break; // look around case window::key::I: if (e.mods == window::mods::SHIFT) rotateAroundTarget(quat4f(Eigen::AngleAxisf(0.1f, vec3f::UnitX()))); else localRotate(quat4f(Eigen::AngleAxisf(0.1f, vec3f::UnitX()))); break; case window::key::J: if (e.mods == window::mods::SHIFT) rotateAroundTarget(quat4f(Eigen::AngleAxisf(0.1f, vec3f::UnitY()))); else localRotate(quat4f(Eigen::AngleAxisf(0.1f, vec3f::UnitY()))); break; case window::key::K: if (e.mods == window::mods::SHIFT) rotateAroundTarget(quat4f(Eigen::AngleAxisf(-0.1f, vec3f::UnitX()))); else localRotate(quat4f(Eigen::AngleAxisf(-0.1f, vec3f::UnitX()))); break; case window::key::L: if (e.mods == window::mods::SHIFT) rotateAroundTarget(quat4f(Eigen::AngleAxisf(-0.1f, vec3f::UnitY()))); else localRotate(quat4f(Eigen::AngleAxisf(-0.1f, vec3f::UnitY()))); break; // rolling case window::key::U: localRotate(quat4f(Eigen::AngleAxisf(0.1f, vec3f::UnitZ()))); break; case window::key::O: localRotate(quat4f(Eigen::AngleAxisf(-0.1f, vec3f::UnitZ()))); break; } } }