OSG粒子系统与阴影 - ​​​​​​​粒子系统的读取与保存(6)

news2024/11/29 2:34:21

粒子系统的读取与保存

        在前面的章节中,已经讲到了所有的粒子系统的基本使用方法和自定义粒子系统的方法。有时需要把一个好的粒子系统保存起来,方便以后使用。保存粒子系统可以通过简单地调用 osgDB::writeNodeFile()来完成,如果直接读取并加到根节点就可能会出现一系列的问题。当根节点进行各种矩阵变换时,读者将发现粒子系统会出现各种莫名其妙的现象,如倒转方向、消失等。造成这种现象的原因很简单,粒子系统是作为Drawable加入到叶节点Geode的,因此,对叶节点作各种矩阵变换实际上是对 Drawable进行矩阵变换,Drawable一旦进行矩阵变换,粒子系统就随之改变。因此,读取粒了系统时需要作一些处理。处理的方法有很多,例如,读取文件时,获取 Drawable 对象的句柄,然后将这个Drawable对象从读入节点的子节点中去除,并重新添加到根节点上。这种方法虽然能够达到我们所需要的目的,但是在很大程度上增加了程序的繁琐度,需要不停地删除、不停地增加。还有一种方法就是使粒子系统节点处于绝对变换下,即不受任何节点的任何矩阵变换。

        绝对变换的具体实现方法为:写一个承自osg::MatrixTransform类的新类,反转所有矩阵变换,以达到粒子系统处于绝对变换中的目的。看一下下面的示例,读者就明白该怎么做了。

        代码如程序清单11-7 所示:

1.	/* 粒子系统的读写 */  
2.	// 创建一个新的变换类  
3.	class ParticleTransform :public osg::MatrixTransform  
4.	{  
5.	public:  
6.	    class ParticleTransformCallback :public osg::NodeCallback  
7.	    {  
8.	        virtual void operator()(osg::Node *node, osg::NodeVisitor *nv)  
9.	        {  
10.	            // 得到节点  
11.	            if (ParticleTransform *ps = dynamic_cast<ParticleTransform*>(node))  
12.	            {  
13.	                osg::NodePath &fullNodePath = nv->getNodePath();  
14.	                if (fullNodePath.size() > 0)  
15.	                {  
16.	                    //fullNodePath.pop_back();  
17.	                    // 反转各种矩阵变换  
18.	                    osg::Matrix localCoordMat = osg::computeLocalToWorld(fullNodePath);  
19.	                    osg::Matrix inverseOfAccum = osg::Matrix::inverse(localCoordMat);  
20.	  
21.	                    // 设置矩阵  
22.	                    ps->setMatrix(inverseOfAccum);  
23.	                }  
24.	  
25.	  
26.	            }  
27.	            traverse(node, nv);  
28.	        }  
29.	    };  
30.	  
31.	    ParticleTransform()  
32.	    {  
33.	        // 设置更新回调  
34.	        setUpdateCallback(new ParticleTransformCallback());  
35.	    }  
36.	  
37.	};  
38.	  
39.	// 更新回调  
40.	class orbit :public osg::NodeCallback  
41.	{  
42.	public:  
43.	    // 构造函数  
44.	    orbit() :_angle(0.0){}  
45.	  
46.	    // 返回局部矩阵  
47.	    osg::Matrix getWCMatrix()  
48.	    {  
49.	        return m;  
50.	    }  
51.	  
52.	    virtual void operator()(osg::Node *node, osg::NodeVisitor *nv)  
53.	    {  
54.	        osg::ref_ptr<osg::MatrixTransform> tx = dynamic_cast<osg::MatrixTransform*>(node);  
55.	        if (tx != NULL)  
56.	        {  
57.	            _angle += 0.01;  
58.	  
59.	            // 设置矩阵旋转  
60.	            tx->setMatrix(osg::Matrix::rotate(_angle, 0.0, 0.0, 1.0));  
61.	  
62.	            // 计算由世界坐标到局部坐标  
63.	            m = osg::computeWorldToLocal(nv->getNodePath());  
64.	        }  
65.	  
66.	        traverse(node, nv);  
67.	    }  
68.	private:  
69.	    osg::Matrix m;// 矩阵  
70.	    float _angle; // 角度  
71.	  
72.	};  
73.	  
74.	/* 粒子系统的读写 */   
75.	void readAndWriteParticleSystem_11_7(const string &strDataFolder)  
76.	{  
77.	    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();  
78.	    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
79.	    traits->x = 40;  
80.	    traits->y = 40;  
81.	    traits->width = 600;  
82.	    traits->height = 480;  
83.	    traits->windowDecoration = true;  
84.	    traits->doubleBuffer = true;  
85.	    traits->sharedContext = 0;  
86.	  
87.	    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());  
88.	  
89.	    osg::ref_ptr<osg::Camera> camera = viewer->getCamera();  
90.	    camera->setGraphicsContext(gc.get());  
91.	    camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));  
92.	    GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;  
93.	    camera->setDrawBuffer(buffer);  
94.	    camera->setReadBuffer(buffer);  
95.	  
96.	    osg::ref_ptr<osg::Group> root = new osg::Group();  
97.	  
98.	    // 读取奶牛模型  
99.	    string strDataPath = strDataFolder + "cow.osg";  
100.	    osg::ref_ptr<osg::Node> cowNode = osgDB::readNodeFile(strDataPath);  
101.	  
102.	    // 读取粒子系统模型  
103.	    strDataPath = strDataFolder + "myvr.osg";  
104.	    osg::ref_ptr<osg::Node> particleNode = osgDB::readNodeFile(strDataPath);  
105.	  
106.	    // 添加矩阵变换节点  
107.	    osg::ref_ptr<osg::MatrixTransform> cowTransform = new osg::MatrixTransform();  
108.	  
109.	    // 设置更新回调  
110.	    cowTransform->setUpdateCallback(new orbit());  
111.	  
112.	    // 添加子节点  
113.	    root->addChild(cowTransform.get());  
114.	    cowTransform->addChild(cowNode.get());  
115.	  
116.	    // 创建粒子系统变换节点  
117.	    ParticleTransform *my = new ParticleTransform();  
118.	  
119.	    // 添加子节点  
120.	    my->addChild(particleNode.get());  
121.	  
122.	    cowTransform->addChild(my);  
123.	  
124.	    // 优化场景数据  
125.	    osgUtil::Optimizer optimize;  
126.	    optimize.optimize(root.get());  
127.	  
128.	    viewer->setSceneData(root.get());  
129.	  
130.	    viewer->realize();  
131.	    viewer->run();  
132.	}  

        运行程序,截图如图11-9所示。

