搜索
您的当前位置:首页正文

基于gltf的三维模型服务关键技术研究与实现

来源:知库网
摘要

摘要

Web技术的发展,特别是HTML5新特性的广泛支持,为实现跨设备、跨平台、免插件的交互式三维地理应用提供了良好的基础。但是随着三维建模技术和三维扫描仪等三维模型获取技术的快速发展,三维模型数量呈现出了几何级增长的趋势,由于三维模型的结构复杂、类型多样等特点,致使三维模型格式一直缺乏相应的标准规范。大量现有的三维模型格式在内容完整性、编码性能和访问开放性等方面都各有缺陷,难以相互转换,严重影响了三维模型资源的共享与重用。并且在城市三维模型可视化中存在的三维模型数据量大、显示效率要求高等问题都还缺乏相应的解决方案。

针对上述问题,本文提出了选择glTF格式作为标准三维模型格式并构建基于glTF格式的三维瓦片金字塔的解决思路。本文所做的工作有:

(1)研究了glTF三维模型格式,分析了三维模型中各种元素的存储方法,针对三维模型数据占用存储空间大的问题,提出了glTF模型数据存储的优化方案。

(2)提出了将Collada作为中间格式实现各种模型格式向glTF格式转换的思路,设计实现了Collada格式到glTF格式的转换工具,并对模型格式转换工具的功能、完整性和处理效率进行了试验。

(3)设计实现了基于OSG平台的glTF可视化插件和管理glTF文件的模型资源浏览器。对glTF三维模型可视化的渲染和动画效果、以及glTF模型管理功能进行了试验。

(4)提出了在三维模型文件中添加模型属性的解决方案,设计实现了基于glTF的三维瓦片文件格式和从glTF格式到三维瓦片格式的转换工具,并对该转换工具进行了功能测试。

(5)提出了三维瓦片文件的组织和管理方案,设计了三维瓦片金字塔结构,并基于该结构实现了对瓦片金字塔的构建和可视化功能。

综上所述,本文构建了以glTF格式为基础的三维模型处理、管理和可视化服务,并实现了对三维瓦片金字塔的构建和可视化。本文的研究内容对城市三维模型资源的共享、管理及可视化具有重要的参考意义。

关键词:glTF, 三维模型, 三维瓦片, 空间数据结构, 三维瓦片金字塔

I

ABSTRACT

ABSTRACT

With the development of HTML5, the realization of interactive 3D geography applications which are across devices, cross-platform and plug-free has a good foundation. However, with the rapid development of 3D model acquisition technology such as 3D modeling technology and 3D scanner, the number of 3D models shows a trend of geometric growth. Due to the complex structure and various types of 3D models, the 3D model hasn’t have a standard format. A large number of existing 3D model formats are flawed in terms of content integrity, coding performance and openness, and are difficult to convert each other, which seriously affects the sharing and reuse of 3D assets. There are also many problems in 3D city models. For example, due to the complexity of models’ structure, and the high demand of network transmission, the visualization of 3D city models still lacks a corresponding solution.

In view of the above problems, this dissertation puts forward a solution, which selects glTF as standard 3D format and constructs 3D tiles pyramid based on glTF. The work done in this dissertation is as follows.

(1) Various elements in glTF are studied. And an optimization scheme to reduce glTF file footprint is proposed.

(2) An approach to achieve the conversion from other model formats to glTF is proposed, which uses Collada as the intermediate model format. The software that converts Collada to glTF is designed and implemented. Functions, completeness and processing efficiency of the software are tested.

(3) A scheme that realizes the visualization and management of glTF is proposed. A OSG plugin that visualizes glTF and a glTF assets manager based on Three.js are designed and implemented. The functions of plugin and assets manager are tested.

(4) A technology called 3D tiles that merges glTF assets and attributes is proposed. The software that realizes main data porcessing steps from glTF to 3D tiles is designed and implemented. All functions of the software are tested.

III

西安电子科技大学硕士学位论文

(5)A scheme for organizing and managing 3D tiles is proposed. The structure of 3D tiles pyramid is designed. The construction and visualization of 3D tiles pyramid are implemented and tested.

In summary, this dissertation constructs 3D model services of processing, management and visualization based on glTF, designs the structure of 3D tiles pyramid and implements the construction and visualization of 3D tiles pyramid. The content of this dissertation has great reference significance for reusing, managing and visualizing 3D city models.

Keywords: glTF, 3D models, 3D tiles, spatial data structure, 3D tiles pyramid

IV

插图索引

插图索引

图2.1 图2.2 图2.3 图2.4 图2.5 图2.6 图2.7 图2.8 图2.9 图3.1 图3.2 图3.3 图3.4 图3.5 图3.6 图3.7 图3.8 图3.9

图3.10 图3.11 图3.12 图3.13 图3.14 图3.15 图3.16 图3.17 图3.18 图3.19 图3.20 图4.1 图4.2

glTF文件组织结构图 ................................................................................. 6 场景图 ........................................................................................................... 7 场景图在JSON中的描述 ........................................................................... 8 元素之间应用关系图 ................................................................................. 10 OSG程序层次结构 ................................................................................... 11 OSG组成模块图 ....................................................................................... 12 场景图示例 ................................................................................................. 13 场景树结构图 ............................................................................................. 13 状态树结构图 ............................................................................................. 14 八分向量编码过程 ..................................................................................... 18 Collada格式模型资源存储结构图 ........................................................... 20 Collada2glTF模块总体设计 ..................................................................... 20 Rest3D流程图 ........................................................................................... 22 Rest3D模块数据转换类图 ....................................................................... 23 Rest3D模块数据存储类图 ....................................................................... 24 osgdb_glTF模块图 .................................................................................... 25 数据加载解析流程图 ................................................................................. 26 数据存储类图 ............................................................................................. 27

元素数据引用关系图 ................................................................................. 28 元素数据解析过程图 ................................................................................. 29 动画创建流程图 ......................................................................................... 31 关键帧动画创建函数关系图 ..................................................................... 32 动画数据解析图 ......................................................................................... 33 文件组织结构图 ......................................................................................... 34 数据服务流程图 ......................................................................................... 35 模型资源库目录页面构建流程图 ............................................................. 36 glTF三维模型可视化效果图 .................................................................... 38 模型资源目录实现效果图 ......................................................................... 39 模型资源浏览实现效果图 ......................................................................... 39 批次表示例图 ............................................................................................. 41 b3dm文件布局 .......................................................................................... 42

V

西安电子科技大学硕士学位论文 图4.3 图4.4 图4.5 图4.6 图4.7 图4.8 图4.9

图4.10图4.11 图4.12图4.13图4.14图5.1 图5.2 图5.3 图5.4 图5.5 图5.6 图5.7 图5.8 图5.9

图5.10图5.11 图5.12图5.13图5.14图5.15图5.16图5.17图5.18

批次表在glTF中应用 ............................................................................... 43 特征表示例图 ............................................................................................ 44 i3dm结构图 ............................................................................................... 44 pnts结构图 ................................................................................................ 45 glTF转换b3dm流程图 ............................................................................ 46 Mesh元素添加批ID属性图 .................................................................... 47 technique元素添加批ID属性图 ............................................................. 48

program元素添加批ID属性图 ................................................................ 48 glTF转换i3dm流程图 ............................................................................. 49 b3dm三维瓦片文件效果图 ...................................................................... 50 i3dm三维瓦片文件效果图 ....................................................................... 50 pnts三维瓦片文件效果图 ......................................................................... 51 点四叉树示例图 ........................................................................................ 54 PR四叉树示例图 ...................................................................................... 54 MX四叉树示例图 .................................................................................... 54 宽松四叉树示例图 .................................................................................... 55 适配空间四叉树示例图 ............................................................................ 55 content.boundingVolume与boundingVolume区别 ................................. 57 transform属性计算规则 ........................................................................... 58 瓦片结构图 ................................................................................................ 58 tilesets组织结构图 .................................................................................... 59

引用外部瓦片文件条件 ............................................................................ 59 外部瓦片的偏移使用图 ............................................................................ 60 四叉树组织三维瓦片金字塔结构图 ........................................................ 61 创建三维瓦片金字塔流程图 .................................................................... 62 三维瓦片金字塔调度图 ............................................................................ 63 三维瓦片金字塔渲染调度图 .................................................................... 64 三维瓦片金字塔效果图 ............................................................................ 65 建筑物选中效果图 .................................................................................... 65 点击建筑物效果图 .................................................................................... 66

VI

表格索引

表格索引

表2.1 表3.1 表3.2 表5.1

glTF元素与OSG类对应关系表 .............................................................. 15 关键帧数据类型表 ..................................................................................... 32 模型转换前后对比表 ................................................................................. 38 三维瓦片元数据表 ..................................................................................... 56

VII

缩略语对照表

缩略语对照表

缩略语 英文全称 中文对照

API b3dm CAD CAM CityGML FPS GDAL

GLSL glTF GPU HLSL i3dm JPEG JSON KD LOD

OpenGL OpenGL ES OSG SAH TIFF

VRML WebGL WGS84 XML

Application Programming Interface

Batched 3Dimensional Model Computer Aided Design

Computer Aided Manufacturing City Geography Markup Language Frames Per Second

Geospatial Data Abstraction Library Graphics Library Shading Language GL Transmission Format Graphics Processing unit

High Level Shader Language Instanced 3Dimensional Model Joint Photographic Experts Group

JavaScript Object Notation K-Dimensional Levels of Detail

Open Graphics Library OpenGL for Embedded System

OpenSceneGraph

Surface Area Heuristic Tag Image File Format Virtual Reality Modeling Language Web Graphics Library

World Geodetic System 1984 Extensible Markup Language

IX

应用程序编程接口 批量三维模型 计算机辅助设计 计算机辅助制造 城市地理标记语言 中央处理器

栅格空间数据转换库 图形库着色语言 图形库传输格式 图形处理器 高级着色器语言 实例化三维模型 联合图像专家小组 JavaScript对象标记语言K维空间 多细节层次 开放图形库

嵌入式系统开放图形库 开源场景图形库 表面积启发 标签图像文件格式 虚拟现实建模语言 Web图形库 全球定位系统 可扩展标记语言

目录

目录

摘要 ........................................................................................................................................ I ABSTRACT ........................................................................................................................ III 插图索引 .............................................................................................................................. V 表格索引 ............................................................................................................................ VII 缩略语对照表 ..................................................................................................................... IX 第一章

1.1 1.2

绪论 ...................................................................................................................... 1 研究背景与意义 .................................................................................................. 1 国内外研究现状 .................................................................................................. 2 1.2.1 三维模型文件格式研究现状 ................................................................... 2 1.2.2 城市三维模型应用研究现状 ................................................................... 3 1.3 1.4 第二章

2.1

论文研究内容 ...................................................................................................... 3 论文组织结构 ...................................................................................................... 4 论文相关技术研究 .............................................................................................. 5 glTF格式分析 ..................................................................................................... 5 2.1.1 glTF格式介绍 .......................................................................................... 5 2.1.2 文件组织结构分析 ................................................................................... 6 2.1.3 数据模型研究 ........................................................................................... 7 2.2

OSG可视化关键技术研究 ............................................................................... 11 2.2.1 OSG平台介绍 ........................................................................................ 11 2.2.2 OSG场景组织及渲染分析研究 ............................................................ 12 2.3 第三章

3.1

glTF与OSG可视化结合 ................................................................................. 14 glTF模型转换及可视化的设计与实现 ........................................................... 17 数据存储优化 .................................................................................................... 17 3.1.1 顶点数据存储优化 ................................................................................. 17 3.1.2 法向量数据存储优化 ............................................................................. 18 3.2

glTF模型转换设计与实现 ............................................................................... 19 3.2.1 glTF模型转换设计思路 ........................................................................ 19 3.2.2 Collada2glTF转换工具总体设计 .......................................................... 20 3.2.3 命令行模块设计与实现 ......................................................................... 21 3.2.4 Rest3D模块设计与实现 ........................................................................ 21 3.3

glTF基于OSG可视化的设计及实现 ............................................................. 25

XI

西安电子科技大学硕士学位论文 3.4

3.5

第四章

4.1

4.2

4.3

第五章

5.1 5.2

5.3

5.4 第六章

6.1

3.3.1 文件加载模块设计与实现 ..................................................................... 26 3.3.2 场景渲染模块设计与实现 ..................................................................... 28 3.3.3 动画实现模块设计与实现 ..................................................................... 30 模型资源浏览器设计及实现 ........................................................................... 33 3.4.1 glTF模型数据服务设计及实现 ............................................................ 34 3.4.2 模型浏览器页面设计及实现 ................................................................. 36 效果试验 ........................................................................................................... 37 3.5.1 glTF模型转换效率试验 ........................................................................ 37 3.5.2 glTF基于OSG可视化效果试验 .......................................................... 38 3.5.3 模型资源浏览器效果试验 ..................................................................... 38

基于glTF的三维瓦片格式设计与实现 .......................................................... 41 三维瓦片格式设计 ........................................................................................... 41 4.1.1 b3dm瓦片设计 ....................................................................................... 41 4.1.2 i3dm瓦片设计 ........................................................................................ 43 4.1.3 pnts瓦片设计 ......................................................................................... 45 glTF转换三维瓦片 ........................................................................................... 46 4.2.1 glTF转换b3dm设计实现 ..................................................................... 46 4.2.2 glTF转换i3dm设计实现 ...................................................................... 49 效果试验 ........................................................................................................... 50 4.3.1 b3dm效果试验 ....................................................................................... 50 4.3.2 i3dm效果试验 ........................................................................................ 50 4.3.3 pnts效果试验 ......................................................................................... 51

三维瓦片金字塔的设计与实现 ....................................................................... 53 四叉树 ............................................................................................................... 53 三维瓦片金字塔设计及构建 ........................................................................... 55 5.2.1 三维瓦片元数据设计 ............................................................................. 55 5.2.2 三维瓦片元数据文件组织结构设计 ..................................................... 59 5.2.3 三维瓦片金字塔的构建设计与实现 ..................................................... 60 三维瓦片金字塔的可视化设计与实现 ........................................................... 63 5.3.1 三维瓦片金字塔调度 ............................................................................. 63 5.3.2 三维瓦片金字塔渲染 ............................................................................. 64 效果试验 ........................................................................................................... 64 总结与展望 ....................................................................................................... 67 总结 ................................................................................................................... 67

XII

目录

6.2 展望 .................................................................................................................... 67

参考文献 ............................................................................................................................. 69 致谢 ..................................................................................................................................... 71 作者简介 ............................................................................................................................. 73

XIII

第一章 绪论

第一章

1.1 研究背景与意义

绪论

Web技术的发展,特别是HTML5新特性的广泛支持,为实现跨设备、跨平台、免插件的交互式三维实时应用提供了良好的基础,在娱乐、工业制造、数字城市等领域都有迫切需求。基于web的三维可视化技术也得到了快速的发展,并有着广泛的应用。但传统的用于实现三维数据的Web3D技术包括,VRML、X3D、Java3D等技术,都需要安装插件或者加载组件,而且具有操作性复杂、兼容性差等缺点[1]。因此未来的网络三维模型发展方面是实现Web3D免插件环境。WebGL的出现为web浏览器带来无插件三维图形加速,其兼容性强、渲染效果好,取得了众多浏览器生产厂商支持。WebGL技术的出现使得三维数据可以直接显示在网络浏览器中,而无需再加载任何插件[2]。

标准数据格式是实现Web应用的基本前提,如在传统的媒体中,音频中的MP3、视频中的H.264、图像中的JPEG等都是很成熟、高效的标准格式。对于三维模型而言,它是构造虚拟三维场景的基础数据,其数据量都比较大,因此三维模型数据格式必须要具备打包传输、快速加载、完整的场景描述、可扩展等特点。但是在目前的三维模型格式中,由于三维模型结构复杂、类型多样,一直没有相应的标准格式规范,使得现有的三维模型格式在内容完整性、编码性能、解析效率及访问开放性等方面各有缺陷,难以相互转换,严重影响了三维模型资源的共享与重用。

