OSG学习:几何体的操作(一)——交互事件、简化几何体

以下内容来自: 

1、《OpenSceneGraph三维渲染引擎编程指南》肖鹏 刘更代 徐明亮 清华大学出版社 
2、《OpenSceneGraph三维渲染引擎设计与实践》王锐 钱学雷 清华大学出版社

3、自己的总结

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


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

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

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


本篇文章解析简化几何体的方法:

osgUtil::Simplifier类继承自osg::NodeVisitor类,以访问器的方式遍历几何体并对其进行简化处理。

这个简化方法使用边塌陷算法,该算法我没有详细了解,可以看一看这篇文章:实现边塌陷的网格简化方法

扫描二维码关注公众号,回复: 1671025 查看本文章


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

// stdafx.h 

#include <osg/Node> //节点类
#include <osg/Geode> //是个几何节点,可以说是一个几何Group节点,一般的可绘制几何体都是通过它来传向root进行渲染,是OSG几何绘制的最高管理节点
#include <osg/Group> //对节点起到组织作用,一般作为父节点或者根节点出现
#include <osg/PositionAttitudeTransform> //位置变换节点类,提供模型的位置变换、大小缩放、原点位置的设置、坐标系的变换

#include <osgDB/ReadFile>
#include <osgDB/WriteFile> 

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers> //事件监听

#include <osgGA/StateSetManipulator> //事件响应类,对渲染状态进行控制

#include <osgUtil/Optimizer> //优化器
#include <osgUtil/Simplifier> //简化几何体
//.cpp

/*
加载一个模型
深拷贝该模型到其他地方
对深拷贝的模型进行简化
将两个模型添加到叶节点
对场景进行优化
显示模型
按w键显示网格化模型,可以看出网格密度不同
按t键显示去表皮模型,可以看出模型相同
*/

//读取模型
osg::Node *readModel()
{
	osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");
	return node.release();
}

//深拷贝并简化新模型
osg::Node *deepCopy(osg::Node *node)
{
	/*
	创建简化对象
	simplifier(sampleRatio, maxError)
	参数:样本比率、点的误差或边的长度
	样本比率<1 设置点的误差
	样本比率>1 设置边的长度限制
	比率越大,简化越少
	使用的是边塌陷算法
	*/
	float sampleRatio = 0.3f;
	float maxError = 4.0f;
	osgUtil::Simplifier simplifier(sampleRatio, maxError);

	//深拷贝
	osg::ref_ptr<osg::Node> deepnode = (osg::Node *)(node->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(deepnode);

	pat->accept(simplifier);

	return pat.release();
}

int main()
{
	//创建一个叶节点对象并添加节点 
	osg::ref_ptr<osg::Group> root = new osg::Group;
	osg::ref_ptr<osg::Node> node1 = readModel();
	osg::ref_ptr<osg::Node> node2 = deepCopy(node1);
	root->addChild(node1);
	root->addChild(node2);

	//优化场景数据
	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键显示网格模型,可以看出格网密度不同;

按t键显示去皮模型,可以看出无差别。



猜你喜欢

转载自blog.csdn.net/u013719339/article/details/80728882
今日推荐