Jack Huang's Blog


  • 首页

  • 标签

  • 归档

  • 搜索

OSG中GLB转IVE之路

发表于 2022-01-20 | 更新于 2023-04-10

最近在使用OSG 3.4的过程中,需要将一个GLB格式的3D模型文件,转换成IVE格式,以便osgDB::readNodeFile函数加载。具体方法是通过Blender建模软件进行3D文件格式转换。这个过程中遇到很多问题,记录一下。

常用的3D文件格式

.obj

OBJ文件是Alias | Wavefront公司为它的一套基于工作站的3D建模和动画软件“AdvancedVisualizer”开发的一种标准3D模型文件格式。

应用OBJ文件一般包括三个子文件,分别是.obj、.mtl、.jpg,除了模型文件,还需要.jpg纹理文件。OBJ可以是传统模型,也可以是倾斜模型。

特点OBJ格式适合用于3D软件模型之间的互导。比如Smart3D里面生成的模型需要修饰,就可以输出OBJ格式,然后导入到3dsMax进行处理;如果你想把在3dsMax中建的模型调到Maya里面渲染或制作动画,导出OBJ文件就是一种很好的选择。

目前几乎所有知名的3D软件都支持OBJ文件的读写,不过其中很多需要通过插件才能实现。另外,OBJ文件还是一种文本文件,可以直接用写字板打开进行查看和编辑修改。值得一提的是,老子云平台能够支持OBJ格式数据的上传和OBJ格式与其它格式间的互转。

其特点如下:

  • OBJ文件是一种3D模型文件。不包含动画、材质特性、贴图路径、动力学、粒子等信息。

  • OBJ文件主要支持多边形(Polygons)模型。虽然也支持曲线(Curves)、表面(Surfaces)、点组材质(Point Group Materials),但Maya导出的OBJ文件并不包括这些信息。

  • OBJ文件支持法线和贴图坐标。OBJ只能保存贴图坐标信息,贴图需要手动重新指认,但不需要再调整贴图坐标。

.dae

COLLADA ( COLLA borative Design A ctivity ) 是一种用于交互式3D应用程序的交换文件格式。它由非营利性技术联盟Khronos Group管理,并已被 ISO 采用为公开可用的规范 ISO/PAS 17506。[1]

COLLADA 定义了一个开放的标准 XML 模式,用于在各种图形软件应用程序之间交换数字资产,否则这些应用程序可能会将其资产存储在不兼容的文件格式中。描述数字资产的 COLLADA 文档是 XML 文件,通常以.dae(数字资产交换)文件扩展名标识。

.fbx

FBX是FilmBoX软件中所使用的格式,后来这一软件改名为Motionbuilder。

应用因为Motionbuilder扮演的是动作制作平台,所以FBX格式最大的用途是在3dsMax、Maya、softimage等软件间进行模型、材质、动作和摄影机信息的互导,这样就可以发挥max和maya等各个软件的优势。可以说,FBX方案是最好的互导方案。

其优点如下:

  • FBX格式是一种3D通用模型文件。包含动画、材质特性、贴图、骨骼动画、灯光、摄像机等信息。

  • FBX格式支持多边形(Polygons)游戏模型、曲线(Curves)、表面(Surfaces)、点组材质(Point Group Materials)。

  • FBX格式支持法线和贴图坐标。贴图以及坐标信息都可以存入FBX文件中,文件导入后不需要手动指认贴图以及调整贴图坐标。

.gltf 和 .glb

glTF( Graphics Language Transmission Format或GL Transmission Format的衍生简称)是三维场景和模型的标准文件格式。glTF 文件使用两种可能的文件扩展名之一,.gltf ( JSON / ASCII ) 或 .glb ( binary )。.gltf 文件可以是自包含的,也可以引用外部二进制和纹理资源,而 .glb 文件是完全自包含的。Khronos Group开发和维护的开放标准,支持3D 模型几何、外观、场景图层次结构和动画。它旨在成为一种简化的、可互操作的格式,用于交付 3D 资产,同时最大限度地减少文件大小和应用程序的运行时处理。因此,其创建者将其描述为“ 3D JPEG ”。

应用GlTF是一种可以减少3D格式中与渲染无关的冗余数据并且在更加适合OpenGL簇加载的一种3D文件格式。GlTF的提出是源自于3D工业和媒体发展的过程中,对3D格式统一化的急迫需求。如果用一句话来描述:GlTF 就是三维文件的 JPEG ,三维格式的 MP3。在没有GlTF的时候,大家都要花很长的的时间来处理模型的载入。尽管一些3D Web框架支持特定于平台的模型格式,如FBX和OBJ,但几乎每个框架都支持GLTF。如果有人要为你提供3D模型,你可以请求他们提供GLTF格式的版本。

