#include "MousePicker.h" #include #include #include #include MousePicker::MousePicker(QObject *parent) : QObject(parent) { // 防止老点绘制影响新点的求交运算 currentDrawNode->setNodeMask(0xffffffff & (~0x00000004)); } void MousePicker::setRoot(osg::ref_ptr root) { // root->addChild(currentDrawNode); root->addChild(drawNodeList); } void MousePicker::activate(PickingMode _mode, osg::Node* node) { disactivate(); mode = _mode; isActivated = true; model = node; } bool MousePicker::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa) { if(!isActivated){ return false; } osgViewer::Viewer* pViewer = dynamic_cast( &aa ); osgUtil::LineSegmentIntersector::Intersections intersections; pViewer->computeIntersections(ea, intersections, 0x00000004); if(intersections.empty()){ return false; } osg::Vec3 mouseWorldCoord = intersections.begin()->getWorldIntersectPoint(); switch( ea.getEventType() ){ case osgGA::GUIEventAdapter::PUSH:{ if(ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON){ if(!isDrawing){ // 初始化lineGeometry lineGeometry = new osg::Geometry; lineGeometry->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); currentDrawNode->addDrawable(lineGeometry); // 初始化vertexArray vertexArray = new osg::Vec3Array; vertexArray->push_back(mouseWorldCoord); osg::ref_ptr color = new osg::Vec4Array(); color->push_back(osg::Vec4(0.0f, 0.8f, 0.8f, 0.5f) ); lineGeometry->setColorArray(color, osg::Array::BIND_OVERALL); isDrawing = true; } vertexArray->push_back(mouseWorldCoord); vertexArray->dirty(); pushPnt = mouseWorldCoord; } if(ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON){ // 当点击右键时, 退出编辑 disactivate(); } return false; } case osgGA::GUIEventAdapter::RELEASE:{ if(ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON){ // 点击事件完成时 if(pushPnt != mouseWorldCoord){ // 当用户真正希望的是拖动视角时,弹出点击事件的录入操作,假装无事发生 vertexArray->pop_back(); return false; } // 绘制相应点 // currentDrawNode->addDrawable(createPointGeode(mouseWorldCoord)); osg::MatrixTransform* mt = new osg::MatrixTransform; mt->setMatrix( osg::Matrix::translate(mouseWorldCoord)); mt->addChild(model); drawNodeList->addChild(mt); if(mode == LinePicker){ // 如果是线要素则绘制该线段并显示长度 lineGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, vertexArray->size())); } if(mode == AreaPicker){ // 如果是面要素则绘制该面并显示面积 lineGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, vertexArray->size())); } } return false; } case osgGA::GUIEventAdapter::MOVE:{ if(isDrawing){ // 绘制过程中,按不同的图形类型进行图形绘制的预览 vertexArray->pop_back(); vertexArray->push_back(mouseWorldCoord); vertexArray->dirty(); if(mode == PointPicker){ return false; } // 根据MOVE的坐标实时更新lineGeometry lineGeometry->setVertexArray(vertexArray); lineGeometry->dirtyDisplayList(); } return false; } case osgGA::GUIEventAdapter::DOUBLECLICK:{ if(isDrawing){ // 当双击时,完成当前geode的编辑 isDrawing = false; } // 双击时应避免视角操作,故返回true return true; } } return false; } void MousePicker::disactivate() { isDrawing = false; isActivated = false; emit editionDone(mode, vertexArray); currentDrawNode->removeChildren(0, currentDrawNode->getNumChildren()); lineGeometry = nullptr; vertexArray = nullptr; } osg::ref_ptr MousePicker::createPointGeode(const osg::Vec3 &pos) { osg::Geometry *geom = new osg::Geometry(); osg::ref_ptr vertex = new osg::Vec3Array(); vertex->push_back(pos); geom->setVertexArray(vertex.get()); osg::ref_ptr color = new osg::Vec4Array(); color->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) ); geom->setColorArray(color, osg::Array::BIND_OVERALL); geom->getOrCreateStateSet()->setAttribute(new osg::Point(6.0f), osg::StateAttribute::ON); geom->getOrCreateStateSet()->setMode(GL_POINT_SMOOTH, osg::StateAttribute::ON); geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, 1)); geom->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); return geom; }