寻求高性能的应用程序很少直接加载建模数据。相反,他们将模型作为自定义内容管道的一部分进行离线处理,并将模型数据转化为私有格式,这种私有格式主要是为了对运行时应用程序进行优化。这就导致了各种格式之间的不兼容,并且在管道的创建方面浪费不必要的精力[3]。除非将原始数据再转化为另一种应用程序支持的数据格式,否则为一种应用程序导出的3D模型数据是不能够被另一种应用程序使用的。

对于城市中的大量三维模型数据如地势、建筑物、点云的组织管理也出现新的问题,不同于二维资源的管理,传统的管理模式在三维模型中并不适用。如在二维地图瓦片中的传统的KD树分割方法,由于三维模型在地图中的分布的离散性,使得按照传统的分割方法,不能满足其在渲染效率上的要求。

由于上述的三维模型的现状,解决三维模型的重用与共享及对大规模三维模型的管理显示问题变得日益重要。

1

西安电子科技大学硕士学位论文 1.2 国内外研究现状

1.2.1

三维模型文件格式研究现状

现有的三维模型文件格式都是由各个公司根据不同的需求设计实现的,由于每个公司开发的模型标准不同,这就导致模型资源的共享性和可重用性差等问题[4],目前主流的三维模型文件格式主要有:3DS、STL、OBJ等。

(1)OBJ文件格式

OBJ文件是Alias Wavefront公司设计的一种标准三维模型文件格式,该格式开始时被用作基于工作站的3D建模和动画软件开发,可以通过三维建模软件Maya进行读写[5]。OBJ文件可以使用文本编辑器直接打开查看、编辑,因为在OBJ文件中所有的模型信息都是以纯文本的形式存放。目前几乎所有的三维建模软件支持对OBJ文件的读写,但大多都需要添加相应的插件。

目前主流的OBJ版本为v3.0。OBJ文件优点在于它不含有任何的文件头,使得对OBJ文件的解析比较简单。而且模型的贴图坐标可以通过软件直接写入到OBJ文件中,在使用其他软件打开该文件时,只需调整纹理图像的路径即可,不需要重新调整贴图坐标[6]。但是OBJ文件格式也存在很多的不足,首先是模型格式之间的转换问题,由于目前大多数的三维模型格式只支持三点组成的面,而在OBJ中含有三个以上的点组成的面,因此在转换过程中需要进行三角化处理。其次OBJ作为模型存储文件没有存储模型的动画、模型组织结构、光照等信息[7]。

(2)3DS文件格式

3DS文件格式是由3D Studio三维建模软件生成的三维图形文件格式,是由Autodesk公司提出设计的[8],目前已经成为非常普遍的数据格式并且有着非常丰富的三维模型文件库。3DS文件可以直接由三维建模软件3D Studio直接制作导出,非常的方便。

3DS文件是由块组成的,该文件中定义的块有:初始块、主块、对象块、摄像机块、光源块、三角形列表块、关键帧块、视口块、颜色块等[9],从其定义的块中可以看出,3DS文件几乎存储了模型的所有信息,但正是由于其包含的内容太多,使3DS文件显得臃肿且混乱,而且其最大的缺点是对这些属性的定义是不对用户开放的。

(3)STL文件格式

STL文件格式是目前快速成型技术中应用最广泛的三维模型文件格式,它是由3D System公司进行设计开发的,主流的三维建模软件都支持直接导出此种格式文件

[10]

。STL文件是由三角形面片构成的,每个三角形面片由三角形顶点的坐标值和法STL文件中表示的物体几何模型是以三角形集合存储的,它除了物体的几何信息

2

向量值组成,通常STL文件有ASCII和二进制两种格式。

第一章 绪论

外,并没有存储任何几何体之间的拓扑关系[11]。而且在STL文件中,不支持颜色材质等信息。

1.2.2 城市三维模型应用研究现状

CityGML是一种城市地理标记语言,它使用XML格式来表示城市三维对象信息模型,主要用于存储和交换虚拟三维城市中的数据模型。CityGML定义了城市地理对象和它们之间的关系,并且充分考虑了模型的几何、语义等属性[12]。

在CityGML中,所有的属性被分为5个不同层次的细节(LOD),低细节层次中含有模型较少的细节,高细节层次中含有模型较多的细节。在CityGML文件中每个对象可以含有多个细节层次。LOD0表示地域模型即2.5D的数字地形图,LOD1、LOD2、LOD3都表示城市、场地模型,在LOD1中显示的只是粗略的楼块模型,LOD2的模型中包含贴图和建筑物粗模,LOD3中则包含了更细节的建筑模型,LOD4表示室内模型,可以进入建筑模型内部[13]。虽然CityGML作为目前最广泛应用的管理存储大量三维模型的技术,但是它通常并不直接用作数据的传输模型,因为CityGML严格使用空间参考系统中的坐标并允许复杂的3D多边形来建模对象。

1.3 论文研究内容

本文针对目前三维模型资源的共享与重用及城市三维模型可视化中存在的三维模型数量多、结构复杂、数据量大、网络传输与显示效率要求高等问题,提出了选择glTF格式作为标准三维模型格式并构建基于glTF格式的三维瓦片金字塔的解决思路,并设计实现相关功能、服务。具体的研究内容包括:

(1)研究glTF三维模型格式,分析三维模型中各种元素的存储方法,提出对glTF模型数据存储的优化方案。

(2)设计将Collada作为中间格式实现各种模型格式向glTF格式转换的解决方案,实现Collada格式到glTF格式的转换工具,并对转换工具的功能、效率进行试验。

(3)设计实现glTF文件在OSG平台的可视化插件和用于glTF模型管理、预览的模型资源浏览器,对模型资源浏览器和OSG可视化做效果试验。

(4)设计在三维模型文件中添加模型属性的解决方案,实现基于glTF的三维瓦片文件格式和从glTF格式到三维瓦片格式的转换工具。

(5)设计对三维瓦片文件进行组织和管理的三维瓦片金字塔结构,并实现对瓦片金字塔的构建和可视化功能。

3

西安电子科技大学硕士学位论文 1.4 论文组织结构

根据本文的研究内容,将论文的章节安排如下:

第一章:绪论。阐述本文的研究背景与意义,介绍研究的内容、国内外基本现状及本文的组织结构。

第二章:论文相关技术研究。分析glTF文件格式,研究glTF格式的特点、内部组织结构及数据模型;研究用于glTF可视化的OSG平台。

第三章:glTF模型转换及可视化的设计与实现。提出对glTF数据存储的优化方案,设计实现从Collada文件转换为glTF文件的模型转换工具,实现glTF文件格式在OSG平台的可视化和对模型管理、预览的模型资源浏览器。

第四章:基于glTF的三维瓦片格式设计与实现。设计基于glTF文件格式的三维瓦片文件格式b3dm和i3dm,并实现将glTF文件转换为三维瓦片文件的转换工具。

第五章:三维瓦片金字塔的设计与实现。研究目前空间数据管理的数据结构,使用空间数据结构管理三维瓦片文件,构建三维瓦片金字塔,并实现城市三维模型的可视化。

第六章:总结与展望。总结本文的工作,提出后续的相关工作内容。

4

第二章 论文相关技术研究

第二章

2.1 glTF格式分析

2.1.1

glTF格式介绍

论文相关技术研究

glTF[14]是GL Transmission Format的简称,是为了方便三维模型的网络传输而设计的三维模型文件格式。传统的3D模型格式设计为脱机使用存储数据,主要是为了在桌面操作系统上支持编辑工作流。行业标准的3D交换格式允许在不同的建模工具之间以及在内容管道内共享数据,但这些格式都没有对下载速度和运行时的快速加载进行优化并且无法满足Web传输和解析上的要求。模型文件也非常的大,并且应用程序需要进行大量的处理操作来将这些数据加载到基于GL的应用程序中。

随着基于移动和Web的3D计算的出现,出现了需要快速、动态加载标准3D模型数据的新类型应用程序,比如:数字营销解决方案、电子商务可视化、在线模型共享网站,这些都是目前基于WebGL和OpenGL ES建立的连接3D模型的应用程序。这些在线应用除了要求有效的数据传输外,同样需要一个能够在用户之间、应用程序之间甚至在异构的分布式内容管道之间实现数据共享和重利用的标准3D模型格式[15]。

glTF通过提供一个运营商和运行时中立的格式来解决这些问题,它可以用最少的处理来实现加载和显示。这种格式将一个用于场景描述的、易于解析的JSON文件和几个用于存储几何、动画和其他数据的二进制文件结合。由于使用二进制存储使得数据可以直接被加载到GL缓冲器中而不用其他额外的解析和操作。使用这种方法,glTF在保存具有节点、网格、相机、材质和动画的完整分层场景的同时,实现了高效的交付和快速加载[16]。

作为一种被设计为用于网络传输的三维模型格式,glTF具有以下特点: 压缩文件大小,尽管web开发人员喜欢尽可能多的使用明文,但是由于文件的大小问题,明文编码对于3D数据的传输是不切实际的。glTF的JSON文件本身是明文,但它具有紧凑和快速解析的特点。所有的大数据比如几何、动画等都是存储的二进制文件中的,因为同样的数据内容,使用二进制表示比使用文本表示占用更小的空间。

实现快速加载,不管是在JSON文件还是二进制文件中,glTF的数据结构都被设计为尽可能的接近GL API数据来减少加载时间,比如,可以直接使用简单的拷贝操作将网格的二进制数据加载到WebGL的数组类型中,不需要解析或其他的操作。

运行时独立性,glTF没有假定要使用的应用或3D引擎。除了渲染和动画,glTF没有指定任何运行时行为。

5

西安电子科技大学硕士学位论文 完整的3D场景描述,对于很多应用来说,从一个模型包中导出单个对象是不够的,更通常的情况是需要将包括节点、偏移、偏移层级、网格、材质、相机、动画等的整个场景加载到应用中。glTF为下游应用尽量保存所有的信息。

可扩展性,尽管初始的基本规格支持了很丰富的特征,但是这些特征还有很大的可能性进行扩展,glTF定义了一种允许通用的和供应商特定的扩展的添加机制。

glTF的设计采用了一种务实的方法,虽然这种格式尽可能的符合GL API的设计,但是如果跟GL API一样的话,那么这种格式将不会含有相机、动画以及其他的在建模工具和运行时系统都很常见的特性,并且很多语法信息也会丢失。通过提供这些常见的构造,glTF不仅可以进行加载和渲染,还能在大量的应用程序中直接使用并且在内容管道中节省很多精力。

2.1.2 文件组织结构分析

glTF主要包括JSON文件和一些配套的外部数据。具体来说,glTF主要包括:bin文件、图像文件、GLSL文件和JSON文件。

.glTF(JSON)节点层次、材质、相机.bin几何图形:顶点、索引动画:关键帧动画骨骼:矩阵.glsl着色器.png.jpg…纹理 图2.1

glTF文件组织结构图

bin文件主要用来存储场景的数据,包括场景中动画的数据、节点的坐标、法向量坐标、纹理坐标、材质的数据等。凡是具体使用的有关数据都是以二进制的形式存储在此文件中。可以通过对JSON文件的解析将二进制数据还原为指定的数据格式如VEC2、VEC3等,通过此种方法来压缩文件占用的存储空间。

GLSL文件主要存储的是glTF中使用的着色器代码。着色器是用来代替固定渲染管线的可编辑的运行在GPU上的程序,实现3D图形学计算中的相关计算,目前比较流行的着色器语言有GLSL、HLSL、RM等。

JSON文件是glTF文件的重要组成部分,它完整了描述了一个模型应该具有的所有的属性,包括节点层次、材质、相机和对网格、着色器、动画和其他结构的描述信息。它还包含了对模型数据进行解析的信息,包括模型数据的基本类型,数据格式等。

6

第二章 论文相关技术研究

通过对JSON文件的解析可以得到整个场景的结构及模型数据。

2.1.3 数据模型研究

JSON文件是glTF的核心部分,它描述了一个三维模型场景的结构及组成部分。组成这个文件的主要元素包括以下几个方面的内容:场景的基本结构、在场景中出现的三维物体、三维物体数据的索引信息、物体应该如何渲染的相关信息。描述场景的基本结构的元素主要有scenes、nodes、cameras和animations;描述场景中出现的三维物体的元素主要有meshes、textures、images、samplers、skins;数据类信息的元素有buffers、bufferviews、accessors;渲染的有关信息的元素有materials、techniques、programs和shaders。这些元素都以字典的形式存储在文件中,元素之间通过ID实现关联,JSON文件还会用url来实现对外部文件的引用,如存储场景数据的bin文件、着色器代码glsl文件和图像文件,通过这两种形式的关联与引用完整的描述了整个场景的所有信息。

(1)场景结构类元素

scenes元素是整个模型场景的最上层的元素,它描述了整个模型场景的组织结构,glTF中的场景是按层次来进行描述的,即JSON文件中包含很多场景元素,在这些场景元素中含有一个默认的场景,每一个场景由不同的节点组成,每一个节点由它所有的子节点组成,因此一个模型的场景图如图2.2所示,场景图对应的在JSON中的描述形式见图2.3:

scene01node01node02node03node04node05 图2.2

场景图

7

西安电子科技大学硕士学位论文 { “scene”: “scene01” “scenes”: { “scene01”: { “nodes”: [“node01”, “node02”, “node03”] }, }, “nodes”: { “node01”: { “children”: [“node04”, “node05”], ... }, ... “node04”: { … }, “node05”: { … } }}图2.3

场景图在JSON中的描述

animations元素描述场景中的动画,在animation中定义有动画通道及采样器,动画通道主要记录了该动画要使用的采样器ID、对应的场景中的节点和对应的动画状态如翻转、缩放、平移等。采样器则主要定义了动画输入参数、输出参数和插值算法。此处使用的插值算法一般为线性插值算法(LINEAR)。此外,在animation中还定义了parameters属性,它主要用来解析动画的输入参数和输出参数数值,其值一般存储在外部的bin文件中。

动画的实现是由其定义的动画通道和采样器以这样一种合作的方式来完成:动画通道定义该动画指向的节点、动画状态及要使用的到的采样器ID,采样器则根据其定义的输入参数(时间)、输出参数(关键帧)来完成时间与关键帧的对应关系,并采用插值算法完成期间时间的补充,使得动画看起来更加的平滑。

nodes元素中存储了每个场景中的节点,glTF中的节点是按层组织的,一个节点中含有若干个子节点,子节点中又含有若干个子节点,在节点的最末端为在mesh中定义的几何体。节点中含有矩阵(matrix)属性或平移/旋转/缩放(translation/rotation/scale即TRS)的任意组合用来表示节点之间的相对坐标。在计算节点的相对坐标或动画时,这三个属性矩阵的乘法顺序总为translation * rotation * scale。当此节点含有动画时,通常使用TRS,而不是直接使用矩阵属性。

在nodes元素中也会含有相机(cameras),相机定义了看此节点的“眼睛”所在的位置,相机元素中定义了一个正射投影矩阵和透视投影矩阵。

(2)渲染类元素

meshes元素表示要被渲染的原始几何体(primitives)的集合,一个节点中可以

8

第二章 论文相关技术研究

包含一个或多个meshes,通过节点的变换(在节点中定义的变换矩阵)将meshes放置在场景中。meshes中包括原始几何体信息、索引、材质以及几何体的渲染模式,渲染模式主要包括POINT,LINES,LINE_LOOP,LINE_STRIP,TRIANGLES,TRIANGLE_STRIP,TRIANGLE_FAN等七种模式。原始几何体中含有包括图元顶点、法向量、纹理坐标在内的全部信息,它是渲染一个图元的基本信息体。

textures元素描述对图像的解释信息,包括像素格式、纹理类型、使用的采集器(samplers)的引用及指向定义图像信息(images)的引用。采集器定义了纹理的采样方法,包括放大采样、缩小采样和超边界采样(wrap),这里采集器跟动画实现中的采集器并不是同一个内容,动画中的采集器是定义在动画通道中的,因此两者并不会造成冲突。

images元素在场景中用于创建纹理的图像信息,是一个原始的图像资源。可以是外部图像文件,或者base64-encoded编码。images 同样也是一个二进制块,GPU并不知道具体的图像尺寸和像素格式。具体某种图像格式中可能会包含这些信息,比如图像尺寸,但这些信息需要应用程序自行提取。

