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

以下内容来自: 

1、《OpenSceneGraph三维渲染引擎编程指南》肖鹏 刘更代 徐明亮 清华大学出版社 
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键显示关闭光照,旋转模型,可以看出亮度不变,仔细观察显示点时的情况,可以看到一两个点。



猜你喜欢

转载自blog.csdn.net/u013719339/article/details/80729421