图11-9粒子系统的读取与保存截图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1256468.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高性能Mysql第三版(一)

学习目标&#xff1a; 高性能Mysql第3版 学习内容&#xff1a; MySQL架构与历史Mysql基座测试服务器性能Schema与数据类型优化创建高性能的索引查询性能优化Mysql高级特性Explain 文章目录 学习目标&#xff1a;高性能Mysql第3版 学习内容&#xff1a;1 Mysql逻辑架构1.1 My…

【STM32单片机】贪吃蛇游戏设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用STM32F103C8T6单片机控制器&#xff0c;使用8*8LED点阵模块、矩阵按键、蜂鸣器模块等。 主要功能&#xff1a; 系统运行后&#xff0c;贪吃蛇游戏开始运行&#xff0c;默认蛇身为2节&#xff…

057-第三代软件开发-文件监视器

第三代软件开发-文件监视器 文章目录 第三代软件开发-文件监视器项目介绍文件监视器实现原理关于 QFileSystemWatcher实现代码 关键字&#xff1a; Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&…

【数据结构初阶】树,二叉树

树&#xff0c;二叉树 1.树概念及结构1.1树的概念1.2 树的相关概念1.3 树的表示1.4 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 2.二叉树概念及结构2.1概念2.2现实中的二叉树2.3 特殊的二叉树2.4 二叉树的性质2.5 二叉树的存储结构 1.树概念及结构 1.…

计算机视觉算法——基于Transformer的目标检测(DN DETR / DINO / Sparser DETR / Lite DETR)

计算机视觉算法——基于Transformer的目标检测&#xff08;DN DETR / DINO&#xff09; 计算机视觉算法——基于Transformer的目标检测&#xff08;DN DETR / DINO&#xff09;1. DN DETR1.1 Stablize Hungarian Matching1.2 Denoising1.3 Attention Mask 2. DINO2.1 Contrasti…

Map和Set小总结【温习】

目录 一、概念与模型 二、Map的使用 三、Set的说明 一些小练习 四、哈希表 1.概念 2.冲突 2.1、概念 2.2、冲突-->避免 2.3、冲突-->解决 &#xff08;1&#xff09;闭散列 &#xff08;2&#xff09;开散列 2.4、其他问题 一、概念与模型 1.概念&#xff1a…

全程云OA SQL注入漏洞复现

0x01 产品简介 全程云OA为企业提供日常办公管理、公文管理、工作请示、汇报、档案、知识体系、预算控制等26个功能&#xff0c;超过100多个子模块。为企业内部提供高效、畅通的信息渠道&#xff0c;同时也能大力推动公司信息系统发展&#xff0c;提高企业的办公自动化程度和综合…

wangeditor实时预览

<template><div><!--挂载富文本编辑器--><div style"width: 45%;float: left;margin-left: 2%"><p>编辑内容</p><div id"editor" style"height: 100%"></div></div><div style"w…

