OSG鼠标点选模型,选中的模型消失:
1.模型路径
1.创建两个模型,并且把这两个模型放到Group中,并且注册鼠标点击事件处理
void mousePick2() {
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
viewer->addEventHandler(new osgViewer::WindowSizeHandler());
viewer->addEventHandler(new MouseHandler2());
osg::ref_ptr<osg::Group> root = new osg::Group;
root->setName("ROOT");
osg::ref_ptr<osg::Node> n1 = osgDB::readNodeFile("cow.osgt");
osg::ref_ptr<osg::Node> n2 = osgDB::readNodeFile("xyz.osgt");
root->addChild(n1);
root->addChild(n2);
viewer->setSceneData(root.get());
viewer->realize();
viewer->run();
}
鼠标点击事件:
class MouseHandler2 :public osgGA::GUIEventHandler {
public:
MouseHandler2();
~MouseHandler2();
private:
virtual bool handle(const osgGA::GUIEventAdapter&ea, osgGA::GUIActionAdapter&aa)override;
void pick(osgViewer::View* view, float x, float y);
};
#include "MouseHandler2.h"
MouseHandler2::MouseHandler2() {
}
MouseHandler2::~MouseHandler2() {
}
bool MouseHandler2::handle(const osgGA::GUIEventAdapter&ea, osgGA::GUIActionAdapter&aa) {
osg::ref_ptr<osgViewer::View> view = dynamic_cast<osgViewer::Viewer*>(&aa);
if (!view) {
return false;
}
osgGA::GUIEventAdapter::EventType eventType = ea.getEventType();
switch (eventType) {
case osgGA::GUIEventAdapter::PUSH://鼠标按下
if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) {
pick(view, ea.getX(), ea.getY());
}
break;
case osgGA::GUIEventAdapter::DRAG://鼠标拖动
break;
case osgGA::GUIEventAdapter::RELEASE://鼠标松开
if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) {
}
break;
default:
break;
}
return false;
}
void MouseHandler2::pick(osgViewer::View* view, float x, float y) {
osgUtil::LineSegmentIntersector::Intersections intersections;
if (view->computeIntersections(x, y, intersections)) {
osgUtil::LineSegmentIntersector::Intersections::iterator inter = intersections.begin();//获取第一个点
const osg::NodePath& nodePath = inter->nodePath;//获取第一个交点的Path
for (int i = 1; i < nodePath.size() - 1; i++) {
std::string name = nodePath[i]->getName();
qDebug() << QString::fromStdString(name);
}
}
}
运行结果,“坐标模型”是在“牛模型”的内部:
点击模型的时候,可以在【输出】界面打印出模型的路径(这里的路径指的是模型的数据组织)信息:
比如点击牛的时候:
"ROOT"
"cow.osg"
当进入到牛的内部的时候,点击坐标信息的时候,输出的信息:
"ROOT"
"axes.osg"
2.坐标系模型在牛模型的内部不是很好看,我们可以把牛模型缩小一下:
void mousePick2() {
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
viewer->addEventHandler(new osgViewer::WindowSizeHandler());
viewer->addEventHandler(new MouseHandler2());
osg::ref_ptr<osg::Group> root = new osg::Group;
root->setName("ROOT");
osg::ref_ptr<osg::Node> n1 = osgDB::readNodeFile("cow.osgt");
osg::ref_ptr<osg::MatrixTransform>mt = new osg::MatrixTransform;
mt->setName("MatrixTransform");//注意:设置一个名称
osg::Matrix matrix;
matrix.makeScale(osg::Vec3(0.3,0.3,0.3));
mt->setMatrix(matrix);
mt->addChild(n1);
osg::ref_ptr<osg::Node> n2 = osgDB::readNodeFile("xyz.osgt");
root->addChild(mt);
root->addChild(n2);
viewer->setSceneData(root.get());
viewer->realize();
viewer->run();
}
运行结果:
当再次点击牛的时候,打印出来的信息:
"ROOT"
"MatrixTransform"
"cow.osg"
当点击坐标系的X轴的时候,打印出来的信息:
"ROOT"
"axes.osg"
2.隐藏模型
1.由上面的打印信息可以看出,模型总是在最后一层,所有我们只需要不模型最后一层获取到就可以了,选中的就是当前点击的模型。
代码:
void MouseHandler2::pick(osgViewer::View* view, float x, float y) {
osgUtil::LineSegmentIntersector::Intersections intersections;
if (view->computeIntersections(x, y, intersections)) {
osgUtil::LineSegmentIntersector::Intersections::iterator inter = intersections.begin();//获取第一个点
const osg::NodePath& nodePath = inter->nodePath;//获取第一个交点的Path
osg::ref_ptr<osg::Node> node = new osg::Node;
node = nodePath.at(nodePath.size() - 1);
if (node!=nullptr){
node->setNodeMask(0);
}
}
}