osg::ComputeBoundsVisitor用法(二)
前一章讲了《osg::ComputeBoundsVisitor用法(一)》,现在继续讲osg::ComputeBoundsVisitor用法。
osg::ComputeBoundsVisitor可以用于在场景中较精确估计模型移动的距离,便于和外部传入的逻辑移动的距离进行交互。例如:现有一个这样的场景:
如上图是一个振动台,台子由两个osg模型文件构成,下面的一个osg如下:
上面的osg模型(为便于后文表述,称之为 盖子)缓缓移动插入到下面的底座中, 盖子下移或上升的逻辑距离即外部传入距离为【0, 160】区间内,即下图所示:
先说明物理距离和逻辑距离的概念:
- 物理距离:是指模型文件中的实际距离。
- 逻辑距离:是指外部调用方传入的需要模型移动的距离,其往往和模型文件中距离不同。(这两个距离参见后文样例)
问题的提出:
- 当外部传入要让上面的盖子模型下降或上升Height逻辑距离,如 120 时,对上面的盖子在osg类似osg::Matrix::translate函数中的第三个参数即Z轴上设置的具体数值是多少?
解决方法如下:
利用如下代码算出整个盖子从160下降到0的距离,也即银白色支柱完全被盖子遮住时,盖子下降的高度,可以随便摆个按钮,把下面代码放在按钮单击事件函数中,不停单击按钮,直到银白色支柱部分被上面的盖子下降完全盖住为止,算出后再删除该按钮,按钮仅仅由于探测用:
// 没有被其它函数调用,用于在实际测试中探测盖子上升或下降能移动的最大距离
void CLaunchWnd::getHolderTranslateHeight()
{static int n = 0;osg::Matrix curMatrix;// 先记录盖子当前位置z轴的最小值osg::ComputeBoundsVisitor boundVisitor;// m_spMatrixTransformHolder1->accept(boundVisitor);float fZMin = boundVisitor.getBoundingBox().zMin();QString qsZMin = QString::number(fZMin);CLogToolKits::getInstance()->writeLog(qsZMin.toStdWString());curMatrix = m_spMatrixTransformHolder1->getMatrix();// 再相应地移动盖子,看盖子能上升到的最大距离curMatrix *= osg::Matrix::translate(0, 0, ++n);m_spMatrixTransformHolder1->setMatrix(curMatrix);// 只要模型的位置发生了变化,就要重新调用accept一次。m_spMatrixTransformHolder1->accept(boundVisitor);fZMin = boundVisitor.getBoundingBox().zMin();qsZMin = QString::number(fZMin);// 再次记录盖子当前位置z轴的最小值CLogToolKits::getInstance()->writeLog(qsZMin.toStdWString());
}
说明:上面代码中m_spMatrixTransformHolder1定义为:osg::ref_ptr<osg::MatrixTransform>m_spMatrixTransformHolder1,其是盖子模型的父节点。
通过记录未移动之前和移动之后两次的zMin到日志,可以算出银白色支柱完全被盖子罩住即银白色支柱的高度。日志记录如下:
当盖子位于最大位置时,如果再执行上面代码,盖子和银白色支柱就要分离了,如下:
所以盖子下落或上升的最大物理位移为:4669.22 - 43444.22,因为盖子是匀速下落或上升,可以通过等比例关系算出盖子的移动逻辑距离,如下:
double dfHolderPhysicsMaxHeight = 4699.22;
double dfHolderPhysicsMinHeight = 4344.22; // 盖子能够上升或下降的最大物理位移
double dfMaxPhysicsHolderWeiYi = dfHolderPhysicsMaxHeight - dfHolderPhysicsMinHeight ; // dfCurHeight是外部传入的盖子需要移动的逻辑位移,dfOldHeight是盖子上一次移动的逻辑位移
double dfHolderLogicWeiYi = dfCurHeight - dfOldHeight; // 盖子移动的逻辑位移// 通过逻辑位移,算出盖子移动的物理位移,等比例关系换算而成
dfHolderLogicWeiYi dfHolderPhysicsWeiYi = dfMaxPhysicsHolderWeiYi * dfHolderLogicWeiYi / 160;osg::Matrix curMatrix = spMatrixTransformHolder->getMatrix();
curMatrix *= osg::Matrix::translate(0, 0, nHolderPhysicsWeiYi);
spMatrixTransformHolder->setMatrix(curMatrix);
可以看到本场景通过osg::ComputeBoundsVisitor很好解决了,需要说明的是:上述的等比例关系是在盖子匀速情况下才成立,且只要模型的位置发生了变化即调用translate或缩放即调用了scale之类的函数,就要重新调用osg::ComputeBoundsVisitor类的accept函数一次,以获取最新的位置信息。
osg::ComputeBoundsVisitor用法(二)相关推荐
- osg::ComputeBoundsVisitor用法(一)
osg::ComputeBoundsVisitor用于获取模型或绘制几何体的最小包围盒.如下代码: #include<osg/Geometry> #include<osg/Geode ...
- 最重要的事情 一 、消息通信机制(1)ant 打包方法(2) system.out.println()用法 二、UML学习
最重要的事情 一 .消息通信机制(1)ant 打包方法(2) system.out.println()用法 二.UML学习
- 【Linux命令】ip addr、ip link、ifconfig 用法 二
文章目录 1. 前言 2. ip link 2.1 ip link add 2.1.1 命令实例 2.2 ip link set 2.3 ip link show 2.4 ip link delete ...
- OSG学习:OSG组成(二)——渲染状态和纹理映射
以下内容来自: 1.<OpenSceneGraph三维渲染引擎编程指南>肖鹏 刘更代 徐明亮 清华大学出版社 2.<OpenSceneGraph三维渲染引擎设计与实践>王锐 ...
- Linux九阴真经之九阴白骨爪残卷5(ansible用法二之Playbook和YAML语法)
playbook是由一个或多个"play"组成的列表 play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色.从根本上来讲,所谓task无 ...
- 详解MySQL字符串函数CONCAT()、CONCAT_WS()、INSERT()、REPLACE()、LOWER()、UPPER()用法(二)
文章目录 一.合并字符串函数CONCAT()和CONCAT_WS() 1.CONCAT() 2.CONCAT_WS() 二.替换字符串INSERT()和REPLACE 1.INSERT() 2.REP ...
- boost::function的用法(二)
boost function是一组类和模板组合,用于包装各种函数.从功能上,它类似于函数指针,但是比函数指针的功能更强大. 使用boost function,必须包含头文件 [cpp] view pl ...
- requirejs的用法(二)
这个系列的第一部分和第二部分,介绍了Javascript模块原型和理论概念,今天介绍如何将它们用于实战. 我采用的是一个非常流行的库require.js. 一.为什么要用require.js? 最早的 ...
- Android ListView常用用法(二)
来自:51CTO论坛 原帖:http://mobile.51cto.com/android-254823.htm Android开发:实现带图片和checkbox的listview 项目要用到一个li ...
最新文章
- 旋转卡壳——模板(对踵点)
- Python中如何使用构造方法定义类
- SpringBoot 线程池,也太好用了叭!
- c# 单例 按需创建
- 百度2014校园招聘笔试题(成都站,软件研发岗)——2014.09.21
- 2015盘点最佳5笔小投资引援:骑士得枪勇士收肉盾
- VMware安装Linux ubuntu虚拟机
- mysql 按照两个字段之和进行排序
- MaxCompute客户端在windows命令行下查询中文乱码怎么办?
- Linux学习之chage命令
- PHPOffice下PHPWord生成Word2007(docx)使用方法
- java捕捉sql执行异常_如何捕获java.sql.SQLIntegrityConstraintViolationException?
- CSS外边距合并(塌陷/margin越界)
- Vivado18.3的安装 安装教程
- 获取任意一个微信小程序码的两种方式
- VCL组件DevExpress VCL v21.2 - 甘特图、网格控件升级
- 黄牛用高性能服务器抢票,还在找黄牛“加速”抢票?成功抢票旅客:黄牛让我去12306候补...
- 扬子苦荞啤酒 一杯苦荞啤酒,精彩你的世界
- 叮咚DsV1.0pj版(去授权)
- 【转】91个排名:中国知名个人站长及发家史
热门文章
- 基于FPGA跳舞机实现
- docker 删除_docker 批量删除镜像
- java throwable判断,Java异常处理 Throwable实现方法解析
- mean项目的分模块开发
- Docker入门(CentOS7)
- PHP-cli 日志彩色玩法 echo \033[1;33m Hello World. \033[0m \n;
- Mac系统安装nginx+rtmp模块
- silverlight导出excel
- C# 获取文件名及扩展名
- 随机化算法-----模拟退火