simulationMaster/MousePicker.cpp
2021-12-23 17:46:55 +08:00

152 lines
5.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}