osg三维场景中拾取鼠标在模型表面的点击点

news/2024/11/19 21:30:21/文章来源:https://www.cnblogs.com/herd/p/18555625

osg三维场景中拾取鼠标在模型表面的点击点

 

#include <osg/Group>
#include <osg/Geode>
#include <osg/ShapeDrawable>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osgGA/GUIEventHandler>
#include <osgGA/TrackballManipulator>
#include <osg/Material>
#include <osg/StateSet>
#include <osgUtil/LineSegmentIntersector>
#include <osgUtil/IntersectVisitor>#include <iostream>class PickHandler : public osgGA::GUIEventHandler {
public:PickHandler() {}virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) {osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);if (!view) return false;// 检查是否为鼠标左键点击事件if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) {performPick(ea, *view);return true;}return false;}osg::ref_ptr<osg::Geode> createRedSphere(const osg::Vec3f& position, float radius) {// 创建一个球体形状osg::ref_ptr<osg::Sphere> sphere = new osg::Sphere(position, radius);// 创建一个形状绘制对象,并设置其颜色为红色osg::ref_ptr<osg::ShapeDrawable> sphereDrawable = new osg::ShapeDrawable(sphere);sphereDrawable->setColor(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); // 红色(RGBA)// 创建一个地理节点(Geode),并将形状绘制对象添加到其中osg::ref_ptr<osg::Geode> sphereGeode = new osg::Geode();sphereGeode->addDrawable(sphereDrawable);return sphereGeode;}//
private:void performPick(const osgGA::GUIEventAdapter& ea, osgViewer::View& view) {// 将鼠标位置转换为窗口坐标int x = ea.getX();int y = ea.getY();// 创建一个射线相交检测器//osgUtil::LineSegmentIntersector* intersector = new osgUtil::LineSegmentIntersector(//    osgUtil::IntersectionVisitor::IntersectionType::FIRST, // 使用第一个相交点//    osg::Vec3(x, y, -1.0f), // 射线起点//    osg::Vec3(x, y, 1.0f)   // 射线终点//    );//osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::PROJECTION, x, y);// 执行相交检测
        osgUtil::IntersectionVisitor iv;//bool computeIntersections(float x,float y, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff);// 存储相交结果的容器
        osgUtil::LineSegmentIntersector::Intersections intersections;// 执行相交检测if (view.computeIntersections(x, y, intersections)) {// 检查是否有相交点if (!intersections.empty()) {// 获取第一个相交点//const osgUtil::LineSegmentIntersector::Intersection& intersection = intersections[0];for (const auto& intersection : intersections) {const osg::Vec3& point = intersection.getWorldIntersectPoint();std::cout << "Intersection point: " << point.x() << "    " << point.y() << "    " << point.z() << std::endl;osg::ref_ptr<osg::Geode> redSphere = createRedSphere(point, 10.1f); // 半径为1的红色球体view.getSceneData()->asGroup()->addChild(redSphere);break; // 只处理第一个相交点
                }//const osg::Vec3& point = intersection.getWorldIntersectPoint();//std::cout << "Intersection point: " << point << std::endl;
}else {std::cout << "No intersection found." << std::endl;}}else {std::cout << "No intersection found." << std::endl;}// 清理资源//delete intersector;
    }
};int main(int argc, char** argv) {osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;// 加载场景 cow.osg     excavator.OSGB    library.OSGBosg::Node* root = osgDB::readNodeFile("library.OSGB");if (!root) {std::cerr << "Error loading model" << std::endl;return 1;}viewer->setSceneData(root);// 添加鼠标拾取事件处理器viewer->addEventHandler(new PickHandler());// 开始运行return viewer->run();
}////////////////

 

 

 

 

 

 

 

 

#######################################

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/837009.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

流和向量(Streams and Vectors)

在GNU Radio的官方教程中,提到了两个重要的块连接方式:流和向量(Streams and Vectors)。具体的章节链接为: 🔗:流和向量 - GNU Radio 🔗:带有向量的 Python 块 - GNU Radio 官方文档对流和向量的概念和使用有着简介和直观的讲述,但对于两者之间的转化方法以及何时使…

