OSG 自定义场景漫游示例
一下代码可以简单实现osg中视角的简单自由漫游.并且可以进行简单的碰撞检测
mian.cpp
1 #include <osgViewer/Viewer> 2 3 #include <osg/Node> 4 #include <osg/Geode> 5 #include <osg/Group> 6 7 #include <osgDB/ReadFile> 8 #include <osgDB/WriteFile> 9 10 #include <osgUtil/Optimizer> 11 12 #include "ManipulatorTravel.h" 13 14 int main() 15 { 16 //创建Viewer对象,场景浏览器 17 osgViewer::Viewer* viewer = new osgViewer::Viewer(); 18 19 //把漫游器加入到场景中 20 TravelManipulator::TravelToScene(viewer); 21 22 osg::Group* root = new osg::Group(); 23 24 //读取地形模型 25 osg::Node* node = new osg::Node(); 26 node = osgDB::readNodeFile("lz.osg"); 27 28 //添加到场景 29 root->addChild(node); 30 31 //优化场景数据 32 osgUtil::Optimizer optimizer ; 33 optimizer.optimize(root) ; 34 35 viewer->setSceneData(root); 36 37 viewer->realize(); 38 39 viewer->run(); 40 41 return 0 ; 42 }
ManipulatorTravel.h
#pragma once#include <osgViewer/Viewer>#include <osg/LineSegment> #include <osg/Point> #include <osg/Geometry> #include <osg/Node> #include <osg/Geode> #include <osg/Group>//#include <osgGA/MatrixManipulator> #include <osgUtil/IntersectVisitor>#include <vector>class TravelManipulator : public osgGA::CameraManipulator { public://构造函数 TravelManipulator ();//析构函数 ~TravelManipulator(void);// 把漫游加入到场景之中 static TravelManipulator * TravelToScene(osg::ref_ptr <osgViewer::Viewer> viewer);private: osg::ref_ptr <osgViewer::Viewer> m_pHostViewer;//移动速度 float m_fMoveSpeed; // osg::Vec3 m_vPosition; // osg::Vec3 m_vRotation;public://鼠标左键是否按下 bool m_bLeftButtonDown ;//鼠标X,Y float m_fpushY;float m_fpushX;//设置矩阵 virtual void setByMatrix(const osg::Matrixd& matrix); //设置逆矩阵 virtual void setByInverseMatrix(const osg::Matrixd& matrix); //得到矩阵 virtual osg::Matrixd getMatrix(void) const; //得到逆矩阵 virtual osg::Matrixd getInverseMatrix(void)const ;//事件处理函数 virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);// 屏目角度 float m_fAngle;// 位置变换函数 void ChangePosition(osg::Vec3& delta);//碰撞检测是否开启 bool m_bPeng;//设置速度 float getSpeed() ;void setSpeed(float &) ;//设置起始位置 void SetPosition(osg::Vec3 &position) ;osg::Vec3 GetPosition() ;} ;
ManipulatorTravel.cpp
#include "ManipulatorTravel.h"//构造函数 TravelManipulator::TravelManipulator(): m_fMoveSpeed(1.0f) , m_bLeftButtonDown(false) , m_fpushX(0) , m_fAngle(2.5) , m_bPeng(true) , m_fpushY(0) { m_vPosition = osg::Vec3(-22.0f, -274.0f, 100.0f);m_vRotation = osg::Vec3(osg::PI_2, 0.0f, 0.0f);} //析构函数 TravelManipulator::~TravelManipulator() { // } // 把漫游加入到场景之中 TravelManipulator * TravelManipulator::TravelToScene(osg::ref_ptr <osgViewer::Viewer> viewer) { TravelManipulator* camera = new TravelManipulator;viewer->setCameraManipulator(camera) ;camera->m_pHostViewer =viewer ;return camera; }// 设置矩阵 void TravelManipulator::setByMatrix(const osg::Matrixd& matrix) { // } //设置逆矩阵 void TravelManipulator::setByInverseMatrix(const osg::Matrixd& matrix) { // } //得到矩阵 osg::Matrixd TravelManipulator::getMatrix(void) const { osg::Matrixd mat;mat.makeRotate(m_vRotation._v[0], osg::Vec3(1.0f, 0.0f, 0.0f),m_vRotation._v[1], osg::Vec3(0.0f, 1.0f, 0.0f),m_vRotation._v[2], osg::Vec3(0.0f, 0.0f, 1.0f));return mat * osg::Matrixd::translate(m_vPosition); } //得到逆矩阵 osg::Matrixd TravelManipulator::getInverseMatrix(void) const { osg::Matrixd mat;mat.makeRotate(m_vRotation._v[0], osg::Vec3(1.0f, 0.0f, 0.0f),m_vRotation._v[1], osg::Vec3(0.0f, 1.0f, 0.0f),m_vRotation._v[2], osg::Vec3(0.0f, 0.0f, 1.0f));return osg::Matrixd::inverse(mat * osg::Matrixd::translate(m_vPosition)); } //事件处理函数 bool TravelManipulator::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us) { //得到鼠标的位置 float mouseX = ea.getX(); float mouseY = ea.getY();switch(ea.getEventType()) { case(osgGA::GUIEventAdapter::KEYDOWN): { //空格键 if (ea.getKey() == 0x20) { us.requestRedraw();us.requestContinuousUpdate(false);return true; } //上移动 if (ea.getKey() == 0xFF50) { ChangePosition(osg::Vec3 (0, 0, m_fMoveSpeed)) ;return true; } //下移动 if (ea.getKey() == 0xFF57) { ChangePosition(osg::Vec3 (0, 0, -m_fMoveSpeed)) ;return true; } //增加速度 if (ea.getKey() == 0x2B) { m_fMoveSpeed += 1.0f;return true; } //减少速度 if (ea.getKey() == 0x2D) { m_fMoveSpeed -= 1.0f;if (m_fMoveSpeed < 1.0f) { m_fMoveSpeed = 1.0f; } return true; } //前进 if (ea.getKey() == 0xFF52 || ea.getKey () == 0x57 || ea.getKey () == 0x77)//up {ChangePosition(osg::Vec3 (0, m_fMoveSpeed * sinf(osg::PI_2+m_vRotation._v[2]), 0)) ;ChangePosition(osg::Vec3 (m_fMoveSpeed * cosf(osg::PI_2+m_vRotation._v[2]), 0, 0)) ;return true; } //后退 if (ea.getKey() == 0xFF54 || ea.getKey () == 0x53 || ea.getKey () == 0x73 )//down { ChangePosition(osg::Vec3 (0, -m_fMoveSpeed * sinf(osg::PI_2+m_vRotation._v[2]), 0)) ;ChangePosition(osg::Vec3(-m_fMoveSpeed * cosf(osg::PI_2+m_vRotation._v[2]), 0, 0)) ;return true; } //向左 if (ea.getKey () == 0x41||ea.getKey () == 0x61) { ChangePosition(osg::Vec3 (0, m_fMoveSpeed * cosf(osg::PI_2+m_vRotation._v[2]), 0)) ;ChangePosition(osg::Vec3 (-m_fMoveSpeed * sinf(osg::PI_2+m_vRotation._v[2]), 0, 0)) ;return true; } //向右 if (ea.getKey () == 0x44||ea.getKey () == 0x64) { ChangePosition(osg::Vec3 (0,-m_fMoveSpeed * cosf(osg::PI_2+m_vRotation._v[2]), 0)) ;ChangePosition(osg::Vec3 (m_fMoveSpeed * sinf(osg::PI_2+m_vRotation._v[2]), 0, 0)) ;return true; } //Right if (ea.getKey() == 0xFF53) { m_vRotation._v[2] -= osg::DegreesToRadians(m_fAngle); } //Left if (ea.getKey()== 0xFF51) { m_vRotation._v[2] += osg::DegreesToRadians(m_fAngle); } //改变屏角 if (ea.getKey() == 0x46 || ea.getKey() == 0x66)//F { m_fAngle -= 0.2 ;return true ; }if (ea.getKey() == 0x47 || ea.getKey() == 0x67)//G { m_fAngle += 0.2 ;return true ; }return false; } //鼠标按下 case (osgGA::GUIEventAdapter ::PUSH ):if ( ea.getButton () == 1) { m_fpushX = mouseX ; m_fpushY = mouseY ;m_bLeftButtonDown = true ; }return false ;//拖动 case (osgGA::GUIEventAdapter ::DRAG ):if ( m_bLeftButtonDown){ m_vRotation._v[2] -= osg::DegreesToRadians(m_fAngle * (mouseX-m_fpushX));m_vRotation._v[0] += osg::DegreesToRadians(1.1*(mouseY-m_fpushY)) ;if (m_vRotation._v [0] >= 3.14) { m_vRotation._v [0] = 3.14 ; }if (m_vRotation._v [0] <= 0) { m_vRotation._v [0] = 0 ; } }return false ; //鼠标释放 case (osgGA::GUIEventAdapter ::RELEASE ):if ( ea.getButton () == 1) { m_bLeftButtonDown = false ; }return false ;default: return false; } }// 位置变换函数 void TravelManipulator::ChangePosition(osg::Vec3& delta) { //碰撞检测 if (m_bPeng) { //得到新的位置 osg::Vec3 newPos1 = m_vPosition + delta;osgUtil::IntersectVisitor ivXY; //根据新的位置得到两条线段检测 osg::ref_ptr<osg::LineSegment> lineXY = new osg::LineSegment(newPos1, m_vPosition);osg::ref_ptr<osg::LineSegment> lineZ = new osg::LineSegment(newPos1+osg::Vec3(0.0f,0.0f,10.0f), newPos1-osg::Vec3(0.0f,0.0f,-10.0f)) ;ivXY.addLineSegment(lineZ.get()) ;ivXY.addLineSegment(lineXY.get()) ; //结构交集检测 m_pHostViewer->getSceneData()->accept(ivXY) ; //如果没有碰撞检测 if(!ivXY.hits()) { m_vPosition += delta; } } else { m_vPosition += delta; }}//设置速度 void TravelManipulator::setSpeed (float &sp) { m_fMoveSpeed = sp ; }//得到当前速度 float TravelManipulator::getSpeed() { return m_fMoveSpeed ; }//设置起始的位置 void TravelManipulator::SetPosition (osg::Vec3 &position) { m_vPosition = position ; }//得到当前的所在位置 osg::Vec3 TravelManipulator::GetPosition () { return m_vPosition ; }
转载于:https://www.cnblogs.com/HUNTUN/p/5601758.html
OSG 自定义场景漫游示例相关推荐
- #游戏unity-VR场景漫游#有关VR环境的搭建【HTC vive】
#游戏unity-VR场景漫游#有关VR环境的搭建[HTC vive] 需要解释的一点是,上一周赶上清明假期,我们团队确认了分工和计划后,就各自开始行动了,以至于忘记了更博客,差的两篇博客都会在这一周 ...
- unity3d 工厂模型源码 带漫游示例
unity3d 工厂模型,带漫游示例.资源包和工程源码,需要安装untiy2018版本,双击package文件打开工程. 工程代码 脚本代码 解压后web目录直接拷贝到tomcat发布访问, 页面示例 ...
- Unity3d 简单的小球沿贝塞尔曲线运动(适合场景漫游使用)
简单的小球沿贝塞尔曲线运动,适合场景漫游使用 贝塞尔曲线:(贝塞尔曲线的基本想法部分摘自http://blog.csdn.net/u010019717/article/details/4768 ...
- boost::geometry模块自定义指针到点示例
boost::geometry模块自定义指针到点示例 实现功能 C++实现代码 实现功能 boost::geometry模块自定义指针到点示例 C++实现代码 #include <boost/f ...
- 【Python】自定义排序函数 - 示例
自定义排序函数 - 示例 自定义排序规则: def cmp_value_p_code_big(o1, o2):"""排序规则: value大,排前面"" ...
- Cesium for Unreal 数据加载 场景漫游 粒子效果 视频监控 VR预览
Cesium for Unreal: Cesium出了UE插件后一直没有时间学习体验,而且也从来没有接触过UE开发,只是在网上看过一些用UE做的数字孪生的案例,看上去确实是十分炫酷,正好最近工作不是很 ...
- OpenGL---GLUT教程(六) GLUT场景漫游
GLUT教程 键盘控制例子:场景漫游 让我们看一个比较好的使用键盘控制的例子.这一章我们将建立一个应用程序.这个程序绘制了一个小的居住着雪人的世界.并且我们将用方向键来移 ...
- unity虚拟现实技术场景漫游
unity实现第一人称场景漫游项目,主要包含如下功能: 1.场景搭建 场景主要包括水.草.树木.石头.飘动的白云,房子等. 2.模型导入 这个场景就导入了一个桥和一个房子,这个桥横跨在小溪的两边,我们 ...
- MIGO 行项目屏幕自定义字段增强示例
继上次抬头屏幕增强(MIGO 抬头屏幕自定义字段增强示例),本文章演示行项目增强示例 实现思路参考标准 MB_MIGO_BADI 增强示例类:CL_EXM_IM_MB_MIGO_BADI 1.创建增强 ...
最新文章
- 用Python写出Gameboy模拟器,还能训练AI模型:丹麦小哥的大学项目火了
- sklearn快速入门教程:(一)准备工作
- 概率论与数理统计中的算子半群 第一讲 Banach-Steinhaus定理1 Baire‘s Category与Banach-Steinhaus定理的证明
- 任务——μ/COS-II读书笔记
- IntelliJ IDEA 2020.1 快速查找文件
- 最优布线问题(信息学奥赛一本通-T1349)
- python来构建多层网络
- hiveserver2的高可用HA
- 汇编学习(五)——表处理程序
- 数据预处理与特征工程—6.Kaggle房价预测中数据预处理与特征工程
- ssd1306 oled 行扫描方式
- 利用YYLabel实现图文混排
- 【三维目标检测可视化】三维点云目标检测与图像融合可视化
- slic codec
- Excel表头怎么设计?这里有超全面的表头设计方法!一分钟可学会
- datagrid表格序号列
- 【图像配准】基于光流场算法Horn_Schunck和Brox及Lucas_Kanade实现医学图像配准matlab代码
- 休闲平台,何去何从?(1)
- 计算机考研代码854,哈工大计算机考研考纲854计算机基础
- 【转贴】英语如此简单
热门文章
- 美国加州中学课本 教材介绍 - Glencoe系列- 美国初中语文 数学 科学 健康
- IAP 促销优惠(promotional offer)后端接入指南
- 路由器交换与配置综合实验(二)外网
- 【单调队列优化dp】jzoj4883灵知的太阳信仰 纪中集训提高B组
- ecg 幅度_ECG(心电图)
- ZooKeeper设置ACL权限控制--增加访问ip白名单
- Three.js学习五——让模型沿着轨迹移动
- 尤雨溪大大在 6 月 4 日的 Vue3.0 技术分享
- 英汉翻译对照之视频声频媒体处理
- 王姨劝我学HarmonyOS鸿蒙2.0系列教程之四Git搭建下载实例!