基于halo框架采用docker-compose快速部署个人博客

halo快速部署个人博客 技术方案 dockerdocker-composenginxmysql halo简介 Halo是一款现代化的开源博客/CMS系统&#xff0c;所有代码开源在GitHub上且处于积极维护状态。它是基于 Java Spring Boot 构建的&#xff0c;易于部署&#xff0c;支持REST API、模板系统、附件系…

二叉树算法—后继节点

与其明天开始&#xff0c;不如现在行动&#xff01; 文章目录 1 后继节点1.1 解题思路1.2 代码实现 &#x1f48e;总结 1 后继节点 1.1 解题思路 二叉树节点结构定义如下&#xff1a; public static class Node { public int cal; public Node left; public Node right; public…

记一次处理大数据而导致的内存溢出问题

问题 订单服务通过MQ进行订单同步时&#xff0c;刚启动可以正常消费&#xff0c;但是跑一会就会卡住&#xff0c;每次都是第8个kafka分区不行再进行消费&#xff0c;其他分区消费的很慢。 现象 首先&#xff0c;CPU超高&#xff0c;达到百分之300多&#xff1b;其次&#xf…

纯新手发布鸿蒙的第一个java应用

第一个java开发鸿蒙应用 1.下载和安装华为自己的app开发软件DevEco Studio HUAWEI DevEco Studio和SDK下载和升级 | HarmonyOS开发者 2.打开IDE新建工程&#xff08;当前用的IDEA 3.1.1 Release&#xff09; 选择第一个&#xff0c;其他的默认只能用(API9)版本&#xff0c;…

【教学类-06-09】20231126 X-Y数字分合-分-下空右

结果展示&#xff1a; 背景需求&#xff1a; 1、加减法理论上在幼儿园不适用&#xff08;虽然实际上幼儿在家早就练习了&#xff09; 2、分合题是大班教学数上涉及的内容&#xff0c;可以尝试&#xff08;类似于减法、加法&#xff09;可以用雪花片等实物进行增加、减少。——…

【教学类-06-13】20231126 (55格版)趣味题(一)1-9加法题(10倍)(整十相加)

作品展示 背景需求&#xff1a; 1、会做加法题的孩子5分钟内完成题目&#xff0c;太快了&#xff0c;所以为了拉平差异&#xff0c;需要给这些会做另外的题目&#xff0c;比如提供一些他们没有做过的“趣味题形”。 2、好多次&#xff0c;听见大班孩子在互相“考试”——“老…

数据结构与算法Java版本单元测验题

1.【实验题 2-2】实现以下对单链表的操作&#xff0c;题意和算法描述见《习题解答》图 2-7。 //将单链表 list 逆转&#xff0c;将各结点的 next 指向其前驱。泛型方法&#xff0c;返回值类型前声明类型参数 T public static void reverse(SinglyList list) 【思考题 2-6】实现…

Horizon地平线财富一直坚持“创新、开放、协作、共享”的运营理念

在“寒风凛冽”的熊市&#xff0c;投资人需要一颗不断探索、勇于尝试的心。 勇气意味着即使你知道这条路很难&#xff0c;你仍然选择坚持。而信念则是相信&#xff0c;即使现在很多人不理解、甚至嘲笑&#xff0c;未来总会有一天他们会明白。 Horizon一直坚持着“创新、开放、…

4 时间序列预测入门: LSTM+ATTENTION

0 前沿 注意力机制其本质是一种通过网络自主学习出的一组权重系数&#xff0c;并以“动态加权”的方式来强调我们所感兴趣的区域同时抑制不相关背景区域的机制。核心目标也是从众多信息中选择出对当前任务目标更关键的信息。 Multi-Head Attention&#xff08;MHA&#xff09;&…

一网打尽异步神器CompletableFuture

Future接口以及它的局限性 我们都知道&#xff0c;Java中创建线程的方式主要有两种方式&#xff0c;继承Thread或者实现Runnable接口。但是这两种都是有一个共同的缺点&#xff0c;那就是都无法获取到线程执行的结果&#xff0c;也就是没有返回值。于是在JDK1.5 以后为了解决这…

C# WPF上位机开发(掌握一点c#基础)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 wpf虽然比较简单&#xff0c;但是最好还是要有一点c#的基础比较好。本身wpf有点类似于web开发&#xff0c;前端和html差不多&#xff0c;后端则和j…

2024年第十六届山东省职业院校技能大赛中职组 “网络安全”赛项竞赛正式卷任务书

2024年第十六届山东省职业院校技能大赛中职组 “网络安全”赛项竞赛正式卷任务书 2024年第十六届山东省职业院校技能大赛中职组 “网络安全”赛项竞赛正式卷A模块基础设施设置/安全加固&#xff08;200分&#xff09;A-1&#xff1a;登录安全加固&#xff08;Windows, Linux&am…