// Include own headers #include "PickHandler.hpp" // Include modules #include "TrackPointRenderer.hpp" // Include dependencies #include #include #include #include #include #include #include #include PickHandler::PickHandler(OSGWidget* osgWidget, osg::ref_ptr root) { _osgWidget = osgWidget; _selectionRotateGroup = new osg::MatrixTransform; _selectionMoveToEndGroup = new osg::MatrixTransform; _selectionMoveToEndGroup->addChild(_selectionRotateGroup.get()); _selectionTranslateGroup = new osg::MatrixTransform; _selectionTranslateGroup->addChild(_selectionMoveToEndGroup.get()); _selectionSwitch = new osg::Switch; _selectionSwitch->addChild(_selectionTranslateGroup.get()); root->addChild(_selectionSwitch.get()); } osg::Node* PickHandler::getPickerRoot() { return _selectionSwitch.get(); } bool PickHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) { if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) { if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH) { osgViewer::View* viewer = dynamic_cast(&aa); if (viewer) { osg::ref_ptr intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), ea.getY()); osgUtil::IntersectionVisitor iv(intersector.get()); iv.setTraversalMask(~0x1); viewer->getCamera()->accept(iv); if (intersector->containsIntersections()) { if (_addNewPoints) { for (const osgUtil::LineSegmentIntersector::Intersection result: intersector->getIntersections()) { if (std::find(result.nodePath.begin(), result.nodePath.end(), _osgWidget->getMesh()) != result.nodePath.end()) { _clickStartedOnElement = true; break; } } } else { bool found = false; for (const osgUtil::LineSegmentIntersector::Intersection result: intersector->getIntersections()) { if (found) break; for (PointShape* shape: _osgWidget->getPointRenderer()->getShapes()) { if (std::find(result.nodePath.begin(), result.nodePath.end(), shape->getMesh()) != result.nodePath.end()) { _clickStartedOnElement = true; found = true; break; } } } } } } } else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE && _clickStartedOnElement) { _clickStartedOnElement = false; osgViewer::View* viewer = dynamic_cast(&aa); if (viewer) { osg::ref_ptr intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), ea.getY()); osgUtil::IntersectionVisitor iv(intersector.get()); iv.setTraversalMask(~0x1); viewer->getCamera()->accept(iv); if (intersector->containsIntersections()) { if (_addNewPoints) { for (const osgUtil::LineSegmentIntersector::Intersection result: intersector->getIntersections()) { if (std::find(result.nodePath.begin(), result.nodePath.end(), _osgWidget->getMesh()) != result.nodePath.end()) { moveTo(result.localIntersectionPoint); rotateToNormalVector(result.localIntersectionNormal); addPoint(result.localIntersectionPoint, result.localIntersectionNormal); break; } } } else { bool found = false; for (const osgUtil::LineSegmentIntersector::Intersection result: intersector->getIntersections()) { if (found) break; int shapeId = 0; for (PointShape* shape: _osgWidget->getPointRenderer()->getShapes()) { if (std::find(result.nodePath.begin(), result.nodePath.end(), shape->getMesh()) != result.nodePath.end()) { _selectedPoint = shapeId; MainWindow::getInstance()->getEditWiget()->setSelection(shapeId); found = true; break; } shapeId++; } } } } } } } // Update position of picker on mouse move if (ea.getEventType() == osgGA::GUIEventAdapter::MOVE || ea.getEventType() == osgGA::GUIEventAdapter::DRAG) { osgViewer::View* viewer = dynamic_cast(&aa); if (viewer) { osg::ref_ptr intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), ea.getY()); osgUtil::IntersectionVisitor iv(intersector.get()); iv.setTraversalMask(~0x1); viewer->getCamera()->accept(iv); invalidateTrackPointColors(); if (intersector->containsIntersections()) { if (_addNewPoints) { for (const osgUtil::LineSegmentIntersector::Intersection result: intersector->getIntersections()) { if (std::find(result.nodePath.begin(), result.nodePath.end(), _osgWidget->getMesh()) != result.nodePath.end()) { moveTo(result.localIntersectionPoint); rotateToNormalVector(result.localIntersectionNormal); setVisibility(true); break; } } } else { bool found = false; for (const osgUtil::LineSegmentIntersector::Intersection result: intersector->getIntersections()) { if (found) break; for (PointShape* shape: _osgWidget->getPointRenderer()->getShapes()) { if (std::find(result.nodePath.begin(), result.nodePath.end(), shape->getMesh()) != result.nodePath.end()) { shape->setColor(osg::Vec4(0.0f, 0.0f, 1.0f, 0.2f)); found = true; break; } } } } } else { if (_addNewPoints) { MainWindow::getInstance()->getEditWiget()->invalidatePositions(); } setVisibility(false); } } } return false; } void PickHandler::setSelection(bool addNewPoints) { _addNewPoints = addNewPoints; if (addNewPoints) { _selectedPoint = -1; } invalidateTrackPointColors(); updateRenderer(); } void PickHandler::moveTo(osg::Vec3f position) { _selectionTranslateGroup->setMatrix(osg::Matrix::translate(position)); MainWindow::getInstance()->getEditWiget()->updatePositions(position); } void PickHandler::rotateToNormalVector(osg::Vec3f normal) { MainWindow::getInstance()->getEditWiget()->updateNormals(normal); osg::Vec3 modifier = MainWindow::getInstance()->getStore()->getNormalModifier(); normal = normal.operator+(modifier); normal.normalize(); _selectionRotateGroup->setMatrix(osg::Matrix::rotate(osg::Vec3f(0.0f, 0.0f, 1.0f), normal)); osg::Vec3f movementVector = normal.operator*(_optiTrackSteamVRLength / 2); _selectionMoveToEndGroup->setMatrix(osg::Matrix::translate(movementVector)); } void PickHandler::updateRenderer() { removeAllShapes(); switch(MainWindow::getInstance()->getEditWiget()->getSelectedTrackingSystem()) { case OptiTrack: { OptiTrackSettings settings = MainWindow::getInstance()->getStore()->getOptiTrackSettings(); _optiTrackSteamVRLength = settings.length; osg::ref_ptr geode = new osg::Geode; osg::ref_ptr cylinder = new osg::ShapeDrawable(); cylinder->setShape(new osg::Cylinder(osg::Vec3(0.0f, 0.0f, 0.0f), settings.radius, settings.length)); cylinder->setColor(osg::Vec4(1.0f, 0.0f, 0.0f, 0.2f)); geode->addDrawable(cylinder.get()); OSGWidget::fixMaterialState(geode); _selectionRotateGroup->addChild(geode.get()); break; } case EMFTrack: { break; } case SteamVRTrack: { break; } case ActionPoints: { break; } } setVisibility(_addNewPoints); } void PickHandler::removeAllShapes() { _selectionRotateGroup->removeChildren(0, _selectionRotateGroup->getNumChildren()); } void PickHandler::setVisibility(bool mode) { _selectionSwitch->setValue(0, mode); } void PickHandler::addPoint(osg::Vec3 point, osg::Vec3 normal) { switch(MainWindow::getInstance()->getEditWiget()->getSelectedTrackingSystem()) { case OptiTrack: { MainWindow::getInstance()->getStore()->addOptiTrackPoint(point, normal); break; } case EMFTrack: { break; } case SteamVRTrack: { break; } case ActionPoints: { break; } } _osgWidget->getPointRenderer()->render(MainWindow::getInstance()->getEditWiget()->getSelectedTrackingSystem()); } void PickHandler::invalidateTrackPointColors() { int shapeId = 0; for (PointShape* shape: _osgWidget->getPointRenderer()->getShapes()) { if (_selectedPoint != shapeId) { shape->setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 0.2f)); } shapeId++; } }