特点GLTF是一种输出格式,这意味着我们无法直接修改它们。但我们可以修改其位置和大小,并对其进行旋转操作。

另外,GLTF文件不是单个文件,而是包含JSON文档、图片、几何图形、纹理、凹凸贴图等的文件夹。

.OSGB

OSGB的全称是Open Scene Gragh Binary。这里的Binary是二进制的意思。

应用目前市面上生产的倾斜模型,尤其是Smart3D处理的倾斜摄影三维模型的数据组织方式一般是二进制存贮的、带有嵌入式链接纹理数据(.jpg)的OSGB格式。

特点此类数据文件碎、数量多、高级别金字塔文件大。因而难以形成高效、标准的网络发布方案,无法实现不同地域、不同部门之间的数据共享。

.ive

ive是由OpenSceneGraph(OSG)创建的三维模型文件,OSG是用于建模和动画处理的开源3D图形工具包; 包含使用该软件创建的3D场景; 用于可视化,仿真,游戏,虚拟现实和其他建模方案。IVE文件以二进制格式存储,有助于查看和渲染场景时提高性能。

OSG实用工具

osgconv

osgconv是一种非常有用的的工具来读取标准的3D格式,如OpenFlight,3DS,Alias Wavefront(OBJ) etc,并且可以将它们转换为一种OSG所支持的格式,如OSG中的ASCII格式的.osg,二进制格式的.ive。

在程序运行的默认情况下,优化导入的场景图,将形成的这样结果:场景图读取的数据量将会更少且速度会更快。尤其值得指出的是,.ive格式的的文件,快速装载数据的能力使它非常适合数据页和大型的数据库。

osgconv常用方式为:

1
2
3
4
# 将cow.obj转成ive
osgconv cow.obj cow.ive
# 沿Z轴逆时针旋转90度
osgconv -o -90-0,0,1 cow.obj cow.ive

osgviewer

osgviewer 是随 OpenSceneGraph 一起分发的基本场景图查看器。它的主要目的是一个如何编写简单查看器的示例,但它的功能也足以用作基本的 3D 图形查看器。使用方法如下:

1
osgviewer cow.ive

osg插件

OpenSceneGraph 核心发行版中有 45 个插件,它们提供了对原生和 3rd 方文件格式的读写支持。OpenSceneGraph 数据库插件库 osgDB 自动按需加载插件,使用正在加载/保存的文件的扩展名来确定要加载哪个插件。osgDB 加载必要的插件是透明的,实际上你不应该做任何特殊的事情来加载某种文件类型。唯一需要记住的因素是 OSG 需要支持文件格式(由文件的扩展名决定)并且您应该已经编译了必要的插件。

转换方法

将glb文件转换成ive文件的流程如下:

  1. 使用blender 2.92 导入 glb 文件。
  2. 使用blender 2.92 将 glb 文件导出成 dae 文件。注意导出时选择导出纹理图像。该步骤的主要目的是为了获取glb文件的纹理图像。
  3. 使用blender 2.92 将 glb 文件导出成 obj 文件。 注意导出时选择导出纹理图像。该步骤将生成.obj、.mtl、.jpg三种文件,其中.jpg是纹理图像。如果纹理图像导出失败,可使用 dae 文件的纹理图像,同时注意修改.mtl文件中纹理图像的路径。.obj、.mtl均是文本文件,可直接打开。
  4. 使用命令 osgconv -o -90-0,0,1 cow.obj cow.ive 将obj文件转换成ive文件。-o选择将模型朝向沿着坐标轴进行旋转。

转换需要注意的问题

3D文件格式转换需要注意的问题主要有:

  • blender打开glb文件渲染时出现透明区域,显示背面区域的问题。

因为对blender建模软件不够熟悉,刚开始以为是纹理贴图的问题,后面才发现是面朝向的问题。法线朝外的面是正面,朝里的面是背面。透明区域的面法线朝里,我们看到的是背面。由于blender着色器默认使用背面剔除功能,导致本应不透明的面被删除,导致出现透明区域现象。

检测方面很简单,在blender中选择“视图叠加层”->“面朝向”打勾,模型正面将显示蓝色,背面显示红色。显示红色的区域就是透明区域。

解决方法很简单,在blender中选择红色区域三角面,选择“网格”->“法线”->“翻转”, 将背面变为正面,即可解决模型显示透明区域问题。

  • blender将glb转换成obj丢失纹理问题。解决方法在转换流程中已有介绍,在此不再详述。

  • 模型朝向问题。解决方法在转换流程中已有介绍,在此不再详述。