(3)具体数据类元素

buffers元素用来存储顶点、索引、法向量、动画等数据。可以是一个外部二进制文件,也可以以base64-coded编码嵌入到glTF的JSON文件中。它定义了整个数据块的长度、数据存储的类型及引用的外部文件的路径。顶点、索引数据经过应用程序解译之后传递给GPU,动画数据一般由应用程序使用,实现节点的关键帧动画。

bufferviews元素表示对buffers中数据的索引,通常表示buffers中数据的一个子块。例如,多个几何体的数据可以存储在一个buffers中,需要使用bufferviews将每个几何体的数据提取出来。每一个bufferviews都指向一个buffer,并定义了相对于buffer开始位置的偏移量和此bufferviews的长度。

accessors元素定义了如何解译bufferviews中的数据,它记录了bufferviews中的元素的个数和类型,例如将自身定义的type设为“vec2”、将componentType设为“5126”、将“count”设为“10”来表示一个具有10个元素的vec2f的数组。accessors同样定义了相对于bufferviews开始位置的偏移量来确定从什么地方开始解译这些数据信息,此外,它还定义了当前数据元素开始的位置和下一个数据元素开始位置的距离,如果此值为0,则表示两个数据元素相邻,中间没有其他数据信息。

(4)三维物体类元素

materials元素用于描述几何图元的材质,包括材质的漫反射值、镜面反射值及光强值。这些值的类型都是在techniques中定义,并可以在定义材质的时候使用value值域来指定数值以覆盖在techniques中定义的默认值。

techniques元素表示一次完整的GL绘制所需要的所有GL状态集,它定义了着

9

西安电子科技大学硕士学位论文 色器代码中的uniform、attribute参数。attribute参数就是在顶点着色器程序中用到的“attribute”类型的变量,而uniform参数则对应片段着色器程序中使用的“uniform”类型变量。不管是uniform参数还是attribute参数,其类型都是在technique中的parameter中定义的,parameter属性中定义了它们的类型(type)及语法(semantic),语法主要是用来定义此变量的用意,对于attribute参数常用的语法如“POSITION”、“NORMAL”分别表示此参数表示的是坐标和法向量信息,而uniform参数常用的语法包括“MODEVIEW”、“PROJECTION”等。一个没有定义语法的uniform既不能含有默认的值也不能在materials中定义它的值。

programs元素对应GL program相关方法,包含顶点着色器、片段着色器和对顶点属性的引用,具体的顶点属性的值在techniques中定义。

shaders描述渲染场景中使用的着色器,包括顶点着色器和片段着色器,着色器代码的内容可以存储在外部文件GLSL文件中或为base64-encoded。在WebGL中使用着色器的方法主要有:createShader(),deleteShader(),shaderSource(),compileShader(),getShaderParameter()和getShaderInfoLog()。

(5)元素之间引用关系

通过以上分析,可以知道场景中的每个元素都不是孤立的,他们之间存在相互的引用关系。通过元素之间的相互引用,可以看到场景清晰的层次结构及数据。图2.4为各元素之间的引用关系:

scene**node11**skinscamera*mesh*material1*animation*accessor1technique1texture11bufferView1program2imagesamplerbuffershader 图2.4 元素之间应用关系图

一个场景(scene)是由一个或多个节点(node)构成的,每个节点可能含有多个孩子节点,这些孩子节点通过偏移、旋转、缩放等矩阵组合成父节点中要描述的场

10

第二章 论文相关技术研究

景。在整个节点组成的树的叶子节点中包含构成几何体的基本图元(mesh),组成这些图元的顶点信息数据存储在二进制块中,并能够通过accessor、bufferView索引来获取相应的数据。在叶子节点中除了含有构成几何体的图元,还有几何体的材质(material)、相机(camera)、骨骼(skins)。骨骼主要用于实现动画中的骨骼动画效果;相机则设置了观察此几何体用到的视角坐标;在几何体的材质中定义了该几何体的显示效果,如颜色、环境光、反射光等,这些材质效果在technique中定义,并通过着色器程序传入GPU中进行计算,着色器通常有顶点着色器(vertex shader)和片段着色器(fragment shader)两种,除了几何体本身材质效果外,在material中还定义了几何体的纹理(texture),纹理中定义有该纹理使用的纹理图片(image)和采集器(sampler)。

2.2 OSG可视化关键技术研究

2.2.1

OSG平台介绍

OSG是OpenSceneGraph的简称,它是一个基于工业标准OpenGL的场景图形管理开发库,主要为图形图像应用程序的开发提供场景管理和图形渲染优化功能[17]。由于是基于OpenGL构建,因此它具有较好的跨平台特性和较高的渲染能力。借助它,程序员可以更方便地创建跨平台、高性能的交互式图形程序。在使用OSG进行程序开发时,整个程序的层次结构如图2.5:

应用程序OpenSceneGraphOpenGL图形硬件 图2.5 OSG程序层次结构

由图中可以看出,OSG对OpenGL的大多数接口进行封装,使得开发者不用去关注底层的具体细节,从而将精力放在具体的功能实现上。

OSG本身是由OSG核心库、OSG工具库、OSG插件库和OSG内省库4个核心模块组成。各库之间的组织形式如图2.6所示:

11

西安电子科技大学硕士学位论文 OSG内省库OSG插件库OSG核心库OSG工具库 图2.6

OSG组成模块图

OSG核心库主要功能是实现场景图形的操作、场景数据库的组织和管理以及为外部数据库的导入提供接口等,在OSG核心库中主要有OSG库、OSGUtil库、OSGDB库和OSGViewer库四个库。

OSG工具库是对OSG核心库的扩展,扩展了OSG对特殊效果(如凹凸贴图特效、卡通渲染特效、异性光照特效等)、粒子系统(模拟各种自然现象及天气特效,如雨效、雪效、爆炸模拟等)、虚拟仿真效果(如地形高程图、光点节点、DOF变换节点等)、生成地形数据(如TIFF、IMAGE、DEM等高程数据格式,OSG是通过GDAL来实现读取)和阴影(添加实时阴影,增强真实性)等节点工具的支持。

OSG内省库的主要功能是通过提供与语言无关的运行程序接口实现OSG对多种编程语言的支持。如目前主流的C++、Java、Python等,都可以实现与OSG的交互。

OSG插件库是OSG的一个主要特点,它提供了对不同格式文件的接口,使得OSG可以直接导入3D模型数据,目前OSG插件库支持的数据模型格式主要有:3dx、obj、flt等常见格式,此外,OSG还自定了两个文件格式osg和ive,分别使用ASCII文本和二进制对文件进行描述。OSG插件库允许程序员开发自己的插件来实现对特定3D模型格式的文件进行导入和渲染。

2.2.2 OSG场景组织及渲染分析研究

在OSG中存在场景树和渲染树两棵树[18]。场景树反映了场景的空间结构和对象信息,它是一棵由真正的可绘制对象、状态切换或矩阵变换所组成的树。渲染树则是一棵以渲染状态和渲染叶为节点的树,它的主要功能为同时渲染渲染状态相同的渲染叶而不用切换OpenGL状态,并且实现尽量少的在多个不同的状态间切换。

OSG是基于场景图概念设计的[19],场景图是一种用于游戏和图形学软件的数据结构设计方法,大规模的场景图形大多使用树结构或图结构来组织节点集,OSG使用自顶向下、分层的树状数据来对空间数据集进行组织,以提高渲染效率。例如,一辆汽车以场景图的形式描述则为以下形式:

12

第二章 论文相关技术研究

汽车轮胎车身车窗 图2.7

场景图示例

场景图形的顶部是根节点,从根节点向下延伸的到各个子节点中,它们包含了组成场景的几何信息和渲染状态信息,根节点和组节点都可以含有0个或多个子节点,在场景图中的最底部各个叶子节点中包含了构成场景中物体的实际几何信息,如图中的轮胎、车身、车窗。

场景树是描述一个场景的具体形式,但是具体的渲染过程则是基于状态树来实现的,因此必须将场景树转换为状态树才能实现场景的渲染[20]。对于一个场景来说,其具体的表现形式如下:

场景根节点_rootNode位移节点1_patNode1位移节点2_patNode2叶节点1_geode1叶节点2_geode2叶节点3_geode3ss03几何体1_drawabless11几何体2_drawable2ss11几何体3_drawable3ss13几何体4_drawable4ss14几何体5_drawable5ss15几何体6_drawable6ss16 图2.8

场景树结构图

在上述场景图中叶节点3和6个几何体对象都设置了关联的状态集,并且对于几何体1和几何体2同属于一个根节点,其状态(ss11)也相同。值得注意的是在OSG中,不管用户是否自己指定,所有的Drawable几何体对象都会自动关联一个StateSet对象。在进入渲染后台之后,OSG将上面的场景树转化为状态树,如图2.9。

图中状态根节点和局部状态节点都是由程序自动生成,在局部状态节点中主要存储和维护渲染后台自动创建的渲染属性;全局状态节点存储了“_globalStateSet”的渲

13

西安电子科技大学硕士学位论文 染状态集对象,它的值为场景主摄像机的StateSet。在对状态树的渲染中,由上而下的对状态树进行遍历,先访问全局状态节点然后再访问局部状态节点。状态树的构建过程遵循的规则为:

1、状态树的生成是根据节点的StateSet来生成的,对于没有指定StateSet的节点来说,它们不会影响状态树的生成。

2、场景树中的几何体对象在转换为状态树的过程中,被放置在渲染叶中,渲染叶必然是状态树的根节点。

3、对于渲染状态相同的几何体对象,在状态树中会被放置在同一个末端节点中。 OSG根据生成的状态树实现场景的渲染。

状态根节点_rootState全局状态_globalState局部状态_localState状态ss11状态ss13状态ss03渲染叶1_leaf1渲染叶2_leaf2渲染叶3_leaf3状态ss14状态ss15状态ss16渲染叶4_leaf4渲染叶5_leaf5渲染叶6_leaf6 图2.9 状态树结构图

2.3 glTF与OSG可视化结合

OSG作为对三维模型实现可视化的平台,其本身的插件机制提高了OSG对各种三维模型格式支持的扩展性[21]。目前OSG本身提供支持的三维模型格式包括3dx、obj、flt等常见格式,除此之外,OSG还自定义了两个三维模型文件格式osg和ive。但是,目前OSG平台还没有提供标准的插件来支持对glTF三维模型格式文件的可视化。

在OSG中,绘制物体主要包含有三个主要步骤:

(1)创建各种向量数据,如顶点、纹理坐标、颜色和法线等。

14

第二章 论文相关技术研究

(2)实例化一个几何对象,设置顶点坐标数组、纹理坐标数组、颜色数组、法线数组、绑定方式及数据解析。

(3)加入叶节点绘制并渲染。

本文中使用glTF格式文件存储要绘制的几何体数据。在OSG中需要创建的各种向量数据都被存放在glTF元素中,如顶点数据存放在meshes元素中的“POSITION”属性中,纹理坐标数据存放meshes元素中的“TEXCOORD”属性中,法线数据存放在meshes元素中的“NORMAL”属性中,颜色及材质数据存放在materials元素中。glTF中元素数据与OSG类对应关系如下表所示:

表2.1 glTF元素与OSG类对应关系表

glTF元素数据 meshes textures animation materials nodes programs shaders OSG类 OSG::Geometry OSG::Texture2D OSGAnimation::Animation OSG::Material OSG::Node OSG::Program OSG::Shaders

除了对几何体的绘制之外,OSG还必须对glTF格式文件中所描述的如纹理、动画、材质等信息进行处理,对glTF格式文件中描述物体的所有信息进行可视化操作。如上表所示,这些具体的信息都能够通过对应的OSG相应的类来进行表述,将glTF中的数据信息解释为OSG能够渲染的具体数据,实现glTF格式文件在OSG平台的可视化。

15

西安电子科技大学硕士学位论文

16

第三章 glTF模型转换及可视化的设计与实现

第三章 glTF模型转换及可视化的设计与实现

glTF全称为GL Transmission Format,它是一种用于网络传输、显示的三维模型格式,目前主流的三维建模软件并不支持直接导出glTF格式文件,为了获得glTF格式文件,必须从其他格式转换过来,由于glTF文件与Collada文件都是由Khronos组织设计的,这两种文件格式之间存在一定的相似性,而大多数三维建模软件可以支持Collada文件的导出,因此本文设计实现从Collada格式文件转换得到glTF格式文件的转换工具。本章提出了对glTF数据的存储优化方案,此外还设计实现了glTF在OSG平台的可视化与实现对glTF模型管理的模型资源浏览器。

3.1 数据存储优化

3.1.1

顶点数据存储优化

在计算机图形学中,对模型中的顶点数据进行压缩、编码、打包是一种很常见的优化手段,通过这些手段可以减少模型的内存占用,降低计算机总线将数据从CPU传送到GPU的时间及GPU带宽,实现顶点数据压缩的代价是在着色器代码中添加额外的指令。额外的着色器指令虽然会增加GPU指令来解析数据,但是它却带来了另一个好处,突破对顶点属性数量的限制。

本文通过降低顶点属性数量来降低文件存储空间,将所有的属性值都存储在四分量矢量中并确保每个分量都能够被用到。例如在着色器中通常会使用下面的定义方法来定义两个属性:

attribute vec3 axis; attribute float rotation;

在顶点属性中定义有一个vec3类型的属性值与float类型的属性值,可以将这两个属性值合并到一个四分量矢量中即用一个vec4类型变量表示。这样,本来在着色器代码中需要两个变量存储的属性值,经过压缩优化,只需一个变量就行。将这两个属性合并之后,可以得到下面定义形式,在需要获取具体的属性定义时通过在着色器中的定义额外指令来读取:

attribute vec4 axisAndRotation; //...

vec3 axis = axisAndRotation.xyz; float rotation = axisAndRotation.w;

17

西安电子科技大学硕士学位论文 3.1.2 法向量数据存储优化

法向量数据在三维坐标系中是使用三分量矢量表示的,可以通过降低法向量的矢量分量实现对法向量数据的优化存储。本文采用八分表示法实现其优化策略,这种表示方法将三分量单位长度向量压缩为两分量向量。八分编码向量是先将球体映射到八面体,然后将八面体投影在z=0的平面中,然后在合适的对角线上反射-z半球[22],如图3.1所示。所有最终结果会填充为一个[-1,+1]的正方形,然后存储正方形中的坐标。图中在球体坐标中的ABC区域的点会映射到八面体A'B'C'区域,然后将八面体投影到z=0的平面中,在八面体A'B'C'区域的点会落在正方形A\"B\"C\"区域,而在BCD区域的点经过八面体中的B'C'D'区域,最终会被映射到正方形中的B\"C\"D\"区域中。在球体坐标中,以球心为坐标原点,在ABC区域中的每个点坐标,就表示法向量数据。

AA’C’BCB’A’’C’’DD’B’’D’’

图3.1 八分向量编码过程

