前一章讲了《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用法(二)相关推荐

  1. osg::ComputeBoundsVisitor用法(一)

    osg::ComputeBoundsVisitor用于获取模型或绘制几何体的最小包围盒.如下代码: #include<osg/Geometry> #include<osg/Geode ...

  2. 最重要的事情 一 、消息通信机制(1)ant 打包方法(2) system.out.println()用法 二、UML学习

    最重要的事情    一 .消息通信机制(1)ant 打包方法(2) system.out.println()用法      二.UML学习

  3. 【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 ...

  4. OSG学习:OSG组成(二)——渲染状态和纹理映射

    以下内容来自: 1.<OpenSceneGraph三维渲染引擎编程指南>肖鹏 刘更代 徐明亮 清华大学出版社  2.<OpenSceneGraph三维渲染引擎设计与实践>王锐 ...

  5. Linux九阴真经之九阴白骨爪残卷5(ansible用法二之Playbook和YAML语法)

    playbook是由一个或多个"play"组成的列表 play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色.从根本上来讲,所谓task无 ...

  6. 详解MySQL字符串函数CONCAT()、CONCAT_WS()、INSERT()、REPLACE()、LOWER()、UPPER()用法(二)

    文章目录 一.合并字符串函数CONCAT()和CONCAT_WS() 1.CONCAT() 2.CONCAT_WS() 二.替换字符串INSERT()和REPLACE 1.INSERT() 2.REP ...

  7. boost::function的用法(二)

    boost function是一组类和模板组合,用于包装各种函数.从功能上,它类似于函数指针,但是比函数指针的功能更强大. 使用boost function,必须包含头文件 [cpp] view pl ...

  8. requirejs的用法(二)

    这个系列的第一部分和第二部分,介绍了Javascript模块原型和理论概念,今天介绍如何将它们用于实战. 我采用的是一个非常流行的库require.js. 一.为什么要用require.js? 最早的 ...

  9. Android ListView常用用法(二)

    来自:51CTO论坛 原帖:http://mobile.51cto.com/android-254823.htm Android开发:实现带图片和checkbox的listview 项目要用到一个li ...

最新文章

  1. 旋转卡壳——模板(对踵点)
  2. Python中如何使用构造方法定义类
  3. SpringBoot 线程池,也太好用了叭!
  4. c# 单例 按需创建
  5. 百度2014校园招聘笔试题(成都站,软件研发岗)——2014.09.21
  6. 2015盘点最佳5笔小投资引援:骑士得枪勇士收肉盾
  7. VMware安装Linux ubuntu虚拟机
  8. mysql 按照两个字段之和进行排序
  9. MaxCompute客户端在windows命令行下查询中文乱码怎么办?
  10. Linux学习之chage命令
  11. PHPOffice下PHPWord生成Word2007(docx)使用方法
  12. java捕捉sql执行异常_如何捕获java.sql.SQLIntegrityConstraintViolationException?
  13. CSS外边距合并(塌陷/margin越界)
  14. Vivado18.3的安装 安装教程
  15. 获取任意一个微信小程序码的两种方式
  16. VCL组件DevExpress VCL v21.2 - 甘特图、网格控件升级
  17. 黄牛用高性能服务器抢票,还在找黄牛“加速”抢票?成功抢票旅客:黄牛让我去12306候补...
  18. 扬子苦荞啤酒 一杯苦荞啤酒,精彩你的世界
  19. 叮咚DsV1.0pj版(去授权)
  20. 【转】91个排名:中国知名个人站长及发家史

热门文章

  1. 基于FPGA跳舞机实现
  2. docker 删除_docker 批量删除镜像
  3. java throwable判断,Java异常处理 Throwable实现方法解析
  4. mean项目的分模块开发
  5. Docker入门(CentOS7)
  6. PHP-cli 日志彩色玩法 echo \033[1;33m Hello World. \033[0m \n;
  7. Mac系统安装nginx+rtmp模块
  8. silverlight导出excel
  9. C# 获取文件名及扩展名
  10. 随机化算法-----模拟退火