参考链接

  1. 三维文件格式知多少 | abc、glTF、fbx、obj、dae、stl、3ds..,by 饼干教育.
  2. 超实用:一篇文章带你了解市面上主流通用的3D模型格式,by qq.
  3. COLLADA,by wikipedia.
  4. glTF,by wikipedia.
  5. osgconv使用指南(转),by 3D入魔.
  6. osgconv,by osgchina.
  7. 背面剔除,正面剔除是什么能干嘛,从Blender和Unity解读,来2个效果你就懂了,by 拉克哈尼.
  8. osgPlugins,by openscenegraph.
  9. 科普:FBX格式和OBJ格式异同,by Tech fan.

多智能体强化学习

发表于 2022-01-18 | 更新于 2022-03-03

强化学习的核心思想是“试错”(trial-and-error):智能体通过与环境的交互,根据获得的反馈信息迭代地优化。在 RL 领域,待解决的问题通常被描述为马尔科夫决策过程。

当同时存在多个智能体与环境交互时,整个系统就变成一个多智能体系统(multi-agent system)。每个智能体仍然是遵循着强化学习的目标,也就是是最大化能够获得的累积回报,而此时环境全局状态的改变就和所有智能体的联合动作(joint action)相关了。因此在智能体策略学习的过程中,需要考虑联合动作的影响。

马尔科夫决策过程拓展到多智能体系统,被定义为马尔科夫博弈(又称为随机博弈,Markov/stochastic game)。

完全合作式

完全竞争式

混合关系式

MADDPG算法

MADDPG是OpenAI给的仿真代码。

安装MADDPG

安装步骤如下:

  1. 安装pyenv,用于python的多版本管理
  2. 使用pyenv安装python 3.5.4
  3. 使用venv创建虚拟环境
  4. 使用pip安装OpenAI gym (0.10.5), tensorflow (1.8.0), numpy (1.14.5)

注意使用pip安装tensorflow (1.8.0)时,可能报错,需要先安装grpcio(1.10.1)。

参考链接

  1. 万字长文:详解多智能体强化学习的基础和应用,by 机器之心.
  2. 多智能体强化学习综述-Lucian Busoniu,by Xray.
  3. AlphaGo原来是这样运行的,一文详解多智能体强化学习的基础和应用,by 机器之心.
  4. 多智能体强化学习中的非平稳性问题,by hoogle.
  5. 深度强化学习的弱点和局限,by 论智.
  6. Self-Play:让计算机学会相扑的强化学习“左右互搏术” ,by 贪心科技.
  7. 从Fictitious Play 到 NFSP,by Yumho.
  8. 传统的战略式博弈求解方法——虚拟博弈(Fictitious Play)讲解及其代码,by 码农家园.
  9. 【论文阅读】Deep Reinforcement Learning from Self-Play in Imperfect-Information Games,by 博弈真的不简单啊.
  10. 多智能体博弈强化学习研究综述笔记,by 一丨.
  11. 多智能体博弈强化学习研究综述笔记,by 一丨.
  12. 【多智能体RL】Actor-Attention-Critic for Multi-Agent RL,by 星桥翊月.
  13. COMA:Counterfactual Multi-Agent Policy Gradients,by 张现杰.
  14. Multi-Agent Actor-Critic for Mixed Cooperative-Competitive Environments,by AHU-WangXiao.
  15. 丧的时候写写东西总没错,《Multi-Agent Actor-Critic for Mixed Cooperative-Competitive Environments》,by 王小惟 Weixun.
  16. 多智能体强化学习入门(四)——MADDPG算法,by ECKai.
  17. 从代码到论文理解并复现MADDPG算法(基于飞桨的强化学习套件PARL),by Mr.郑先生_.
  18. maddpg原理以及代码解读,by Jianeng.
  19. linux中配置MPE和MADDPG环境,by codenong.
  20. Multi-agent Particle Environment - MPE多智能体强化学习运行环境的任务简介,by 普通攻击往后拉.
  21. 左右互搏,self-play,《Emergent Complexity via Multi-Agent Competition》,by 王小惟 Weixun.
  22. 多智能体深度强化学习综述与批判,by Xray.
  23. 伯克利开源工具库 RLib 现已支持大规模多智能体强化学习,by Eric Liang.
  24. python2 安装 tensorflow 遇到问题,by leo_fengj.

OSG的observer_ptr指针

发表于 2021-12-25

observer_ptr指针,这个指针和它的名字一样,就是用来观察指针的,可以把它想象成一个观察者,它只观察一个你给他指点的对象,但是不会影响这个对象的创建和销毁,它只是一个旁观者,但是它观察的这个对象要是被销毁了它也会知道并且自己也会被销毁。和osg::ref_ptr不同,osg::ref_ptr是用来管理指针的创建和删除的。