假设一顶点的法向量坐标为(x,y,z),其在球体坐标系统对应在ABC区域的点坐标为(x,y,z),则根据空间几何相关知识可以得到该点映射到八面体中的坐标(x',y',z

')为:

x'(2xyz)3 y'(2yxz)3 z'(2zxy)3

'''

''

'(3-1) (3-2) (3-3)

'''由于对于映射到ABC区域的点(x,y,z)符合面ABC的平面方程,因此z的坐标可是使用x,y表示:

'''z'1x'y'

(3-4)

最后将八面体的坐标映射到正方形区域,存储x',y'。对于其他区域法向量的最

18

第三章 glTF模型转换及可视化的设计与实现

终存储坐标,会因为该区域映射到的八面体的平面方程不同计算方法会有所不同,但大体便是通过此运算过程将原来三分量矢量最终转换为二分量矢量存储。通过存储的坐标获取原来的法向量坐标只需将上述运算过程翻转。本文之所以舍弃三角表示法是因为在GPU中对三角函数的计算代价太大。

3.2 glTF模型转换设计与实现

3.2.1

glTF模型转换设计思路

Collada是一个开放标准,它提供了面向交互式3D应用程序的基于XML的三维模型数字资产交换方案,使得三维建模软件之间可以自由的交换数字资产而不损失信息[23]。除此之外,Collada还可以作为场景描述语言用于三维模型数据的实时渲染,目前Collada已被标准化团体Khronos组织采纳为三维图形对象描述的标准规格。

Collada格式将三维模型数字资源从难以理解的二进制格式转化为开放的XML为基础的较好表述格式。经过多次的更新迭代,Collada格式目前已经添加了对三维模型中的特效、动画和皮肤的支持,并且对3DS、Maya、XSI等主流三维建模软件都提供了输入输出插件程序[23]。目前Collada格式实现了多种三维建模软件之间可以自由的进行三维模型数字资源交换。虽然Collada存在上述的诸多好处,但是由于它使用XML作为资源存储格式,使得Collada格式文件体积较大,不适合作为最终网络传输文件格式。

在Collada格式文件中,三维模型的所有属性信息都是以集合的形式存储,例如对于三维模型的动画、材质、纹理、几何体等不同种类信息被分别存储在不同的集合中[25]。如图3.2为Collada格式中模型资源的存储结构,从图中可以看出三维模型的每种属性都会以一个单独的元素存储起来。动画信息存储在library_animations元素中,灯光信息存储在library_lights元素中,纹理信息存储在library_images元素中,等等。在每个元素中都含有存储的模型属性相关信息,包括在该属性中被定义的元素和该元素的具体数值。

由图3.2可以得知,Collada格式对三维模型资源的存储形式与glTF格式对三维模型资源的存储形式极其相似,两者都采用将模型属性分开存储的存储方案,并且对模型的属性划分是一样的。事实上,对Collada格式的标准化组织Khronos正是glTF格式的设计和实现者,两者存在很多的相似性。不同的是glTF格式对模型数据的存储从XML格式转换为更容易解析的JSON格式,并对模型资源数据采用占用存储空间更小的二进制存储方法。

由于Collada格式对主流的三维建模软件的支持及Collada格式与glTF格式在存储方案上的相似性,因此本文提出将Collada作为中间格式实现各种模型格式向glTF

19

西安电子科技大学硕士学位论文 格式转换的思路,并基于这种思路设计实现模型转换工具Collada2glTF。

图3.2 Collada格式模型资源存储结构图

3.2.2 Collada2glTF转换工具总体设计

Collada2glTF是基于命令行实现的将Collada文件转化为glTF文件的转换工具。它由Collada2glTF命令解析和Rest3D两个模块组成。图3.3为Collada2glTF转换工具的总体设计。

该工具的实现依赖于两个C++库:OpenCollada和RapidJSON。其中RapidJSON是一个出色的解析及生成JSON文件的框架,用c++来实现,它具有跨平台、独立、高性能等特点,本文中用来生成glTF中的JSON文件来存储具体的场景信息。OpenCollada库用来打开Collada文件并存储三维模型数据,以供转化使用。

Collada2glTF命令行模块主要用来实现对命令行输入参数的解析,得到输入文件路径、输出文件路径及输出文件格式等信息。Rest3D模块是处理和访问三维模型数据的主要模块,它将从OpenCollada模块得到的三维模型数据进行处理转换为符合glTF标准的数据格式,通过RapidJSON模块,将其写入到JSON文件中。

COLLADA2GLTFCOLLADA2GLTF 命令行Rest3DCOLLADA2GLTF C++ LibraryOpenCOLLADARapidjson

图3.3

Collada2glTF模块总体设计

20

第三章 glTF模型转换及可视化的设计与实现

3.2.3 命令行模块设计与实现

Collada2glTF命令行是实现对输入参数解析的模块,它主要实现的功能有:判断输入参数是否有效;解析输入文件并判断其路径是否正确、文件是否存在;解析输出文件,得到输出文件格式及路径。

Collada2glTF模块更多的是对转换流程的控制,而不是将Collada文件内容转换为glTF内容的具体步骤,它负责对各个模块的调度,包括对配置文件的加载、Collada文件的打开、转换模块。glTF文件存在两种存储形式,一种是将二进制数据、外部文件与JSON文件分开存储,另一种则是将所有的这些数据都存放在一个文件中(glb),在命令行控制模块中通过输入参数来实现控制,该模块的实现伪代码如下所示。

parseParameter(inputfilePath, outputfilePath, format): if (not (inputfilePath || outputfilePath || format))

return;

else if (format == “gltf”) convertCollada2gltf(); else if (format == “glb”) convertCollada2glb(); else return;

3.2.4 Rest3D模块设计与实现

Rest3D模块是Collada2glTF转换工具的核心模块,它将从Collada文件中得到的三维模型数据转化为符合glTF格式标准的数据,并使用给定的特定版本存储在文件中。其中需要转换的三维模型数据主要有:节点信息、动画信息、纹理信息、材质信息、光照信息等。

图3.4为将Collada文件转换为glTF文件的流程图,在使用OpenCollada库加载Collada文件内容之后,判断文件读取是否成功,在得到正确的文件内容之后,便可以开始转换,由于glTF文件存在不同的元素类型,必须根据不同的元素类型生成对不同数据的描述信息,这些描述信息都是由glTF文件格式本身定义,并存储在根据该元素中含有的属性设计的类对象中。但是这些描述信息本身并不是构成该场景的资源数据,场景的资源数据是以二进制形式存储在外部文件中的,因此,在转换过程中,需要将Collada中的所有模型资源数据存储在一起放在二进制块中,并记录每个数据的在二进制块中的位置,以便以后对数据解析时使用,这些索引信息便是glTF文件中的Accessor、BufferView元素的由来。如果在Collada文件中含有指定的着色器代码,则glTF直接使用其着色器代码,否则glTF缺省是基于Collada FX Common Profile生成着色器的。

21

西安电子科技大学硕士学位论文 开始使用OpenCollada库读取Collada文件内容判断是否成功获取文件内容是解析读取到的文件内容,根据不同的内容信息,分类转换为glTF模式否...动画类信息对文件数据内容分类场景描述类信息渲染资源类信息根据Animation元素的定义,生成JSON描述字段,根据Scene元素的定义,生成JSON描述字段根据glTF中该类资源信息的定义,生成相应的JSON描述字段将数据填入到二进制块中,并生成accessor、bufferView等索引数据结束

图3.4

Rest3D流程图

该模块中含有的模块数据转换类之间的关系图如图3.5所示,其中COLLADA2GLTFWriter类是实现从Collada文件转换为glTF文件的关键类,在该类中定义了加载Collada文件的加载器(_loader)、指向glTF中所有元素数据的共享指针(_asset)以及所有生成glTF元素数据的方法如生成动画元素的writeAnimation,生成渲染物体元素的writeGeometry,生成材质信息的writeMaterial,这些方法将Collada中描述相关信息的数据转换为glTF中的描述形式。在生成相应元素的描述数据之后,这些数据被存储在定义在该类的_asset变量中,该变量被定义为GLTFAsset类对象的共享指针,准确来说,所有的glTF元素数据都是被存储在GLTFAsset类中的_root成员变量中。

22

第三章 glTF模型转换及可视化的设计与实现

GLTFAsset类是JSONObject的子类,它聚合了整个模块中的所有数据,在该类中除了存储glTF元素数据之外,还存储了需要转换的Collada文件路径、生成的glTF文件存放路径、glTF文件中模型资源和模型动画占用的字节数。glTF数据由JSON文件与二进制文件中的数据构成,因此在GLTFAsset类中定义了两个类对象来分别处理对JSON文件和二进制文件的生成。

GLTFWriterIWriterCOLLADA2GLTFWriter-_loader: Loader-_asset: shared_ptr-_extraDataHandler: ExtraDataHandler-_visualScene: const VisualSceneGLTFDefaultWriter-_fd: FILE*-_writer: PrettyWriter-_fileStream: FileStream+initWithPath(): bool+writeArray(): void+writeNumber(): void+writeString(): void+write(): voidGLTFAsset-_root: shared_ptr-_extras: shared_ptr-_writer: shared_ptr-_inputFilePath: string-_outputFilePath: string-_sharedBufferID: string-_geometryByteLength: size_t-_animationByteLength: size_t-_nameToOutputStream: NameToOutputStream-_uniqueIDToJSONValue: UniqueIDToJSONValue-_profile: shared_ptr+write(): void+createOutputStreamIfNeeded(): shared_ptr+closeOutputStream(): void+setGeometryByteLength(): void+getGeometryByteLength(): size_t+setAnimationByteLength(): void+getAnimationByteLength(): size_t+setOutputFilePath(): void+getOutputFilePath(): const string+setInputFilePath(): void+getInpurFilePath(): const string+write(): bool+writeScene(): bool+writeLibraryNodes(): bool+writeGeometry(): bool+writeMaterial(): bool+writeEffect(): bool+writeCamera(): bool+writeImage(): bool+writeAnimation(): boolJSONObjectGLTFOutputStream-_stream: shared_ptr-_outputPath: string-_filename: string-_id: string-_opened: bool-_embedded: bool+length(): size_t+write(): void+filename(): string&+id(): string&+ouputPath(): string&+close(): void+remove(): void

图3.5

Rest3D模块数据转换类图

GLTFDefaultWriter类是继承自GLTFWriter的子类,该类主要负责对JSON文件的写入操作,它通过GLTFAsset类中的对输出文件路径的解析,在该位置生成glTF的JSON文件,其内部的具体写入操作是通过RapidJSON库中的函数实现的。

GLTFOutputStream类负责对二进制文件的写入操作,在该类中定义了存储模型数据的二进制文件的相关信息,包括文件路径、名字、文件目前打开状态、是否使用embedded模式等,对二进制文件的写入通过数据流的方式实现,具体的写入过程是:首先通过COLLADA2GLTFWriter类中的成员函数解析数据,生成JSON描述部分和二进制数据部分,再由该类负责将二进制部分写入到文件中,由GLTFDefaultWriter

23

西安电子科技大学硕士学位论文 类将JSON部分写入到JSON文件中。

glTF中对不同的场景元素使用不同的数据格式来存储如图3.6所示,如存储模型顶点数据的GLTFMesh、存储材质数据的GLTFMaterial、存储动画数据的GLTFAnimation,在glTF中,这些元素并不直接存储数据,它们存储的是数据在二进制中的解析方法,如该数据的类型、在二进制块中的位置等。这些解析方法便是通过GLTFAccessor、GLTFBufferView类存储的,而生成的二进制数据则被存放在GLTFBuffer中。

无论是GLTFMesh、GLTFMaterial、GLTFAnimation还是GLTFAccessor、GLTFBufferView继承自JSONObject类,并通过基类对象被GLTFAsset类引用,变相的相当于所有的glTF元素数据都存放在GLTFAsset类中。在Rest3D模块中不只含有上述的类,在该模块中定义了所有在glTF格式规范文档中定义的元素(见第二章glTF格式分析章节),所有这些类都是按照该元素在glTF中定义的元数据进行定义的,实现对glTF所有元素的存储。

GLTFAccessor-_componentPerElement: size_t-_componentTyep: string-_elementByteLength: size_t-_ID: string-_minMaxDirty: boolJSONValue-_type: string+write(): virtual void+ValueForKeyPath(): shared_ptr+getJSONType(): virtual JSONType+valueType(): virtual string+setBufferView(): void+getBufferView(): shared_ptr+setByteStride(): void+getByteStride(): size_t+setByteOffset(): void+getByteOffset(): size_t+setCount(): void+getCount(): size_t+applyOnAccessor(): voidGLTFBufferView-_ID: string-_buffer: shared_ptrJSONArray-_values: JSONValueVectorRef-_allValues: JSONValueVector+appendValue(): virtual void+values(): JSONValueVectorRef+getCount(): size_t+contains(): bool+indexOfValue(): size_t+getJSONType(): virtual JSONType+valueType(): string-_keyToJSONValue+createObjectIfNeeded(): shared_ptr+createArrayIfNeeded(): shared_ptr+setValue(): void+getValue(): shared_ptr+removeValue(): void+getObject(): shared_ptr+getArray(): shared_ptr+contains(): bool+getAllKeys(): string+getKeysCount(): size_t+initWithContentOfFile(): bool#_parseRapidJSONObject(): voidJSONObject+setByteLength(): void+getByteLength(): size_t+setByteOffset(): void+getByteOffset(): size_t+getBuffer(): shared_ptr+getID(): string const-setBuffer(): voidGLTFBuffer-_ID: string-_data: unsigned char*-_ownData: bool+getByteLength(): size_t+getID(): string const+getData(): const void*GLTFAsset-_root: shared_ptrGLTFAnimation-_id: string-_originalID: string-_targets: shared_ptr-_nodeId: string-_keyFrames: vector-_bufferViews: map>+writeAnimation(): void+getTargetNodeId(): string+setTargetNodeId(): void+registBufferView(): void+getBufferViewForParameter(): shared_ptr

图3.6

Rest3D模块数据存储类图

24

第三章 glTF模型转换及可视化的设计与实现

3.3 glTF基于OSG可视化的设计及实现

本文实现glTF在OSG平台可视化的基础是OSG的插件机制,OSG允许通过自定义插件实现对glTF格式三维模型的文件加载、节点显示、动画实现、纹理加载等功能。OSG插件是一组动态链接库,其中实现了OSGDB头文件ReaderWriter定义的接口[26]。为了保证OSG可以找到这些插件,插件所在的目录必需在系统的环境变量中指定,用户根据系统的环境变量来查找插件所在的路径。OSG不可能加载所有的插件来获取它目前所支持的文件格式,这样会给程序的启动带来很大的开销,因此OSG设计使用责任链的设计模式,以加载尽量少的插件。OSG按照下面的步骤来查找合适的插件[27]:

1、OSG搜索已注册的插件列表,查找支持文件格式的插件。

2、若没有发现可以支持此格式的已注册插件,OSG根据osgdb_.dll的文件命名规则,根据的名称来加载相应的格式文件,若加载成功则将此插件加入到已注册插件列表中。

3、重复步骤1,若文件I/O操作再次失败,OSG将返回失败信息。

对glTF文件的可视化主要包括文件加载、场景渲染和关键帧动画三个模块,按照OSG插件的命名规则,将该插件命名为osgdb_glTF,图3.7为该插件的模块结构。

osgdb_gltf场景渲染动画实现文件加载picojsonstb_image

图3.7

osgdb_glTF模块图

该插件的实现依赖于两个C++库,picoJSON和stb_image,picoJSON库是使用C++实现的用于JSON解析序列化的库,由于glTF文件的模型资源都是以JSON文件形式存储的,本文使用该库来解析glTF中的模型资源;stb_image库是一个用来解析图片数据的C++库,由于glTF文件的存储模式多样,使得用来存储纹理图片的数据可能以图片文件的形式存储在外部文件中,也可能要将纹理图片的数据以二进制的形式嵌入到glTF文件中,根据不同的文件格式,本文使用两种策略来进行处理,若纹

25

西安电子科技大学硕士学位论文 理图片存储在外部文件,则使用OSG的对相应图片格式的插件加载纹理,如果纹理图片是直接二进制存储的,则使用该库来实现对文件的解析。

3.3.1 文件加载模块设计与实现

文件加载是整个插件得以实现的基础,通过该模块将描述场景的信息导入到内存中,为以后场景渲染和动画实现提供数据基础。

文件加载模块通过使用picoJSON库解析JSON文件内容,在得到数据之后,对JSON键值对根据glTF定义的资源元素进行解析,解析过程主要包括三方面的内容:判断资源元素中描述的属性是否完整,glTF中每类资源都含有相应的属性描述信息,如在BufferView中就定义有描述此BufferView的长度、偏移量、名字、所指向的Buffer等属性;获取相应资源元素属性的描述数据,在判断完属性是否完整之后,还要获取相应属性的数值;对相应属性数据做类型转换,由于JSON文件中存储都是字符类型,但对于资源元素属性来说,可能有的属性数值为整数型,因此,要根据具体的属性将对应的属性值进行类型转换。具体的加载解析流程如图3.8所示。

由于在glTF文件中的描述元素有很多种,在图3.8中并没有列出对全部元素的解析过程,只是举出Asset元素与BufferView元素作为例子。

开始使用rapidjson库解析JSON文件,得到JSON数据…否判定JSON数据是否含有Asset元素否判定JSON数据是否含有BufferView元素是是解析Asset元素中属性,获取属性数值并转换解析BufferView元素中属性,获取属性数值并转换判断Asset元素中属性是是否完整是判断BufferView元素中属性是是否完整是否否结束

图3.8

数据加载解析流程图

26

第三章 glTF模型转换及可视化的设计与实现

根据glTF中对场景元素信息的定义,构建相应的类存储每个元素的内容,详细情况见图3.9。

Scene类是描述整个三维场景的类,它存储了三维模型文件的所有数据包括节点、纹理、动画、材质等,为了减少对内存的占用,类中的所有元素都是通过键值对索引指向真正存储数据的对象。每个类中对场景的描述数据都不是直接存储在该类中的,类之间通过索引相互关联在一起,所有的数据都是被存储在Buffer类中,该类使用无符号字符数组来存储二进制数据。

Accessor类、BufferView类存储的是对Buffer类中数据的解析信息,如该数据的类型、长度、偏移量等等,在BufferView类中含有“buffer”成员变量,它被定义为一个字符串,该字符串内容为需要引用的Buffer类对象名字,由于在Scene类中所有的元素都通过键值对存储,因此将该字符串作为查找关键字便可以找到BufferView类对象引用的Buffer对象,同样的在Accessor类中存储了要引用的BufferView类对象名称。根据在Accessor类和BufferView类中定义的解析信息,便可以将Buffer中的二进制数据解析为相应类型的数据。

Accessor-bufferView: string-name: string-byteOffset: size_t-byteStride: size_t-componentType: int-count: size_t-type: int-minValues: vector-maxValues: vectorBuffer-name: string-data: vectorScene-accessors: map-buffers: map-bufferViews: map-materials: map-meshes: map-nodes: map-textures: map-images: map-seces: map>-programs: map-shaders: map-technique: map-animation: map-sampler: map-defaultScene: string-asset: AssetMaterial-values: map-technique: string-name: stringBufferView-target: int-byteLength: size_t-byteOffset: size_t-buffer: string-name: stringNode-camera: string-name: string-children: vector-rotation: vector-scale: vector-translation: vector-matrix: vector-meshes: vectorMesh-primitives: vector-name: stringAnimations-channels: vector-parameters: AnimationParameters-samplers: map-name: stringImage-name: string-uri: stringTexture-format: int-internalFormat: int-sampler: string-source: string-target: int-type: int-name: stringProgram-attributes: vector-fragmentShader: string-vertexShader: string-name: stringSamplers-wrapT: double-wrapS: double-minFilter: double-magFilter: double-name: stringTechniques-name: string-states: TechniquesState-uniforms: map-program: string-attributes: map-parameters: mapShaders-uri: string-type: double-name: string

图3.9 数据存储类图

27

西安电子科技大学硕士学位论文 Mesh类存储的是渲染物体的具体信息,在每个Mesh类中含有多个Primitive类对象,Primitive类中定义了组成该图元的渲染模式如面、点,图元的顶点信息如顶点坐标、法向量、纹理坐标,图元的材质,以及图元使用的顶点索引。通过这些Primitive类对象中的信息对模型进行渲染。当然,这些数据并不是直接存储在该类中的,实际上,所有上述的信息存储的都是Accessor类对象的名称,然后通过对Accessor类对象的解析得到具体的模型数据。

Material类表示的是渲染模型的材质信息,它被Primitive类引用。在Material类中主要定义了该模型的漫反射、镜面反射、亮度等光照信息,所有这些信息的数值被直接定义在该类中,但是这些信息的具体解释信息如漫反射的语义、数据类型,则通过在该类中引用的Technique对象定义。

Shader类定义了渲染该模型使用到的着色器程序,这些程序代码通常都存储在外部文件中,因此,Shader类通常提供了这些程序代码的外部文件路径及着色器类型,着色器主要有顶点着色器和片段着色器两种。

3.3.2 场景渲染模块设计与实现

在得到所有文件数据之后,便能够实现对场景的渲染,渲染的实现主要是通过调用OSG封装的OpenGL接口来实现,具体到设计实现上面,在场景渲染模块主要实现以下几种功能:对二进制数据的解析、着色器代码的加载、还原描述的场景图。

由于glTF文件的模型数据以二进制的形式存储在外部文件中,通过文件加载模块得到的数据只是对glTF中JSON文件的描述,还要通过JSON中的信息来解析二进制文件才能真正得到模型的数据。二进制数据是根据在JSON中描述的数据基本类型(整形、浮点型等)、数据类型(Vec2、Vec3等)、数据在二进制块中的偏移量进行解析的。在glTF文件中,元素数据并不是直接指向二进制文件数据,只有Buffer元素是直接指向二进制文件,其他所有元素数据都只能通过Accessor、BufferView元素来找到其对应的数据。具体的索引关系如图3.10所示。

BufferbufferViewbufferViewbufferViewvertex accessornormal accessortexcoord accessorimagev/f shadertextureprogrammaterialtechniquemesh 图3.10 元素数据引用关系图

28

第三章 glTF模型转换及可视化的设计与实现

在各个描述场景的元素中,数据的解析都是通过accessor来实现的,在accessor中定义有解析其元素的详细信息,其具体的解析过程为:在元素中定义指向描述此元素数据的accessor元素,在accessor元素中定义了指向buffer的bufferView元素,buffer中则存储了具体的二进制数据,bufferView描述了元素数据在buffer中的偏移量,步长等信息。在buffer中存储了所有的模型资源数据,通过buffeView获取元素数据的数据段,并通过accessor解析该数据段数据,具体的解析过程见图3.11。

buffer从文件中读取到的数据byteLength = 35048121620242832bufferview定义4buffer中的一部分byteOffset = 4byteLength = 28accessor定义了需要使用的偏移量byteOffset = 488121620242832121620242832accessor确定存储8的数据的值type = vec2componentType = Float1216202428abcd

图3.11

元素数据解析过程图

在渲染场景之前,还有一个重要的步骤便是加载着色器代码,着色器主要有顶点着色器和片段着色器,它的主要作用是处理与顶点及画面的相关信息。着色器代码通常都是以单独的文件存储在外部,OSG中常用的着色器代码语言为GLSL。

在着色器加载完成之后,便是对场景的渲染了,虽然本文将数据的解析与渲染分开来描述,在具体的实现中,数据的解析是在渲染过程中实现的,并不是在将所有的数据解析完成之后才开始进行渲染的。OSG填充场景中每个模型的顶点、法向量等数据生成具体的模型,然后通过glTF描述的场景生成场景图,最后将场景图转换得到状态图实现整个场景的渲染。

场景的渲染首先需要在glTF文件中找到scene元素,即描述整个场景结构的元素,该元素所描述的信息便是整个场景的根节点,本文在第二章节介绍场景的组成,场景是由树形结构组成的,在得到场景的根节点之后,便可以向下遍历该树,本文使用深度优先遍历来得到其所有的子节点。在两个场景节点之间通常含有偏移节点来表示子节点与父节点在空间上的偏移量,因此在向父节点添加子节点数据之前还要创建一个偏移节点,然后将在子节点添加到该偏移节点中。做完这些工作之后,根据子节

29

西安电子科技大学硕士学位论文 点中的材质等信息,创建该子节点的状态集,最后,如果该节点含有纹理信息还需将纹理信息绑定到该节点中。在处理完上述所有内容之后,判断该子节点是否含有子节点,如果有,则按照上述流程继续处理,直至场景中的所有节点都被处理完毕,便完成了对整个场景的渲染。场景渲染伪代码如下所示:

convertModel2SceneGraph (scene, basePath):

loadModelData (scene, basePath); root = new Group;

for (iterator = scene.nodes.begin(); iterator != scene.nodes.end(); iterator++){ }

root->addChild (childNode);

createNode (parentNode, iterator, basePath):

for(it = iterator->children.begin(); it != iterator->children.end(); it++){ }

parentNode->addChild(childNode);

childNode = createNode(it, basePath);

childNode = createNode(root, iterator, basePath);

3.3.3 动画实现模块设计与实现

动画效果是在场景中所有模型节点都构建之后创建的,本文中所涉及的动画主要为关键帧动画。在关键帧动画中主要包含位移、缩放、旋转三种动画类型,动画效果通过设置场景节点的矩阵来实现。

在动画的创建过程中,首先使用动画管理器将动画关联到整个场景的根节点中,然后对每一个含有动画效果的模型创建动画对象,判断该动画使用的动画通道中定义的采集器算法,由于目前本文只支持LINEAR线性插值算法,在判断插值算法不是该类型的时候则直接退出,做完上述工作之后,判断动画效果类型,由于旋转(rotation)使用的是四元数其关键帧类型为QuatKeyframe,而位移(translation)和缩放(scale)使用的是三元数,其关键帧数据类型为Vec3Keyframe,因此要区分对待。在创建完动画对象,并通过数据解析模块得到动画数据,填充到关键帧之后,则将动画通道添加到动画对象中,并将动画对象注册到动画管理器实现对动画统一管理。其流程图如图3.12所示。

30

第三章 glTF模型转换及可视化的设计与实现

开始创建BasicAnimationManageer管理器对象并将其关联到场景根节点创建Animation对象判断动画通道中采集器插值算法是否为LINEAR否是判断动画效果translation或scalerotation创建QuatKeyframeContainer对象创建Vec3KeyframeContainer对象将动画通道添加到Animation对象将Animation对象注册到管理器中并播放动画结束

图3.12 动画创建流程图

在OSG中提供了一系列的工具集支持实时动画的实现,包括变换动画、关键帧动画、骨骼动画,由于本文中主要应用的是关键帧动画。OSG使用OSGAnimation库来实现动画的所用相关内容,关键帧动画的实现过程如图3.13所示。

图中Vec3KeyframeContainer类用来管理数据类型相同的关键帧列表,此类派生自std::vector类,并继承其所有的方法,使用起来很方便;关键帧列表中存储时间点和与时间点相对应的关键帧数据,它们的类型为Vec3Keyframe,可以使用push_back()、pop_back()等方法实现关键帧的压入和弹出,容器中的对象都由OSG::Referenced派生,由智能指针进行管理。

在将关键帧列表准备完成之后,使用定义了插值算法的采样器(Vec3LinearSampler)在关键帧容器中插入元素。在完成了采样器的配置之后,将采样器与动画通道进行关联,动画通道(Vec3LinearChannel)所查找的目标通过setTargetName方法设置,动画通道的目标对象经常是OSGAnimation內建的更新回调,如UpdateMatrixTransform,它使用setUpdateCallback方法关联到特点的节点即要实现

31

西安电子科技大学硕士学位论文 该动画的节点(如图中的Child node),UpdateMatrixTransform更新宿主MatrixTransform节点,并使用每一帧的通道结果修改变换矩阵。

Root nodeBasicAnimationManagerChild nodeAnimationsetUpdateCallbackUpdateMatrixTransformsetTargetNameVec3LinearChannel...Vec3LinearSamplerVec3KeyframeContainer0.0, Vec3Keyframe11.0, Vec3Keyframe22.0, Vec3Keyframe3... 图3.13 关键帧动画创建函数关系图

在做完所有的这些准备工作之后,还需为所有的动画通道声明一个管理器类对象,BasicAnimationManager类所有动画对象的最终管家,它使用registerAnimation、unregisterAnimation、getAnimationList方法管理Animation对象,使用playAnimation、stopAnimation、isgPlaying方法管理动画对象的播放状态。BasicAnimationManager类是一个更新回调,为了实现对整个场景的动画控制,它被设置在场景的根节点中。其中的Animation类是用来管理所有的动画通道的,可以使用addChannel方法实现将通道添加到动画对象中。

表3.1 关键帧数据类型表 采集器类型 FloatStepSampler DoubleLinearSampler Vec2LinearSampler Vec3LinearSampler Vec4LinearSampler QuatSphericalLinearSampler MatrixLinearSampler 关键帧类型 FloatKeyframe DoubleKeyframe Vec2Keyframe Vec3Keyframe Vec4Keyfarme QuatKeyframe MatrixKeyframe 32

关键帧数据类型 float double OSG::vec2 OSG::vec3 OSG::vec4 OSG::Quat OSG::Matrixf 第三章 glTF模型转换及可视化的设计与实现

值得注意的是,在图3.13中的关键帧数据类型并不只有Vec3一种,OSG中支持的采样器类型、相关联的容器及关键帧类如表3.1中所示。

在glTF文件中,动画数据是分开存储的,即关键帧动画的时间与该动画在该时间点的动画状态并不是使用键值对存储在一起的,它使用两个数组分别存放,这样带来的好处是如果关键帧动画在某一时刻具有多种动画效果,不用多次存储动画时间。通过采集器将动画时间与动画状态连接起来,并根据在采集器中定义的插值算法对动画数据进行填充,使得动画效果看起来更加的逼真,本文中插值算法主要应用的是线性插值算法,暂不支持对其他插值算法的解析。在确定好动画的关键帧之后,还要将该动画与节点关联,确定是哪个节点的关键帧动画,这些主要通过在动画中定义的动画通道来实现。具体的动画数据解析过程如图3.14所示。

采集器查找关键帧动画的时间012345根据采集器定义的输入、输出参数确定动画状态跟时间的对应关系0012243648510采集器根据插值算法对数据进行补充000.20.40.61.21.32.61.73.42.34.6根据动画通道确定的节点,对相应的节点进行动画显示nodenodenode

图3.14

动画数据解析图

3.4 模型资源浏览器设计及实现

模型浏览器是glTF文件在Web端的可视化实现,在模型浏览器中实现了比OSG更多的功能,它提供了模型的预览功能及对模型的后台数据管理,模型浏览器主要包含两方面的内容:glTF模型数据服务和模型资源库浏览器。

33

西安电子科技大学硕士学位论文 3.4.1 glTF模型数据服务设计及实现

glTF模型数据服务主要包含两个方面的内容:设计文件存储方式及服务接口。如果使用静态HTTP Server,会在url中暴露文件的组织方式,而且如果模型文件或者文件夹中含有中文名,则无法使用。因此本文使用JSON文件来重新定向文件路径,实现对文件的隐藏。服务器上的文件组织方案如图3.15所示:

根文件夹Meta.json陆地车辆1Thumbview.pngmain.gltf……我方海上glTF-ordinarybuffer1.binshader1.glsl对方空中glTF-binaryimage1.png……………………

图3.15 文件组织结构图

按照图3.15中的文件组织方式,Meta.json文件中存储了所有模型的元数据,具体内容包括模型ID、模型名字、模型文件路径和对模型的详细描述。模型ID是模型的唯一标识,不能是中文或其他在url中需要转义的字符;模型名字可以为中文;模型文件路径为相对于Meta.json的相对模型文件路径,只需要指定到ThumbView.png所在的文件夹即可,服务器会根据从浏览器传过来的模型ID和模型版本找到具体要使用到的文件路径;模型的详细描述包括模型的创建时间、作者、具体功能描述等,可以为空。

模型浏览器实现了对三维模型的预览和浏览两个功能,因此模型数据必须具备两个服务接口,一个获取所有三维模型的预览图片,一个获取三维模型数据的实际存储地址。两个服务接口如下所示:

“http://hostname/model/catagory”:用于获取所有三维模型的预览图片,由于在Meta.json文件中存储了所有模型的相关信息,包括其预览图片,因此通过加载元数据文件,解析元数据文件内容便可以得到模型预览图片的文件地址。前端得到预览图之后,加载每个模型的预览图文件,生成一个Grid视图的html文件,点击一个单元可以加载实际的glTF文件,进入模型浏览页面。该服务接口返回的是Meta.json文件的文件内容。

“http://hostname/model/id/version”:该服务接口用于获取具体的三维模型数据,

34

第三章 glTF模型转换及可视化的设计与实现

服务接口中的“id”表示需要访问的三维模型的ID,“version”表示三维模型的文件存储形式,包含“ordinary”和“binary”两种,每个三维模型都有两种不同的文件存储形式,分别放在该模型文件夹下的两个子文件夹中。该服务接口返回的是需要使用到的三维模型文件的文件路径和该三维模型在Meta.json中的元数据信息。

开始前端发送预览模型请求,返回模型元数据内容根据请求数据,获取需要显示的模型id及version判断模型id与version组合路径上的模型是否存在否是发送对应的文件路径及该模型的元数据给前端结束

图3.16 数据服务流程图

glTF模型数据服务是基于Node.js实现的,在数据服务端主要功能便是实现在模型数据中定义的两个接口。加载元数据文件的服务接口功能比较简单,只需要读取服务器中定义的元数据文件,然后将元数据文件内容发送到前端即可。前端会根据获得的元数据文件信息,找到对应模型的预览图完成对模型预览的加载。在完成对所有模型资源的预览之后,前端会生成对具体模型的浏览按钮,浏览按钮有两个,分别对应不同的模型版本,获取模型数据的服务接口是根据浏览按钮的不同来获取模型的不同版本。该接口返回的是该模型对应版本的文件路径,前端页面使用Three.js实现对模型的加载及显示,其解析过程如图3.16所示。

35

西安电子科技大学硕士学位论文 3.4.2 模型浏览器页面设计及实现

模型资源浏览器是展示模型预览效果与三维模型可视化效果的前端页面,主要有两个界面组成,模型资源目录视图(category.html)和模型浏览视图(webglglTF.html)。资源目录视图以网格形式布局,每个网格对应一个三维模型的信息,目前资源浏览器支持有\"ordinary\两种glTF存储版本,点击相应的三维模型链接按钮,进入模型浏览页面。模型浏览页面主要由四部分构成,三维模型主视图、FPS信息、动画控制面板和该三维模型的元数据信息。三维模型主视图用于显示三维模型、参考网格及实现与三维模型的交互;动画控制面板用于控制动画的启动和停止;模型元数据部分被放置在浏览器的右上角,用于显示该三维模型的具体信息,该部分内容来自数据服务端中的Meta.json文件。

模型资源浏览器在加载资源目录页面category.html文件时向服务器发送Ajax请求元数据,在得到元数据之后,根据得到的数据信息构建模型资源目录页面。根据选择的模型ID及版本号,发送其组合给服务器,可以得到具体的模型资源文件,通过Three.js实现对模型的加载和显示。

开始获取元数据Meta.json文件中的内容判断是否显示完所有的模型预览图是否创建模型显示名称构建下一个模型网格创建模型预览图创建模型version按钮结束

图3.17 模型资源库目录页面构建流程图

36

第三章 glTF模型转换及可视化的设计与实现

在模型资源目录页面中,显示了所有三维模型的预览效果,该预览效果通过加载三维模型的预览图来实现,因此每个三维模型除了具体的三维模型数据之外,还含有该三维模型的静态预览图片。在该页面中,会为每个三维模型创建一个网格来表示该模型在页面的显示信息,网格中含有该模型的名字、预览图以及指向不同版本模型文件的链接按钮。模型名字是从加载的Meta.json文件中对该模型的描述中获得;预览图根据同样是从Meta.json中获取,与模型名字不同的是,预览图的获取是通过Meta.json提供的文件路径对服务器再次请求获得的;链接按钮是从模型资源目录页面跳转到模型浏览页面的入口,每个模型网格中都会含有两个链接按钮,对应该模型两种不同的文件存储形式。具体的资源目录页面构建流程如图3.17所示。

在模型浏览页面中,实现了对三维模型文件的加载、显示和动画效果,由于开源三维渲染引擎Three.js定义实现了对glTF文件格式的接口,因此本文中对三维模型的操作都是基于该三维渲染引擎实现的。在从服务器得到模型文件路径之后,使用Three.js对glTF文件进行加载,在得到具体的模型数据之后调用Three.js库API创建场景、设置相机位置、设置环境光线,然后进行场景的渲染,在对这些元素的初始化完成之后,实现对动画的加载更新。由于需要对动画的播放、停止进行控制,在动画中设置了标志位来确定目前动画的状态,通过按钮反转该状态实现对动画的控制。

除了三维模型的显示,在模型浏览界面还有对元数据信息的显示,该功能通过在界面中添加Table来实现,通过解析元数据文件中该模型的信息描述,将信息添加到Table中,实现对元数据的显示。实现的伪代码如下:

displayModel (basePath):

if (!getDataFromServer(basePath, id, version)) return; addMataData (); addFPS ();

addAnimationControl (); drawing ();

3.5 效果试验

3.5.1

glTF模型转换效率试验

glTF模型转换是指从Collada格式文件转换得到glTF格式文件。表3.2为从Collada格式转换为glTF格式的文件大小变化及转换模型需要的时间。从表中可以得知,随着文件体积的增加,所需要的转换时间也变得越来越长。当Collada文件较小的时候,转换为glTF格式之后,文件甚至会变得比原来更大。但是随着Collada文件的增大,转换得到的glTF格式文件会变得比原文件小。

37

西安电子科技大学硕士学位论文 表3.2 模型转换前后对比表

文件名称 box.dae boxAnimated.dae milktruck.dae monster.dae reciprocating.dae gearbox_assy.dae buggy.dae Collada文件大小(KB) 5.55 25.5 207 650 7169 14067 13705 glTF文件大小(KB) 8.22 26.7 131 404 3735 4957 7896 转换时间(s) 0.05 0.14 0.26 0.68 4.59 6.08 9.01 3.5.2 glTF基于OSG可视化效果试验

基于OSG的可视化是对单个glTF三维模型的显示,包括对模型资源渲染、动画效果、纹理加载。图3.18为一辆包含有纹理和动画效果的glTF三维模型渲染效果图, 该图中的动画效果为车轮的旋转,由于使用静态图片,这里并没有能够体现出动画效果。

图3.18

glTF三维模型可视化效果图

3.5.3 模型资源浏览器效果试验

模型资源浏览器中主要包括两个显示页面,模型资源目录页面和三维模型浏览页面。图3.19为资源目录的显示效果图,点击每个模型浏览图片下面的按钮便可以实时浏览相应的三维模型。图3.20为具体模型的浏览显示效果图,图中左上角和右上角分别表示当前的FPS信息和对该模型的详细描述信息,该图中的模型含有动画,并可以通过点击“play”按钮控制动画的开始和结束,但由于静态图片的显示问题,在

38

第三章 glTF模型转换及可视化的设计与实现

此图中并没有显示出动画效果。

图3.19

模型资源目录实现效果图

图3.20

模型资源浏览实现效果图

39

西安电子科技大学硕士学位论文

40

第四章 基于glTF的三维瓦片格式设计与实现

第四章 基于glTF的三维瓦片格式设计与实现

常用的三维模型存储格式包括glTF在内,它们只包含了三维模型的渲染资源,并没有提供模型对象的属性信息,对象属性需要通过嵌入属性、单独数据表或辅助查询接口提供[28]。本文设计基于glTF文件格式的三维瓦片格式来存储对象属性信息,它使用glTF作为模型资源的存储形式,同时提供了对模型属性信息的存储方法。

4.1 三维瓦片格式设计

本文设计实现了三种不同的三维瓦片格式b3dm、i3dm和pnts,以应对不同的使用场景。b3dm三维瓦片格式主要应用于三维建筑物模型,如整个村庄中所有的建筑物;i3dm的应用场景主要为处理属性相似的三维模型,如大量的路灯、树木;pnts用来表示点云数据。

4.1.1 b3dm瓦片设计

在设计b3dm瓦片之前必须先构建批次表这一概念,批次表是用来存储每个三维模型的用户自定元数据,如建筑物的高度、颜色、名称、地图坐标等等信息,虽然这些信息对于场景的渲染来说并不是必需的,但是这些属性可以在运行时查询声明样式和应用程序用例,例如填充UI或发出REST API请求等。它们是与用户进行交互的关键。批次表在b3dm、i3dm和pnts三种瓦片格式中都有使用到。

{ “id” : [“unique id0”, “unique id1”], “displayName” : [“Building name0”, “Building name1”], “yearBuilt” : [1999, 2015], “address” : [ {“street” : “Main Street”, “houseNumber” : “1”}, {“street” : ”Main Street”, ”houseNumber” : ”2”} ]}

图4.1 批次表示例图

在图4.1中,定义了对表示三维模型属性的批次表,该表中含有三维模型的元数据,建筑物名字、建造时间和地址,所有属性的名称、值都是直接定义在JSON文件中的,在应用的时候根据数组的对应关系来查找,使用数组下标来判断该属性属于哪个三维模型的,如id[0]、 displayName[0]、yearBuilt[0]、address[0]组成一个三维模型的所有属性,下标为1的组成另一个三维模型的所有属性。因此在批次表所有属性

41

西安电子科技大学硕士学位论文 列表中的元素个数都必须是相同的。属性的个数也必须与定义在瓦片头部的batchLength相同,表示此瓦片中含有的三维模型的个数。

Batched 3D Model简称为b3dm,它的主要核心思想是在网络传输和显示模型过程中,使用一次请求能够传输多个模型,并且使用最少量的绘制命令。在b3dm文件中模型的所有顶点都被分配了一个在区间[0,模型文件中的模型数量-1]的数值,每个数值代表模型文件中的一个模型,数值相同的顶点则说明这些顶点是属于同一模型的。该数值就是模型文件中该模型的ID即batchID,在b3dm中所有模型的属性信息都是存储在批次表中并通过batchID关联的。图4.2为b3dm文件的内部结构。

format identifier(unsigned char[4])version(uint32)byteLength(uint32)batchTableJSONByteLength(uint32)24-byte headerbatchTableBinaryByteLength(uint32)batchLength(uint32)batchTablebodyBinary glTF

图4.2

b3dm文件布局

图中元素format identifier的值为“b3dm”,用来识别该文件为b3dm瓦片格式文件;version目前为“1”,表示该瓦片格式的版本号;byteLength表示该文件的总字节长度,包括头部24个字节的长度;batchTableJSONByteLength和batchTableBinaryByteLength分别表示批次表中JSON部分的字节长度和二进制块的字节长度,如果JSON部分为0,则表示该瓦片中没有批次表,其二进制块也会为0。

通过对模型文件中的模型编号,b3dm提供了一种非常有效的识别模型对象的方法,在b3dm文件中,不再用为每个模型定义单独的网格(meshes),在渲染整个模型文件时,将所有的顶点进行渲染,而当需要具体的某个模型信息时,只需传递给顶点着色器该模型的ID,并通过在b3dm中定义的批次表信息查询到相应的模型属性信息。为了支持这种使用模式,必须在glTF文件对每个网格指定额外的“_BATCHID”语法并在顶点着色器中添加对该属性的支持:

attribute float a_batchID;

42

第四章 基于glTF的三维瓦片格式设计与实现

其具体的使用情况如图4.3所示。

“technique”: { “attributes”: { “a_batchId”: “batchId” } , “parameters”: { “batchId”: { “semantic”: “_BATCHID”,“type”: 5123 } }} 图4.3 批次表在glTF中应用

可以看出在b3dm瓦片格式中,对场景的渲染并不是将每个模型单独渲染然后再组合在一起的,对于应用程序来说,整个瓦片相当于一个模型对象,直接将瓦片中所有模型对象的顶点属性传给着色器,进行一次性的渲染。当要选取瓦片中的某个具体的模型对象时,瓦片会通过批次表来查询选取的该模型对象ID,然后在对其做相应的处理,如获取名称、建筑时间、地址、显示、隐藏或者改变模型对象的颜色等。

4.1.2 i3dm瓦片设计

在i3dm瓦片格式中含有特征表,该表在b3dm和pnts瓦片中并没有使用,它主要用在i3dm这种瓦片格式中。特征表的用途是具体描述瓦片中每个模型的位置、方向等信息。在特征表中定义了大量的语法来表示模型属性如INSTANCE_LENGTH、POSITION、NORMAL_UP、NORMAL_RIGHT、SCALE等等,他们分别表示模型个数、该模型的位置、朝向及模型的缩放。不同于批次表中每个属性列表中的元素个数都必须相同,特征表并没有这方面的限制。如特征表中会含有INSTANCE_LENGTH属性表示瓦片中三维模型的个数,该属性为uint32类型的数字,在该属性中只会含有这一个元素,而表示位置信息的POSITION属性在三维坐标系中,每个坐标点都是由三个元素构成的,因此该属性的元素个数等于INSTANCE_LENGTH的值乘以3。在计算每个三维模型的坐标的时候,会按照每三个元素为一个属性的方式进行处理。

特征表在文件中的存储形式如图4.4所示,在特征表的JSON部分中定义了模型的个数和每个模型的位置坐标,具体的模型位置数据存储在特征表的二进制块中,每个模型对应一个含有三个元素的数组,分别表示它的x、y、z轴坐标,在这个例子中定义了一个含有四个模型的特征表表,每个模型分别放置在坐标系统中的xz面一个正方形区域的一角。

43

西安电子科技大学硕士学位论文 var featureTableJSON = { INSTANCES_LENGTH: 4, POSITION: { byteOffset: 0 }};var feature Table Binary = new Buffer(new Float32Array([ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0]).buffer);

图4.4 特征表示例图

i3dm的全称为Instanced 3D Model,与b3dm不同,i3dm处理的不是大量的异构模型,相反,它更适合处理模型属性及其相似的大规模模型,如树、路灯等。对于这种类型的模型来说,不需要将每个模型都存储起来,只需存储一个模型数据和每个模型的位置坐标即可实现渲染效果,i3dm便是使用此种策略构建起来的。i3dm的布局结构如图4.5所示:

format identifier(unsigned char[4])version(uint32)byteLength(uint32)featureTableJSONByteLength(uint32)featureTableBinaryByteLength(uint32)batchTableJSONByteLength(uint32)batchTableBinaryByteLength(uint32)32-byte headerglTF format(uint 32)featureTablebatchTablebodyBinary glTF

图4.5

i3dm结构图

图中元素与b3dm中元素基本相同,只是多了glTF format与特征表相关的元素,glTF format用来指定要使用到的模型的存储形式,“0”表示glTF模型数据存储在外部文件并通过url来指定,“1”表示glTF模型文件数据是嵌入到二进制块中的。特征表定义了模型的位置、朝向等属性,通过在特征表中定义的模型属性,便可以将一个模

44

第四章 基于glTF的三维瓦片格式设计与实现

型数据在场景中渲染出大批模型的效果,这也就是i3dm要实现出来的效果。

4.1.3 pnts瓦片设计

除了i3dm和b3dm两种瓦片格式之外,还有另一种瓦片格式pnts,这种瓦片格式与i3dm及其相似。都是通过定义特征表来完成对模型场景的描述,但不同的是,pnts瓦片格式存储的不是模型数据,而是一个个离散的点。它通常用来表示点云(Point Cloud)这种数据类型。在pnts瓦片格式的特征表中定义是点的位置坐标、颜色等信息。其布局结构与i3dm一样,只是在pnts瓦片格式中并不存在具体的模型数据,取而代之的是点,因此pnts的结构布局与i3dm相比,缺少了glTF format和binary-glTF两个区域,所有点的有关数据都存储在特征表中,如图4.6。

format identifier(unsigned char[4])version(uint32)byteLength(uint32)featureTableJSONByteLength(uint32)featureTableBinaryByteLength(uint32)28-byte headerbatchTableJSONByteLength(uint32)batchTableBinaryByteLength(uint32)featureTablebatchTablebody

pnts结构图

图4.6

在pnts瓦片格式中的特征表定义了大量的语法来描述点的位置、颜色、法向量等信息,在pnts瓦片格式中定义了两类语法,全局语法(global semantics)和点语法(point semantic)。在全局语法中定义了所有瓦片中的点所共有的属性,如瓦片中点的数量、点的全局颜色、及瓦片中用到的批次表的长度等;点语法则侧重每个点的具体信息,如点的坐标位置、颜色、法向量、在批次表中的batchID。

在点语法中定义的语法中含有的元素个数必须与在全局语法中定义的点数量相同,即每个点对应一个语法元素。点语法之间存在关联性,当一个语法的定义依赖于另一个语法时,则被依赖的语法也必须要被定义。如果两个语法同时定义了相同的语义,例如在“POSITION”和“POSITION_QUANTIZED”同时被定义的时候,往往使用精确度更高的“POSITION”来作为点的位置坐标。

45

西安电子科技大学硕士学位论文 4.2 glTF转换三维瓦片

在三维瓦片应用中,模型数据的存储模式都为二进制形式,所有与场景有关的信息都只包含在一个文件中,包括节点数据、场景层次、纹理图片等等。由于瓦片格式的不同,在三维瓦片中需用到glTF文件的主要有b3dm和i3dm两种格式,pnts格式主要使用点数据不需要具体的数据模型,因此,本文主要介绍了前两种瓦片格式的转换过程。

4.2.1 glTF转换b3dm设计实现

b3dm三维瓦片格式对glTF在原有的基础数据之上添加了batchID属性,并将原有的glTF文件格式转换为二进制模式。除此之外还添加了glTF文件中模型的属性信息,属性信息的添加是通过批次表来实现的。

开始加载存放glTF文件路径的json文件判断是否处理完所有glTF文件是否加载glTF文件在mesh元素中添加batchId属性添加对batchId的语法定义及着色器变量在program元素中添加着色器属性生成包含文件数据信息的二进制块添加批次表及b3dm头部信息结束

图4.7 glTF转换b3dm流程图

46

第四章 基于glTF的三维瓦片格式设计与实现

对glTF文件的转换通常都是批量进行的,因此本文设计将所有需要转换的glTF文件路径存放在一个JSON文件中,通过加载此文件,找到每个模型文件的存放路径,实现一次加载多次转换的效果。对每个模型文件的处理是独立的,虽然b3dm使用glTF文件作为模型存储格式,但是由于在b3dm中需要模型文件中的每个模型都有唯一的ID,因此b3dm使用的glTF需要在原来的glTF文件格式中,添加自定义的内容。这就使得对glTF文件转换不仅仅添加头部信息那么简单,必须要重新打开glTF文件,向文件中添加自定义内容,对于此转换过程,需要添加的自定义内容主要有:为mesh元素添加batchId属性、该属性的语法定义、对着色器变量的映射、着色器代码中的变量。b3dm使用glTF的二进制存储形式来表示,因此要将glTF的所有数据转换为二进制块,并在b3dm头部添加批次表信息和头部描述数据。其具体的转换流程图如图4.7所示。

在mesh元素中对“BATCHID”属性的添加是根据mesh元素中的“POSITION”属性实现的,由于在glTF文件中所有的数据信息都被存放在外部二进制文件中,而元素属性值都为解析二进制信息的Accessor元素,因此在添加“BATCHID”属性的过程中,实际上添加的是解析其在二进制块中数据的Accessor元素,添加前后的对比如图4.8所示。

{ “Geometry-mesh001”: { “primitives”: [ … “attributes”: { “NORMAL”: “accessor_01”, “POSITION”: “accessor_02” … }, … ] }}{ “Geometry-mesh001”: { “primitives”: [ … “attributes”: { “NORMAL”: “accessor_01”, “POSITION”: “accessor_02”, “BATCHID”: “batchid_accessor_01” … }, … ] }}

图4.8

Mesh元素添加批ID属性图

在3.3.2章节本文介绍过数据的解析过程,是由accessor、bufferView、buffer三个元素一起实现的,因此在添加对批ID属性的accessor数据之后,还要添加该accessor使用的bufferView元素,对于每个模型资源来说,顶点的位置属性与批ID属性个数是相同的,本文中批ID属性使用与位置属性相同的bufferView作为中间解析信息,并通过设置批ID属性的accessor的偏移量来确定该属性的二进制数据位置。

在Mesh中添加过批ID属性之后,需要在glTF中添加对该属性的语法定义及该属性与着色器程序代码中变量的映射关系。这些可以通过在Technique元素中添加

47

西安电子科技大学硕士学位论文 attribute和parameter属性来实现。在parameter属性中除了添加属性的语法定义之外,还需要指定该属性的属性值类型,对于批ID属性来说,其类型为unsigned short,使用“5123”来表示。在attribute属性中,则指定了在glTF定义的属性与该属性在着色器代码中变量的映射关系。添加完这些信息之后的对比图如图4.9所示,此外为了明确在着色器代码中需要使用的attribute变量,需要在glTF文件中的program元素中添加对变量的声明如图4.10所示。

{ “technique0”: { “attributes”: { “a_position”: “position” … }, “parameters”: { “position”:{ “semantic”: “POSITION”, “type”: 35665 },... }, … }}{ “technique0”: { “attributes”: { “a_position”: “position”, “a_batchid”: “batchid” … }, “parameters”: { “position”:{ “semantic”: “POSITION”, “type”: 35665 }, “batchid”:{ “semantic”: “BATCHID”, “type”: 5123 },... }, … }}

图4.9 technique元素添加批ID属性图

{ “program0”: { “attributes”: [ “a_position”, “a_batchid” … ], … }}

{ “program0”: { “attributes”: [ “a_position” … ], … }}

图4.10

program元素添加批ID属性图

在完成所有对glTF中JSON文件内容的操作之后,还需要对模型资源数据信息进行处理,包括外部二进制文件、纹理图像文件、着色器代码文件和批ID属性数值。b3dm使用单个文件存储所有的这些信息,因此将这些文件内容读取并以二进制形式存储在b3dm文件中。批ID属性数值会被添加到原来glTF二进制数据末尾,并且可以通过前面定义的accessor属性进行解析。对于着色器代码来说,需要在代码中添加变量“a_batchid”实现对模型的分块处理。

最后需要对b3dm按照图4.2结构布局添加头部描述信息及批次表属性,将所有的内容写入到后缀名为.b3dm的文件中,便完成了从glTF文件到b3dm文件的转换。

48

第四章 基于glTF的三维瓦片格式设计与实现

4.2.2 glTF转换i3dm设计实现

在glTF文件转换为i3dm的过程中,除了要添加批次表之外,还要添加特征表,与b3dm中含有大量不同的异构三维模型不同,i3dm中使用到的glTF文件通常只有一个,通过特征表将一个模型复制成大量的模型。在i3dm的头部需要填充的内容主要有:格式标识符、版本号、文件总字节长度、特征表长度、批次表长度。

由于在i3dm文件中既有使用到批次表又有用到特征表,因此它比b3dm的转换更加的复杂,但是对于批次表的添加其过程与b3dm是一样的,可以直接使用b3dm的转换流程,在i3dm中添加批次表相关信息,其过程如上一章节介绍的一样,这里就不再赘述。在添加完批次表相关信息之后,要在i3dm文件中添加特征表相关信息,特征表是实现从一个模型扩展到大量模型的关键。对特征表的添加比较简单,不像对批次表添加那样需要重新打开glTF文件向文件内添加属性数据,特征表不需要对glTF文件内部做更改,它将整个glTF文件看做一个模型,特征表只需添加对该模型的索引,并设定模型个数、每个模型的位置、朝向等信息,便实现了对该模型的复制。因此直接读取特征表内容,并在i3dm文件中按照图4.11文件头部结构添加头部数据完成文件格式转换。

开始获取文件路径,判断文件是否存在否是加载glTF文件将glTF所有文件合并并使用二进制形式存储添加批次表信息加载特征表内容添加i3dm文件头部数据信息结束

图4.11 glTF转换i3dm流程图

49

西安电子科技大学硕士学位论文 4.3 效果试验

4.3.1

b3dm效果试验

在b3dm格式三维瓦片文件中除了含有对模型的渲染资源外,还包括模型的属性信息和样式信息。图4.12为b3dm瓦片文件的效果图,在渲染完模型之后,当选取到该模型时,显示存储在瓦片文件中的属性信息和样式信息,图中在选中该模型时显示了该模型的ID并且改变模型颜色。

图4.12

b3dm三维瓦片文件效果图

4.3.2 i3dm效果试验

i3dm格式瓦片文件的应用场景是场景中的模型相同,如图4.13中,场景中的大量树模型是由一个树模型衍生出来的。在i3dm文件中只包含了一个三维模型渲染数据,通过设置每个模型的位置、朝向属性实现图中的显示效果。

图4.13

i3dm三维瓦片文件效果图

50

第四章 基于glTF的三维瓦片格式设计与实现

4.3.3 pnts效果试验

pnts格式瓦片文件用来实现点云数据,在pnts文件中没有包含具体的模型渲染资源,它的渲染资源是由点构成的。pnts格式三维瓦片文件渲染效果图如图4.14所示。

图4.14

pnts三维瓦片文件效果图

51

西安电子科技大学硕士学位论文

52

第五章 三维瓦片金字塔的设计与实现

第五章 三维瓦片金字塔的设计与实现

三维瓦片金字塔结构是实现对城市三维模型可视化的关键,由于城市三维模型中模型内容多样,使得模型文件都很大,如果需要渲染的场景含有大量的模型文件,一次性的将所有的数据加载到内存是不现实的。三维瓦片金字塔是一种多分辨率的层次结构,从瓦片金字塔顶层到底层,模型的分辨率越来越高[29]。借助三维瓦片金字塔,如果在需要渲染整个场景时,使用三维瓦片金字塔顶层数据进行渲染,在需要渲染场景的某个具体角落时,使用三维瓦片金字塔相应的底层数据进行渲染提高模型显示的清晰度。

5.1 四叉树

由于空间数据具有时空、多维、多尺度、海量数据等特征,对于空间数据的组织管理就变得极其重要和复杂。通常使用空间索引技术来完成,空间索引技术就是通过更加有效的组织方式,抽取与空间定位相关的信息组成对原空间数据的索引,以较小的数据量管理大量数据的查询,从而提高空间查询的效率和空间定位的准确性[30]。空间索引技术需要满足三个特定的要求:每个要素在一个或多个网格中、每个网格可含多个要素、要素不真正被网格分割。在三维瓦片中,主要使用的空间索引技术为四叉树。

四叉树的基本思想是将已知范围的空间等分成四个相等的子空间,如此递归下去,直至树的层次达到一定深度或者满足某种要求后停止分割。四叉树的结构比较简单,并且当空间数据对象分布比较均匀时,具有比较高的空间数据插入和查询效率,因此四叉树是常用的空间索引之一[31]。四叉树索引又分为很多种类,包括点四叉树、PR四叉树、MX四叉树等。

点四叉树与k-d树相似,两者的差别是在点四叉树中,空间按照点所在的位置被分割成四个矩形。其搜索过程和k-d树相似,当一个点包含在搜索范围内时被记录下来,当一个子树和搜索范围有交叠时它将被穿过,如图5.2所示:

53

西安电子科技大学硕士学位论文 ABCBFCDEIADHGEFGHI 图5.1

点四叉树示例图

BCBCEFEADHGAFIGDHI 图5.2

PR四叉树示例图

PR四叉树[32]是点四叉树的一个变种,它不使用数据集中的点来分割空间。在PR四叉树中,每次分割空间时,都是将一个矩形分成四个相等的子矩形,依次进行,直到每个矩形的内容不超过所给定的桶量(比如一个对象)为止,如图5.3所示。

MX四叉树与PR四叉树的空间分割方法是一样的,都是将矩形分为四个相等的子矩形。与PR四叉树不同的是,MX四叉树中所有的数据都处在四叉树的同一个深度,多个点可以由一个指针联接,如下图所示:

BCFEADHIGBCEAFIGDH 图5.3 MX四叉树示例图

在三维瓦片中,当每个瓦片中都含有的四个孩子时,四叉树这种数据结构就会被

54

第五章 三维瓦片金字塔的设计与实现

使用。不同于二维瓦片的四叉树,在三维瓦片中当四个孩子并不是均匀分布,甚至当这四个孩子互相之间有重叠的时候,四叉树一样可以被使用,只是此时使用的是四叉树的一种变形模式宽松四叉树(loose quadtree)。宽松四叉树是指将父瓦片分为大小并不是完全一样的四个瓦片,这四个瓦片之间可以相互的重叠。它即可以保持空间数据的层次性,同时可以避免场景中的模型被切割。例如,在场景中存在一座大厦,它正好位于两个孩子瓦片之间,大厦的一部分属于一个瓦片,而另一部分属于另一个瓦片,由于大厦本身是一个整体并不能将其切分为两部分来分别渲染,而宽松四叉树的特点便是四个孩子瓦片的大小可以不同,因此可以将此大厦划分为一个瓦片,避免对它的切割,如图5.4描述了此种情况。

图5.4

宽松四叉树示例图

在三维瓦片中还有另外一种四叉树的变形结构,适配空间四叉树(tight-fitting quadtree),它将所有划分出来的子空间进行缩减,使得包含有模型数据的子空间得到保留,不含有模型数据的空白空间则舍弃掉(如图5.5所示),这种索引结构可以降低对无用空间的划分,提高查找三维模型数据的效率。

图5.5

适配空间四叉树示例图

5.2 三维瓦片金字塔设计及构建

5.2.1

三维瓦片元数据设计

瓦片的空间数据结构通过瓦片元数据来表示,元数据内容如表5.1所示。

55

西安电子科技大学硕士学位论文 boundingVolume.region属性是一个含有6个数的数组,这个数组按照特定的排列顺序定义一个地理区域([west, south, east, north, minimum height, maximum height]),其中经度和纬度使用弧度作为计量单位,高度使用米作为计量单位。在每个瓦片中都定义有这样一个空间包围盒(bounding volume),所有该瓦片的图形数据都必须包含在这个空间包围盒中,由于组织瓦片的空间数据结构具有空间层次性,因此所有孩子瓦片中的图形数据都必须在其父瓦片的空间包围盒中。为了更好的划分不同空间结构数据的空间包围盒,如建筑物数据、整个城市数据及点云数据等,空间包围盒可以为四方体、球体或者由经度、纬度、高度定义的地理区域。一个瓦片中可能含有一个多个模型数据,例如,瓦片中含有建筑物、树、点云中的点、向量数据中的点、多边形等;为了降低客户端的加载时间和WebGL的渲染开销,这些模型在瓦片中会被合并成一个模型来处理。

表5.1 三维瓦片元数据表

名称 boundingVolume geometricError refine viewerRequestVolume content transform children 描述 定义包围其三维模型的地理区域 使用一个非负数值定义误差 指定细化模型使用的模式 定义视图区域 指定瓦片中含有的具体模型数据 定义一个4*4的矩阵表示瓦片中模型、boundingVolume等的变换 定义了该瓦片的子瓦片

geometricError属性在LOD中使用,它定义了以米单位的视角距离,决定了瓦片中定义的模型在多远的距离开始渲染以及何时使用高级别LOD来替代低级别LOD。

viewerRequestVolume属性按照和空间包围盒一样的方法定义了一块地理区域,当视角在这块区域之外则该瓦片在空间包围盒中定义的内容不会渲染,只有在视角进入该区域之后,该瓦片中的内容才会被加载渲染。它的另一个作用是可以用来对不同结构的数据集进行组合。举个例子,在瓦片的空间包围盒中定义一个半径为1.25的球体1,并在瓦片中定义viewerRequestVolume为一个半径为15的球体2,则只有当视角进入球体2所定义的区域后,才能看到球体1,否则看不到球体1。

refine属性指定的细化模型的模式主要有“replace”和“add”两种,“replace”模式是使用一个新的更加清晰的模型来替换原来的旧的模糊的模型,而“add”模式则是在原来的模型中添加细节来是模型看起来更加的精细。这个属性必须在三维瓦片的根瓦片

56

第五章 三维瓦片金字塔的设计与实现

中指定,子瓦片可以指定自己瓦片中的内容的细化模式,若没有指定,则从其父瓦片中继承。

content属性指定瓦片用来显示的图形数据,它可能指向具体的模型文件,也可能指向另一个瓦片文件。在content属性中也定义了一个可选的空间包围盒,与顶层空间包围盒不同的是,在瓦片内容中的空间包围盒定义了一个相对于顶层空间包围盒更小的区域来囊括瓦片中的模型数据,图5.6中虚线区域为顶层空间包围盒定义的区域,实线区域为瓦片内容中的定义的空间包围盒涵盖的区域。对于“replace”模式来说,顶层空间包围盒提供了空间区域的一致性,而在瓦片内容中定义的空间包围盒则用来裁剪具体模型所在的空间区域视图,若在瓦片内容中没有定义空间包围盒,就会使用顶层空间包围盒实现此功能。

图5.6

content.boundingVolume与boundingVolume区别

transform属性是一个可选属性,它的主要作用是支持瓦片中的局部坐标系统。比如说,一个在城市瓦片中的建筑物瓦片,它可以定义自己的建筑物坐标系统,而在此建筑物瓦片中的点云瓦片也可以定义自己的点云坐标系统。transform属性定义了一个4*4以列为主的矩阵,以实现将子瓦片中的局部坐标转移到其父瓦片中的坐标系统中,最终通过transform属性将其映射到根瓦片中。transform属性主要应用在瓦片的content、boundingVolume、viewerRequestVolume三个属性中,并不影响geometricError属性。对于content来说,transform主要应用在模型的位置坐标、法向量,值得注意的是如果content.boundingVolume.region、tiles.boundingVolume.region或者tiles.viewerRequestVolume.region被定义之后,transform属性也不会影响其定义的区域,因为这些被定义的区域是使用WGS84坐标系确定的地理区域,这些区域含有固定的坐标,并不会被transform矩阵影响。

对于没有定义transform属性的瓦片来说,其默认值为4*4的单位矩阵,将瓦片的局部坐标转换到全局坐标是使用自上而下的点乘算法实现的,即使用父节点的转换矩阵右乘子节点的转换矩阵。

57

西安电子科技大学硕士学位论文 T0T1T2T3b3dmT4i3dm 图5.7 transform属性计算规则

对于上述结构的瓦片集来说,每一个瓦片转换矩阵计算结构如下: T0: [T0] T1: [T0][T1] T2: [T0][T2] T3: [T0][T1][T3] T4: [T0][T1][T4]

当然,仅仅依赖瓦片中transform属性并不能确定模型的最终位置坐标、法向量等,以图5.7为例,b3dm和i3dm是以glTF格式作为模型的存储格式,而glTF模型文件本身也定义了组成此模型的节点之间的转换属性,因此最终的每个节点的位置坐标和法向量都必须在得到的上述转换矩阵之后再乘上glTF本身定义的转换矩阵,才能得到。

通过上述描述,整个瓦片的结构如图5.8所示:

空间包围盒空间误差细化模型模式内容空间包围盒模型文件url孩子瓦片b3dm或i3dm模型文件或者外部tileset.json

图5.8 瓦片结构图

58

第五章 三维瓦片金字塔的设计与实现

5.2.2 三维瓦片元数据文件组织结构设计

三维瓦片元数据是存储在tileset.json文件中的,文件中含有瓦片本身的模型数据与该瓦片的细分孩子瓦片。在具体的场景应用中,整个场景是由一张张瓦片组成的,这些瓦片可以定义在一个tileset.json文件中,通过其中的“children”属性将所有的瓦片拼接起来;也可以将每张瓦片的内容单独的存储在一个tileset.json文件中,通过“content.url”属性将这些文件连接起来达到同样的效果。例如在每个tileset.json文件中定义城市中的一个建筑物,然后使用全局tileset.json来管理城市中的所有建筑物,如图5.9所示:

tileset0.jsontileset1.jsontileset2.jsontileset3.jsontileset4.jsontileset5.jsontileset6.jsontileset7.json 图5.9 tilesets组织结构图

在使用后者来实现三维瓦片金字塔的时候,如果一个瓦片定义了指向外部瓦片的文件,那么这个瓦片的孩子属性则必须是未定义或者为空,并且在外部瓦片的定义中其内容属性要与本瓦片的内容一致,如:误差、细化渲染模式、定义的空间包围盒、视角空间等即为如下形式:

root.geometricError === tile.geometricErrorroot.refine === tile.refineroot.boundingVolume === tile.content.boundingVolume root.boundingVolume === tile.boundingVolumeroot.viewerRequestVolume === tile.viewerRequestVolume 图5.10

引用外部瓦片文件条件

瓦片之间的相互引用关系不能形成环路,如引用此瓦片的瓦片又将引用指向此瓦

59

西安电子科技大学硕士学位论文 片,即形成瓦片之间的相互引用,这种引用关系会导致瓦片之间无休止的循环,没办法进行渲染。对于瓦片中定义的偏移与外部瓦片中定义的偏移都要应用,如图5.11示意定义了两个瓦片文件,其中T0、T1定义在一个文件中,T1是T0的孩子节点,T2、T3定义在另一个文件中,T3是T2的孩子节点,则T3的最终偏移为:[T0][T1][T2][T3]。

T0T1指向外部文件T2T3 图5.11

外部瓦片的偏移使用图

5.2.3 三维瓦片金字塔的构建设计与实现

在得到具体模型的三维瓦片存储结构之后,还要将这些瓦片按照空间数据结构组织起来。如果一个场景中含有大量的三维模型,那么一次将所有的模型文件装入内存进行渲染显然是不可能实现的,构建三维瓦片金字塔则是解决这一问题的方法途径。三维瓦片金字塔使用LOD技术,该技术使得在观察视点距离模型较远的时候使用粗略的模型来显示以降低每个模型占用的空间,在观察视点拉近与模型之间的距离之后,再具体渲染该模型的细节。至于拉近到什么样的距离才渲染具体细节,则是由在三维瓦片元数据的geometricError中定义的。

三维瓦片金字塔结构是由存储瓦片的tileset.json文件之间的相互关联来实现,常用的构建三维瓦片金字塔的空间数据结构为四叉树,图5.12为使用四叉树构建得到的结构图,在每个tileset.json文件中都指定了需要被渲染的三维瓦片格式(b3dm或i3dm)的数据。在这棵树中每个节点都含有四个子节点,将该节点中定义的空间划分为四个子空间,子空间中含有对空间区域更加细致的模型文件,在子节点中又含有四个孙子节点,如此递归分割。在视角进入具体的子空间之后,只需要请求该空间中包含的数据,不用理会其他空间数据,这样实现整个场景的渲染。

在设计完成三维瓦片金字塔元数据、空间数据结构及文件组织结构之后,还需实

60

第五章 三维瓦片金字塔的设计与实现

现对三维瓦片金字塔的构建。本文使用四叉树来构建实现,由于在场景中通常含有大量的三维瓦片文件,要将这些瓦片文件按照四叉树组织,必须定义数据结构来确定每个瓦片的位置,及它们之间的关系。本文通过数组形式来定义瓦片的树形结构,即按照深度优先遍历要生成的瓦片金字塔,若瓦片没有孩子则在数组中插入空值,如果有孩子则将该瓦片的名字插入到数组中,这样便可以使用数组来表示瓦片的组织结构。

tileset0.jsontileset00.jsontileset01.jsontileset02.jsontileset03.jsontileset010.jsontileset011.jsontileset013.jsontileset013.json 图5.12

四叉树组织三维瓦片金字塔结构图

在确定瓦片的树形组织结构之后,还要确定每个瓦片相对于父瓦片的偏移矩阵,这个偏移矩阵需要按照自己的需求定义,偏移矩阵的存储与瓦片结构存储一样,使用数组存储,并且与瓦片数组向对应,即瓦片名字在瓦片数组中的下标与该瓦片使用的偏移矩阵在偏移矩阵数组中的下标必须一致。

瓦片数组与偏移矩阵数组确定后,还要对瓦片元数据进行填充,使用tileset.json文件构建瓦片金字塔结构。瓦片元数据中含有空间包围盒、误差、模型细化模式、瓦片文件url及孩子瓦片。在每个瓦片文件中都含有该瓦片的空间包围盒,瓦片元数据中空间包围盒是能够将所有在该瓦片中的瓦片文件包含在内的空间包围盒体积大小。误差表示的是观察点与模型的距离在多远的情况下,使用高级别LOD来替代低级别LOD,此值通常通过设置为父瓦片的一半。最后,还需要填充该瓦片的孩子瓦片,本文使用瓦片数组来存储所有的瓦片并使用四叉树构建瓦片金字塔,因此当该瓦片没有孩子瓦片是其在数组的形式为如下形式:

[...,“tile”, “”, “”, “”, “”,...]

通过此种方式来判断是否需要创建该瓦片的孩子瓦片。具体的瓦片金字塔构建流程图如图5.13所示。

61

西安电子科技大学硕士学位论文 开始读取存储三维瓦片文件路径的json文件判断文件读取是否成功是否读取存储三维瓦片之间位移矩阵的json文件判断文件读取是否成功否是创建根瓦片的包围盒设置误差值及模型细化模式创建孩子瓦片开始

图5.13 创建三维瓦片金字塔流程图

构建孩子瓦片结构与构建根瓦片结构略有不同,因为在子瓦片中除了根瓦片中所含有的元数据之外,还包括子瓦片相对于父瓦片的偏移矩阵,该偏移矩阵也通过数组存储,并与瓦片数据一一对应,在构建子瓦片的过程中,需要在此数组中找到相应的下标并将其内容添加到子瓦片元数据中。构建子瓦片之后,判断该子瓦片是否含有孙子瓦片,判断方式与在根瓦片中的判断方式一样。如果含有孙子瓦片则使用递归方式继续创建,直到该瓦片中的所有子瓦片都被创建。创建子瓦片的伪代码如下所示:

createChildTile (currentTile, tilsetFilePath):

if (currentTile == NULL) return; childTile = new Tile; setData(tilesetData, Tile);

createChildeTile(childTile, tilesetFilePath);

62

第五章 三维瓦片金字塔的设计与实现

5.3 三维瓦片金字塔的可视化设计与实现

5.3.1

三维瓦片金字塔调度

三维瓦片金字塔可视化是通过解析tileset.json文件加载具体的模型文件来实现的,因此可视化过程包括对tileset.json文件的加载解析、判断当前需要加载三维瓦片文件、解析瓦片文件加载具体的模型文件以及在不需要三维瓦片文件时将其从内存中删除。

tileset.json三维瓦片文件瓦片中含有的模型数据请求需要加载的tileset.json加载加载tileset.json解析tileset.json处理请求需要用到的瓦片文件解析瓦片文件就绪解析瓦片模型数据绘制模型数据卸载瓦片集卸载瓦片内容卸载瓦片模型数据 图5.14

三维瓦片金字塔调度图

对tileset.json文件的加载是在加载阶段完成的,加载完成之后进入处理阶段,该阶段对tileset.json文件进行解析,构建整个场景的树形结构,并加载其误差值,但是在这个阶段并没有请求具体的模型数据,只保存了该三维瓦片树上的所有节点及它们之间的关联,此时内存中只含有属性信息,并没有正式加载数据内容,所以对于大量模型数据来说,计算机内存是可以承受的。

在完成三维瓦片树的构建之后,便可以根据具体的情况请求需要渲染的瓦片文件。在请求具体的瓦片文件数据过程中,根据LOD策略决定哪些瓦片数据需要进入渲染队列,为了避免对同一数据的反复请求,设置标识contentUnloaded来判定该数据是否已经下载过,若没有,则发送请求。在数据下载完成之后,被添加到两个队列:processQueue和removeQueue等待后续处理。在tileset.json文件中定义的geometricError属性是实现这一功能的关键,它定义的视点与模型的距离决定了何时需要加载高级别LOD替代低级别LOD。具体过程如图5.14所示。

63

西安电子科技大学硕士学位论文 对于b3dm和i3dm两种瓦片文件,两者所表示的模型数据都是通过glTF文件存储的,因此三维瓦片金字塔的显示实质是对glTF模型资源的可视化,本节主要负责对瓦片金字塔结构解析,得到相应的glTF文件。

5.3.2 三维瓦片金字塔渲染

在解析得到瓦片模型数据之后,要开始对模型数据的绘制,在本文设计实现的三维瓦片文件格式都是基于glTF格式实现的,即三维瓦片文件中的模型数据资源都是通过glTF格式文件存储的。对三维瓦片金字塔的渲染归根到底是对glTF格式所描述的模型资源的渲染。本文在第二章中详细介绍了glTF格式文件对模型资源的存储形式及对模型数据的解析方法,三维瓦片金字塔具体渲染调度如图5.15所示。

JSON部分内容二进制部分内容渲染资源数据获取scene元素内容获取node元素内容加载获取accessor元素内容...解析元素内容解析根据元素内容解析二进制数据渲染填充渲染资源数据,进行模型绘制 图5.15

三维瓦片金字塔渲染调度图

通过对三维瓦片文件的解析得到glTF格式的三维模型数据资源,解析glTF格式数据,获得整个模型的结构和对二进制数据的解析信息。通过这些信息对二进制数据进行解析得到具体的渲染资源数据,并填充到渲染引擎中进行模型绘制。其具体的解析过程与3.3章节对模型的解析类似,这里就不再赘述。

5.4 效果试验

图5.16为三维瓦片金字塔显示效果图,在图中,不同高度的建筑物会根据自身

64

第五章 三维瓦片金字塔的设计与实现

高度显示为不同的颜色,建筑物高度在10米之下的为橘红色,高度在10米与20米之间颜色为深褐色,高度在20米与50米之间颜色为黑色,高度在50米与100米之间为浅蓝色。

图5.16

三维瓦片金字塔效果图

当鼠标悬停在某个建筑物之上后,会默认选中该建筑物。根据设定的代码,当该建筑物被选定之后,会将该建筑物的颜色设置为半透明,并渲染成黄色状态,具体效果图如5.17所示

图5.17

建筑物选中效果图

使用鼠标点击建筑物之后,会弹出该建筑物的具体属性信息,这些属性信息包括

65

西安电子科技大学硕士学位论文 建筑物名字、ID、所属瓦片等,具体效果实验图如图5.18所示。

图5.18

点击建筑物效果图

66

第六章 总结与展望

第六章

6.1 总结

总结与展望

本文针对目前三维模型结构复杂混乱、类型多样,导致三维模型资源之间可重用性差,以及在城市三维模型可视化中存在的三维模型数量多、数据量大、网络传输与显示效率要求高等问题,提出新的解决方案。构建了以glTF格式为基础的三维模型处理、管理和可视化服务,并提出设计了三维瓦片金字塔结构来解决上述问题。本文研究内容对城市三维模型数据的共享、管理及可视化有重要的参考意义。

本文围绕glTF文件格式,以解决现阶段三维模型可重用与城市三维模型数据可视化为目的,论文所取得的成果有:

(1)总结了glTF三维模型格式特点及数据存储方式,针对三维模型数据占用存储空间大的问题,提出了对glTF模型数据存储的优化方案。

(2)设计实现了从Collada格式到glTF格式的文件转换工具,解决了现有模型格式复杂、可重用性和共享性差等问题。

(3)实现了在OSG中对glTF格式文件的可视化功能,并设计实现模型资源浏览器加强对模型资源的管理。

(4)设计了基于glTF的三维瓦片文件格式,使得在三维瓦片文件中增添了对模型属性的描述信息,并基于空间数据结构构建了三维瓦片金字塔,实现了其可视化功能。

6.2 展望

本文虽然在基于glTF的相关服务方面做了很多的研究,取得了一定的研究成果,但由于时间及glTF作为新三维模型格式的原因,还存在一些不足之处需要完善,主要涵盖有以下几个方面:

(1)glTF文件的转换工具目前只支持单一文件的转换,尚不支持对批量文件的转换,这一部分内容有待后续跟进和补充。

(2)三维瓦片金字塔结构的构建使用的是四叉树结构,对于k-d树、八叉树结构的三维瓦片金字塔构建还有待进一步的添加和完善。

(3)三维瓦片金字塔结构的构建只能单独构建某个特定的城市模型,暂没有实现一个通用的工具。

glTF文件格式目前仍在进一步的完善中,配套的完整工具链目前还没有形成,本文基于glTF构建的转换工具尚存在不能实现批量转换的问题,而且,对三维瓦片

67

西安电子科技大学硕士学位论文 金字塔的构建还有需要完善的地方。因此,围绕上述三个问题将是本文以后工作的重要内容。

68

因篇幅问题不能全部显示,请点此查看更多更全内容

Top