OSG学习:几何体的操作(二)――交互事件、Delaunay三角网绘制

匿名 (未验证) 提交于 2019-12-03 00:30:01


2、《OpenSceneGraph三维渲染引擎设计与实践》王锐 钱学雷 清华大学出版社

3、自己的总结

创建C++项目后,首先需要配置OSG环境,具体步骤看OSG学习:WIN10系统下OSG+VS2017编译及运行第六步:新建OSG项目测试。


首先重新来看一下场景的构成:基本的绘图基元――场景:

基本的绘图基元――简单的几何体――复杂的几何体――复杂的场景。

对几何体进行适当地修改,可以提高渲染效率。这些操作都由osgUtil库提供,主要有简化osgUtil::Simplifier、生成法线osgUtil::SmoothingVisitor(OSG学习:几何对象的绘制(二)――简易房屋:创建人字顶部分)、生成Delaunay三角网osgUtil::DelaunayTriangulator、条带化osgUtil::TriStripVisitor等。


本篇文章解析生成Delaunay三角网的方法:

不规则三角网TIN是数字地形建模中表达地形表面的重要手段,它通过不规则离散分布的数据点生成的连续三角面来逼近地形表面,它能以不同层次的分辨率来描述地形表面,地形平坦的地方点稀疏三角网较大且稀疏,地形陡峭的地方三角网小且密集。

狄洛尼Delaunay三角网是所有可能的三角网中在地形拟合方面最出色的方法。生成Delaunay三角网的传统算法主要为Lawson算法和Bowyer-Watson算法。

步骤:

1)创建顶点数组;

2)创建osgUtil::DelaunayTriangulator类对象并初始化顶点数组,同时生成三角网;

3)创建一个几何体对象,把osgUtil::DelaunayTriangulator类对象生成的绘制图元加入到几何体中,在生成三角网时还可以添加限制条件:点、线、多边形。


根据代码来了解使用方法:

// stdafx.h   #include <osg/Node> //节点类 #include <osg/Geode> //是个几何节点,可以说是一个几何Group节点,一般的可绘制几何体都是通过它来传向root进行渲染,是OSG几何绘制的最高管理节点 #include <osg/Group> //对节点起到组织作用,一般作为父节点或者根节点出现 #include <osg/Geometry> //基本绘制几何体类,用户绘制基本的几何体  #include <osgDB/ReadFile> #include <osgDB/WriteFile>   #include <osgViewer/Viewer> #include <osgViewer/ViewerEventHandlers> //事件监听  #include <osgGA/StateSetManipulator> //事件响应类,对渲染状态进行控制  #include <osgUtil/Optimizer> //优化器 #include <osgUtil/DelaunayTriangulator> //Delaunay三角网
//.cpp  /* 创建顶点数组并添加数据 设置其他相关属性(可选) 创建osgUtil::DelaunayTriangulator类对象并生成三角网 创建几何体对象,把三角网类对象生成的绘制图元添加到几何体中 按w键显示网格化模型,可以看出网格密度不同 由于光照条件默认开启,旋转模型可以看出不同部位亮度显示不同 按l键显示关闭光照,旋转模型,可以看出亮度不变 */  osg::Drawable *createTriangulate() { 	//创建顶点数组 	osg::ref_ptr<osg::Vec3Array> coords = new osg::Vec3Array(); 	//不同于前面例子中添加数组数据的方法,先获取顶点的值并设置为数组,然后将数组值添加到顶点数组 	//设置顶点的值 	float vertex[][3] = { -5.0f,-5.0f, 0.4f, 		1.0f, -5.6f, 0.0f, 		5.0f, -4.0f, -0.5f, 		-6.2f, 0.0f, 4.2f, 		-1.0f,-0.5f, 4.8f, 		4.3f, 1.0f, 3.0f, 		-4.8f, 5.4f, 0.3f, 		0.6f, 5.1f,-0.8f, 		5.2f, 4.5f, 0.1f }; 	//计算顶点数组的大小 	unsigned int n = sizeof(vertex) / sizeof(float[3]); 	//添加顶点数据 	for (unsigned int i = 0; i < n; i++) 	{ 		coords->push_back(osg::Vec3(vertex[i][0], vertex[i][1], vertex[i][2])); 	}  	//创建颜色数组 	osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array(); 	//添加颜色数据   	color->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 	color->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 	color->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); 	color->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f)); 	color->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 	color->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 	color->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f)); 	color->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f)); 	color->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));  	//创建Delaunay三角网对象 	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->setColorArray(color.get()); 	//设置颜色的绑定方式为单个顶点 	geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); 	//添加到绘图基元 	geometry->addPrimitiveSet(dt->getTriangles());  	return geometry.release(); }  int main() { 	//添加到叶节点 	osg::ref_ptr<osg::Geode> geode = new osg::Geode(); 	geode->addDrawable(createTriangulate());  	//添加到根节点 	osg::ref_ptr<osg::Group> root = new osg::Group(); 	root->addChild(geode.get());  	//优化场景数据 	osgUtil::Optimizer optimizer; 	optimizer.optimize(root.get());  	osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer(); 	//方便查看在多边形之间切换,以查看三角网 	viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet())); 	viewer->setSceneData(root.get()); 	viewer->realize(); 	return viewer->run(); }

查看效果:

按w键显示网格模型,可以看出格网密度不同,由于点很少,因此当按两次w键后显示的点看不出来;

由于光照条件默认开启,旋转模型可以看出不同部位亮度显示不同,按l键显示关闭光照,旋转模型,可以看出亮度不变,仔细观察显示点时的情况,可以看到一两个点。



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!