参考链接

  1. OSG中的observer_ptr指针,by vincent-xia.

OSG中的OpenThreads库使用帮助

发表于 2021-12-24

OpenThreads库是一个轻量级的跨平台多线程库,在2.x之前是独立发展的一个库,在2.x后并入到OSG的源码中,OSG中大量的多线程操作都是基于这个库编写的。

参考链接

  1. OpenThreads库介绍——Thread,by csxiaoshui.
  2. OpenThreads库介绍——Mutex,by csxiaoshui.
  3. OpenThreads库介绍——Block,by csxiaoshui.

CPlusPlus之volatile关键字

发表于 2021-12-22

C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier。

volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。声明时语法:int volatile vInt; 当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。

当两个线程都要用到某一个变量且该变量的值会被改变时,应该用 volatile 声明,该关键字的作用是防止优化编译器把变量从内存装入 CPU 寄存器中。如果变量被装入寄存器,那么两个线程有可能一个使用内存中的变量,一个使用寄存器中的变量,这会造成程序的错误执行。volatile 的意思是让编译器每次操作该变量时一定要从内存中真正取出,而不是使用已经存在寄存器中的值。

参考链接

  1. C/C++ 中 volatile 关键字详解,by runoob.
  2. InterlockedCompareExchange用法详解,by 漂泊心情.

CPlusPlus之mutable关键字

发表于 2021-12-22

在 C++ 中,mutable 是为了突破 const 的限制而设置的。被 mutable 修饰的变量,将永远处于可变的状态,即使在一个 const 函数中,甚至结构体变量或者类对象为 const,其 mutable 成员也可以被修改。

mutable的作用有两点:

  1. 保持常量对象中大部分数据成员仍然是“只读”的情况下,实现对个别数据成员的修改;
  2. 使类的const函数可以修改对象的mutable数据成员。

使用mutable的注意事项:

  1. mutable只能作用于类的非静态和非常量数据成员。
  2. 在一个类中,应尽量或者不用mutable,大量使用mutable表示程序设计存在缺陷。

参考链接

  1. c++关键字mutable作用,by 苍老流年.
  2. C++中mutable关键字存在的必要性是什么?,by zhihu.

CPlusPlus运算符重载

发表于 2021-12-22

C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。

重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。

当您调用一个重载函数或重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。

运算符重载

您可以重定义或重载大部分 C++ 内置的运算符。这样,您就能使用自定义类型的运算符。

重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。

->重载

C++98 standard §13.5.6/1 “Class member access”:

An expression x->m is interpreted as (x.operator->())->m for a class object x of type T if T::operator-> exists and if the operator is selected at the best match function by the overload resolution mechanism (13.3).

函数重载

在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。您不能仅通过返回类型的不同来重载函数。

参考链接

  1. Is operator-> “chained” for pointers? [duplicate],by stackoverflow.

CPlusPlus迭代器

发表于 2021-12-22

iterator是不是pointer呢?要看container而定,由上可知,vector的iterator是pointer,list的iterator就不是pointer,而是object利用operator overloading使它表面上的操作像pointer而已,但並不是一個pointer。

参考链接

  1. iterator到底是不是pointer? (C/C++) (STL),by 真 OO无双.

CPlusPlus的using关键字用法

发表于 2021-12-21

C++ using关键字主要有三种用法:

  • 导入命名空间
1
2
3
4
5
// 导入整个命名空间到当前作用域
using namespace std;

// 只导入某个变量到当前作用域
using std::cout;
  • 指定别名

C++ 11 通过 using 指定别名,作用等同于 typedef,但相比 typedef,逻辑更直观,可读性更好。

1
2
typedef int T; // 用 T 代替 int
using T = int; // 用 T 代替 int
  • 在派生类中引用基类成员

using关键字可以让父类同名函数在子类中以重载方式使用。

参考链接

  1. c++11中的using关键字,by 蝶泳奈何桥.
  2. C++中using的三种用法 ,by 算法集市.

CPlusPlus的typename关键字

发表于 2021-12-21

“typename”是一个C++程序设计语言中的关键字。当用于泛型编程时是另一术语”class”的同义词。typename关键字主要功能有两项:

  • class关键字的同义词

这是一项C++编程语言的泛型编程(或曰“模板编程”)的功能,typename关键字用于引入一个模板参数。

  • 类型名指示符

显式地告诉编译器,T::bar是一个类型名。这就必须用typename关键字,而非模板类的静态变量。

参考链接

  1. typename,by wikipedia.
  2. 知无涯之C++ typename的起源与用法,by libfeihu.
上一页1…181920…53下一页

Jack Huang

521 日志
67 标签
© 2025 Jack Huang
由 Hexo 强力驱动
|
主题 — NexT.Muse