一下代码可以简单实现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 自定义场景漫游示例相关推荐

  1. #游戏unity-VR场景漫游#有关VR环境的搭建【HTC vive】

    #游戏unity-VR场景漫游#有关VR环境的搭建[HTC vive] 需要解释的一点是,上一周赶上清明假期,我们团队确认了分工和计划后,就各自开始行动了,以至于忘记了更博客,差的两篇博客都会在这一周 ...

  2. unity3d 工厂模型源码 带漫游示例

    unity3d 工厂模型,带漫游示例.资源包和工程源码,需要安装untiy2018版本,双击package文件打开工程. 工程代码 脚本代码 解压后web目录直接拷贝到tomcat发布访问, 页面示例 ...

  3. Unity3d 简单的小球沿贝塞尔曲线运动(适合场景漫游使用)

        简单的小球沿贝塞尔曲线运动,适合场景漫游使用 贝塞尔曲线:(贝塞尔曲线的基本想法部分摘自http://blog.csdn.net/u010019717/article/details/4768 ...

  4. boost::geometry模块自定义指针到点示例

    boost::geometry模块自定义指针到点示例 实现功能 C++实现代码 实现功能 boost::geometry模块自定义指针到点示例 C++实现代码 #include <boost/f ...

  5. 【Python】自定义排序函数 - 示例

    自定义排序函数 - 示例 自定义排序规则: def cmp_value_p_code_big(o1, o2):"""排序规则: value大,排前面"" ...

  6. Cesium for Unreal 数据加载 场景漫游 粒子效果 视频监控 VR预览

    Cesium for Unreal: Cesium出了UE插件后一直没有时间学习体验,而且也从来没有接触过UE开发,只是在网上看过一些用UE做的数字孪生的案例,看上去确实是十分炫酷,正好最近工作不是很 ...

  7. OpenGL---GLUT教程(六) GLUT场景漫游

    GLUT教程                键盘控制例子:场景漫游 让我们看一个比较好的使用键盘控制的例子.这一章我们将建立一个应用程序.这个程序绘制了一个小的居住着雪人的世界.并且我们将用方向键来移 ...

  8. unity虚拟现实技术场景漫游

    unity实现第一人称场景漫游项目,主要包含如下功能: 1.场景搭建 场景主要包括水.草.树木.石头.飘动的白云,房子等. 2.模型导入 这个场景就导入了一个桥和一个房子,这个桥横跨在小溪的两边,我们 ...

  9. MIGO 行项目屏幕自定义字段增强示例

    继上次抬头屏幕增强(MIGO 抬头屏幕自定义字段增强示例),本文章演示行项目增强示例 实现思路参考标准 MB_MIGO_BADI 增强示例类:CL_EXM_IM_MB_MIGO_BADI 1.创建增强 ...

最新文章

  1. 用Python写出Gameboy模拟器,还能训练AI模型:丹麦小哥的大学项目火了
  2. sklearn快速入门教程:(一)准备工作
  3. 概率论与数理统计中的算子半群 第一讲 Banach-Steinhaus定理1 Baire‘s Category与Banach-Steinhaus定理的证明
  4. 任务——μ/COS-II读书笔记
  5. IntelliJ IDEA 2020.1 快速查找文件
  6. 最优布线问题(信息学奥赛一本通-T1349)
  7. python来构建多层网络
  8. hiveserver2的高可用HA
  9. 汇编学习(五)——表处理程序
  10. 数据预处理与特征工程—6.Kaggle房价预测中数据预处理与特征工程
  11. ssd1306 oled 行扫描方式
  12. 利用YYLabel实现图文混排
  13. 【三维目标检测可视化】三维点云目标检测与图像融合可视化
  14. slic codec
  15. Excel表头怎么设计?这里有超全面的表头设计方法!一分钟可学会
  16. datagrid表格序号列
  17. 【图像配准】基于光流场算法Horn_Schunck和Brox及Lucas_Kanade实现医学图像配准matlab代码
  18. 休闲平台,何去何从?(1)
  19. 计算机考研代码854,哈工大计算机考研考纲854计算机基础
  20. 【转贴】英语如此简单

热门文章

  1. 美国加州中学课本 教材介绍 - Glencoe系列- 美国初中语文 数学 科学 健康
  2. IAP 促销优惠(promotional offer)后端接入指南
  3. 路由器交换与配置综合实验(二)外网
  4. 【单调队列优化dp】jzoj4883灵知的太阳信仰 纪中集训提高B组
  5. ecg 幅度_ECG(心电图)
  6. ZooKeeper设置ACL权限控制--增加访问ip白名单
  7. Three.js学习五——让模型沿着轨迹移动
  8. 尤雨溪大大在 6 月 4 日的 Vue3.0 技术分享
  9. 英汉翻译对照之视频声频媒体处理
  10. 王姨劝我学HarmonyOS鸿蒙2.0系列教程之四Git搭建下载实例!