152 lines
5.2 KiB
C++
152 lines
5.2 KiB
C++
#include "MousePicker.h"
|
||
|
||
#include <QtWidgets>
|
||
|
||
#include <osg/Point>
|
||
#include <osg/MatrixTransform>
|
||
#include <osgViewer/Viewer>
|
||
|
||
MousePicker::MousePicker(QObject *parent)
|
||
: QObject(parent)
|
||
{
|
||
// 防止老点绘制影响新点的求交运算
|
||
currentDrawNode->setNodeMask(0xffffffff & (~0x00000004));
|
||
}
|
||
|
||
void MousePicker::setRoot(osg::ref_ptr<osg::Group> 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<osgViewer::Viewer*>( &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<osg::Vec4Array> 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<osg::Geometry> MousePicker::createPointGeode(const osg::Vec3 &pos)
|
||
{
|
||
osg::Geometry *geom = new osg::Geometry();
|
||
|
||
osg::ref_ptr<osg::Vec3Array> vertex = new osg::Vec3Array();
|
||
vertex->push_back(pos);
|
||
geom->setVertexArray(vertex.get());
|
||
|
||
osg::ref_ptr<osg::Vec4Array> 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;
|
||
}
|