快速学习OSG(7)——几何体操作(简化几何体和三角网的绘制)
一、几何体
大家都知道场景都是由基本的绘图基元构成的,基本的绘图基元构成简单的几何体,简单的儿何体构成复杂的几何体,复杂的几何体最终构造成复杂的场景。当多个几何体组合时,可能存在多种降低场景渲染效率的原因。在很多3D引擎中,都提供了对场景的几何体进行修改的操作,以达到最优渲染效率。虽然最优渲染效率只是一个理想状态,但一定的几何体操作在相当程度上可以提高渲染效率。
在OSG中,为了获得所需的性能和渲染的效率,osgUtil 库提供了一些通用的几何体运算,这些几何体运算主要包括osgUil::simplifier (简化)、osgUil:smoothingVisitor (生成法线)、osgUtil:DelaunayTriangulator (生成Delaunay三角网工具)和ostUl:TriStripVisitor (条带化)等。下面就来介绍几种常用的几何体操作。
二、简化几何体
简化几何体(osgiUil:Simplifier) 类继承自osg:NodeVisitor类,它采用访问器的方式遍历几何体 osgUitl::Simplifier 的继承关系图osiUl:Sipliierin类对几何体的简化主要需要设置两个方面的参数,即当几何体样本比率小于1时,设置点的误差限制:当几何体的样本比率大于1时,设置边的长度限制。通过对点的误差或者边的长度的限制简化不必要的点和边,然后通过平滑处理和条带化渲染几何体,进而达到提高渲染效率的目的,也可以用于自动生成低层次模型。一般来说,样本比率越大,简化越少;样本比率越小,简化越多。优化可以直接调用下面的函数:
virtual void apply(osg:;Geode &geode) /应用于叶节点
void simplify(osg:Geomctry &geometry)/简化几何体
这两个函数同样可用于osg::Node节点,不过,关联实例时需要使用accept0方法osgUtil:Simplifier简化采用的是边塌陷算法,对于这个算法笔者并没有深入研究。目前,网上很少有关于这方面的文档。
三、简化几何体的案例
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>#include <osg/Node>
#include <osg/Geode>
#include <osg/Group>
#include <osg/PositionAttitudeTransform>#include <osgDB/Readfile>
#include <osgDB/WriteFile>#include<osgGA/StateSetManipulator>#include <osgUtil/Optimizer>
#include <osgUtil/Simplifier>int main()
{//创建Viewer对象,场景浏览器osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();//切换网络模式,方便比较模型viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));osg::ref_ptr<osg::Group> root = new osg::Group();//设置样本比率,样本简化比率越大,简化越小//样本比率越小简化越多float sampleRatio = 0.3f;//设置点的最大误差float maxError = 4.0f;//创建简化对象osgUtil::Simplifier simplifiter(sampleRatio, maxError);//读取牛模型osg::ref_ptr<osg::Node> nodel = osgDB::readNodeFile("cow.osg");//深拷贝牛的模型到node2节点osg::ref_ptr<osg::Node> node2 = (osg::Node*)(nodel->clone(osg::CopyOp::DEEP_COPY_ALL));//创建位置变化节点osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform();//设置位节点pat->setPosition(osg::Vec3(10.0f, 0.0f, 0.0f));//添加子节点pat->addChild(node2.get());//简化处理pat->accept(simplifiter);//添加场景root->addChild(nodel.get());root->addChild(pat.get());// 优化场景数据osgUtil::Optimizer optimizer;optimizer.optimize(root.get());//设置场景数据viewer->setSceneData(root.get());//初始化并创建窗口viewer->realize();//viewer->setUpViewInWindow(200, 200, 800, 800);viewer->run();return 0;
}
![](/assets/blank.gif)
四、Delaunay 三角网绘制
4.1. TIN模型
在数字地形建模中,不规则三角网(TIN)通过从不规则离散分布的数据点生成的连续三角面来逼近地形表面。就表达地形信息的角度而言,TIN模型的优点是它能以不同层次的分辨率来描述地形表面。与格网数据模型相比,TIN模型在某一特定分辨率下能用更少的空间和时间更精确地表示更加复杂的表面。特别是当地形包含有大量特征,如断裂线、构造线时,TIN 模型能更好地顾及这些特征,从而能更精确合理地表达地表形态。对于TIN模型,其基本要求有以下3点:
(1) TIN是唯一的。
(2)力求最佳三角形几何形状。
(3)保证最邻近的点构成三角形。
在所有可能的三角网中,狄洛尼(Delaunay) 三角网在地形拟合方面表现最为出色,常用于TIN的生成。当不相交的断裂线等被作为预先定义的限制条件作用于TIN的生成当中时,就必须考虑带约束条件的狄洛尼三角网。
目前,狄洛尼三角网生成的算法比较多,传统的算法主要包括两种,即Lawson算法以及Bowyer-Watson算法。后来经过该传统算法改进的算法就多了,这里不专门对这些算法予以介绍,可参考相关论文。
4.2. osgtli::DelaunayTriangulator 类
上面介绍了狄洛尼(Delaunay)三角网的特性、生成算法及应用,下面来看一下OSG中的狄洛尼三角网。创建狄洛尼三角网有如下3个步骤:
(1)创建项点数组。
(2)创建一个osgUtil:DelaunayTriangulator对象,并初始化顶点数组,同时生成三角网,程序代码如下:
bool triangulate()//开始生成三角网格
(3)创建一个几何体对象,把osgUil:DelaunayTriangulator类对象生成的绘制图元加入到几何体中。在生成狄洛尼三角网时,读者还可以添加一一些限制条件,限制条件可以是点、线或多边形,例如:
void addInputConstraint(DelaunayConstraint *dc)/添加限制条件
通过这么多的讲解,读者应该清楚了狄洛尼三角网的绘制方法了吧。有兴趣的读者可以研究关于狄洛尼三角网的算法。
五、Delaunay三角网绘制示例
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>#include <osg/Node>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Group>#include <osgGA/StateSetManipulator>#include <osgDB/Readfile>
#include <osgDB/Writefile>
#include <osgUtil/Optimizer>
#include <osgUtil/DelaunayTriangulator>
#include "Tex.h"typedef unsigned int Unit;
int main()
{osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;//方便查看在多边形之间的切换,以查看三角网viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));osg::ref_ptr<osg::Group> root = new osg::Group();//创建顶点数组osg::ref_ptr<osg::Vec3Array> coords = new osg::Vec3Array();//计算顶点数组的大小unsigned int n = sizeof(vertex) / sizeof(float[3]);//添加顶点数据for (Unit i = 0; i < n; i++){coords->push_back(osg::Vec3(vertex[i][0], vertex[i][1], vertex[i][2]));}//创建Delauny三角网对象osg::ref_ptr<osgUtil::DelaunayTriangulator> dt = new osgUtil::DelaunayTriangulator(coords.get());//生产三角网dt->triangulate();//创建几何体osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();//设置顶点数组geometry->setVertexArray(coords.get());//加入到绘图单元geometry->addPrimitiveSet(dt->getTriangles());//添加到叶子节点osg::ref_ptr<osg::Geode> geode = new osg::Geode();geode->addDrawable(geometry.get());root->addChild(geode.get());//优化场景数据osgUtil::Optimizer optimizer;optimizer.optimize(root.get());//设置场景数据viewer->setSceneData(root.get());//初始化并创建窗口viewer->realize();//viewer->setUpViewInWindow(200, 200, 800, 800);viewer->run();return 0;
}
![](/assets/blank.gif)
快速学习OSG(7)——几何体操作(简化几何体和三角网的绘制)相关推荐
- 快速学习OSG(2)——光照
一.光照简介 OSG 全面支持 OpenGL 的光照特性,包括材质属性(material property),光照属性(light property)和光照模型(lighting mo ...
- 快速学习OSG(6)——立方图纹理(天空盒)
一.立方图 立方图纹理是一种特殊的技术,它是-一个由6幅二维图像构成的.以原点为中心的纹理立方体.对于每个片段而言,纹理坐标(S,T,R)都被 当作-个方向向量来看待,每个纹理单元表示从原点所看到的纹 ...
- 【教程】Github快速学习
[教程]Github快速学习 备注 一.Git基础 1.安装 2.git原理 3.基本配置 4.Gitignore 二.Git分支 1.基础命令 三.学习Github:Github Docs官方文档 ...
- Grasshopper 学习笔记 2 Geometry 几何体(基本几何体、相关操作、自由曲面)
一些缩略词: Brep: Boundary representation 边界表示 1 基本几何体 (1)平面: Plane Surface (plane, x, y) (2)球壳: Sphere ( ...
- 字典中文乱码怎么处理_CATIA教程技巧和二次开发宏:我的零件有很多的几何体,但是几何体的名称是乱的,还有乱码,影响我的后续操作,我该怎么处理?...
如题:我的零件有很多的几何体,但是几何体的名称是乱的,还有乱码,影响我的后续操作,我该怎么处理?这种零件可能是从其他软件导过来的,然后我想分析判断,或者把每个几何体单独拆成零件,等等情况. 有的朋友问 ...
- 如何快速学习:掌握任何技能的 10 种行之有效的方法
在本文中,我们将介绍掌握任何技能的十种经过验证的方法.您将学习如何快速学习.促进个人成长并在人群中脱颖而出,而无需将每一分钟都花在阅读教科书上. 快速学习的一项关键技能 如果我告诉你有一种技能可以使任 ...
- SAP快速学习小结1
SAP快速学习小结1 一.SAP基础 SAP(System,Applications and Products in Data Processing,即数据处理的系统.应用和产品) SAP R/3 系 ...
- slua 是c语言开发的吗,初学者必备文档:LUA新手快速学习笔记
LUA程序设计语言 是一个简洁.轻量.可扩展的脚本语言.LUA读作/'lua/(噜啊),是葡萄牙语中"Luna"(月亮)的意思. LUA的目标是成为一个很容易嵌入其它语言中使用的语 ...
- 快速学习mysql_快速学习MySQL基础知识
这篇文章主要梳理了 SQL 的基础用法,会涉及到以下方面内容: SQL大小写的规范 数据库的类型以及适用场景 SELECT 的执行过程 WHERE 使用规范 MySQL 中常见函数 子查询分类 如何选 ...
最新文章
- 服务器架设笔记——使用Apache插件解析简单请求
- 暑期集训5:并查集 线段树 练习题F: HDU - 1166 ​​​​​​​
- Centos下安装FTP并进行虚拟用户访问方式配置
- wxHtml 示例:关于对话框测试
- RecyclerView复用item导致数据混乱
- nodemailer使用_如何使用Nodemailer使用HTML作为内容发送电子邮件 Node.js
- python培训班靠谱吗-什么样的python培训机构靠谱?
- count(1)与count(id)与count(*)效率,以及覆盖索引,索引下推
- 封装element分页组件
- Matlab 画图函数
- Ubuntu: 使用U盘拷贝文件
- hdu 5857 Median ★
- Python爬取《你好,李焕英》电影影评并制作词云图
- wifi WPS功能介绍
- IEC61400-6 2020 塔架及基础设计要求 附录K 翻译
- iphone原彩显示对眼睛好吗_iphonex原彩显示有必要开吗
- xctf攻防世界 MISC高手进阶区 黄金六年
- 学习英文-学以致用【场景:美式音标】
- 芯片全产业链:【设计】-【制造(原材料+制造装备+代工)】-【封装】
- 在 Ubuntu 上安装 Sublime,亲测Ubuntu 18.04.6可用