接口测试之fiddler(10.2)

一、fiddler包安装 路径也尽量不要有中文安装步骤:略 二、Fiddler 简介 fiddler 是 C# 开发免费web调试工具之一,记录所有客户端和服务端常见的 http 以及 https 请求,可监视设断点,甚至修改输入输出数据,它还包含了一个强大的基于事件脚本的子系统,并且能使用 .net 语言…

JDK21新增特性

顺序集合(Sequenced Collections)提供了几个新的接口,用于实现有序的集合。在没有提供有序集合操作之前,我们进行集合的序列操作一般如下First element Last elementList list.get(0) list.get(list.size() - 1)Deque deque.getFirst() deque.getLast()SortedSet sortedSet.f…

NOIP2024加赛6

让人家来打模拟赛,被吊打了吧。一签三计数,罚坐了。 草莓 简单贪心,随便贪就过了。点此查看代码 #include<bits/stdc++.h> using namespace std; #define rep(i,s,t,p) for(int i = s;i <= t;i += p) #define drep(i,s,t,p) for(int i = s;i >= t;i -= p) #ifde…

java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法

java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法@目录一、记录文件相关操作方法二、代码1.读取路径返回List<File>2.读取路径返回List<String>3.删除文件夹4.删除文件 一、记录文件相关操作方法 二、代…

一些再也不敢了的行为

前言:考完 CSP-S 2024 才总结出来的各种离谱错误。本文不讨论类似于在有环图上跑拓扑排序这种错误,直接说会见祖宗的行为。进入考场前检查好准考证和身份证等必要物品,笔者因为这个原因 \(2024\) 年联合省选被困在了门外。由于不是正式选手,最终被放了进去。如果当前电脑运…

什么是水鱼?三分钟教会你

"水鱼"是广西人最喜欢玩的酒桌游戏,它属于扑克牌的一种玩法,经过不断改良升级而来。如果你在广西不会水鱼,那喝酒就没有了灵魂。虽然广西名族很多,水鱼玩法不一样,但是同一个框架,内容不同而已。比如有些地方黑桃花色最大,有些地方红桃花色最大,这种一般玩2,…

Oracle Linux 9.5 正式版发布 - Oracle 提供支持 RHEL 兼容发行版

Oracle Linux 9.5 正式版发布 - Oracle 提供支持 RHEL 兼容发行版Oracle Linux 9.5 正式版发布 - Oracle 提供支持 RHEL 兼容发行版 Oracle Linux with Unbreakable Enterprise Kernel (UEK) & Red Hat compatible kernel (RHCK) 请访问原文链接:https://sysin.org/blog/o…

List集合按照由小到大排序或者由大到小排序

@目录背景原代码由小到大排序由大到小排序 背景原List<User>里面是无序的,比如从redis查找等情况,查出来的是无序的,现在想按照由小到大排序或者由大到小排序。原代码 List<User> list = new ArrayList<>(); list.add(new User(3, "c", new Dat…

pta两次大作业

PTA 两次大作业总结:详细分析与实践经验 前言 回顾这次的家具强电电路模拟程序大作业,它无疑是一次极具挑战的编程与设计经历。从最初简单的电路组件模拟,到后期复杂的多设备连接和精准的控制反馈,这个过程不仅让我掌握了许多技术技能,还在思维方式、问题解决能力以及系统…

mac安装maven3.8.8

问题描述 down了一个新应用, maven依赖总是加载不到, 本地仓库也能找到, 项目启动报错 org.apache.skywalking:apm-toolkit-trace:pom:5.0.0-RC-SNAPSHOT failed to transfer from http://0.0.0.0/ during a previous attempt. This failure was cached in the local repositor…

mac 安装maven

问题描述 down了一个新应用, maven依赖总是加载不到, 本地仓库也能找到, 项目启动报错 org.apache.skywalking:apm-toolkit-trace:pom:5.0.0-RC-SNAPSHOT failed to transfer from http://0.0.0.0/ during a previous attempt. This failure was cached in the local repositor…