Cesium 3dtiles详解(2)-b3dm

一、简介

b3dm,即Batch 3d model的缩写,Batch,即批量,指的是多个几何数据,b3dm就是多个数据模型组合在一起存储的一种文件而产生的一种文件格式。

优点

1.多个模型数据可组合到一个缓冲区中,提高渲染性能。
2.单个缓冲数据可以直接复制到GPU内存中,减少复制操作,且可以以最小化绘制调用次数进行结构化

特点

多个模型组合到一个缓冲区时,它仍然支持每个模型的样式变更和对每个模型的操作。比如说可以用不同的颜色来渲染模型,或者通过鼠标单击确定模型是否被选中。

这是如何实现的呢?

在3dtiles中通过扩展额外的顶点属性来实现,几何数据扩展了batchId属性,将每个顶点的batchId存储为整数,具有相同ID的顶点属于同一模型。batchId做为批量表中查找样式信息和元数据的索引。

二、数据组成

b3dm文件组成
一个b3dm文件中主要包含以上数据,文件头和正文。

文件头

文件头一般时前28个字节,包含了该瓦片的一些基本信息数据,内容如下

属性字段字节数含义
magicchar[4]4瓦片类型,通常为“b3dm”
versionuint324瓦片版本号,通常“1”
byteLenghtuint324瓦片文件长度
featureTableJsonByteLengthuint324特征表的JSON文件(二进制)长度
featureTableBinaryByteLengthuint324特征表的二进制数据长度
batchTableJsonByteLengthuint324批量表的JSON文件(二进制)长度
batchTableBinaryByteLenghtuint324批量表的二进制数据长度

正文

正文由特征表、批量表、内嵌glb的二进制数据组成

1.特征表

记录整个瓦片渲染相关数据,非渲染所需数据
包含两个部分

属性含义
featureTableJSON特征表的JSON对象,主要包含一些全局属性
featureTableBinary特征表的二进制本体数据

特征表的JSON对象主要包含的属性有

属性字段字节数含义
BATCH_LENGTHuint324瓦片中存在的模型个数,必须要有
RTC_CENTERfloat32[3]未定瓦片的相对坐标中心,非需要
2.批量表

批量表记录的是每个模型的属性数据以及扩展数据,特征表和批量表的唯一联系就是BATCH_LENGTH,特征表有多少模型,批量表中每个属性就有多少个值。
批量表包含两个部分

属性含义
batchTableJSON批量表的JSON对象,主要包含每个模型的属性数据,每一项属性都由长度为BATCH_LENGTH的数组组成
batchTableBinarypl表的二进制本体数据

批量表的JSON头部数据

{
	“height”:[10,0,20,15],
	“width”:[1,2,3,4],
	...
}

以上是将属性数据直接写在JSON头部内,也可以将属性值写入batchTableBinary中,只在JSON头部定义数据格式和位置,适用于属性数据量比较大的情况。

“height”:{
	“byteOffset”:0.//二进制本体数据中从哪个字节开始存储
	“componentType”:”FLOAT”, //数据值的类型
	“type”:”SCALAR”//数据的元素类型(即标量)
}

同样的一个数字,二进制的JSON文本大多数时候体积要比batchTableBinary大。因为JSON文本中包括括号、逗号、冒号等JSON文本必须的符号。对于属性数据相当大的情况下,应该要适用JSON引用batchTableBinary的方式组织数据,JSON充当元数据角色。但属性类型是JSON中的object、string、bool类型时,则必须存储在JSON中,因为batchTableBinary只能存标量、234维向量四种类型的数据

3.内嵌的glb

在每一个Primitive的attributes中添加额外的访问器:_BATCHID

“primitives”:[
	{
		“attributes”:{
			“POSITION”:0,
			“_BATCHID”:3,//这里就可以和属性数据(批量表)一一对应了
			“TEXTURE_0”:2,
			…
		},
	“indices”:1,
	…
	}
]

一个BATCH用自己的BATCHID与几何数据一一对应,属性数据也与这个BATCHID一一对应,那么这个BATCH的几何数据(glTF)也就能和属性数据(批量表)一一对应了。

4.字节对齐
JSON二进制文本对齐

featureTableJSON、batchTableJSON的二进制文本,最后一个字节相对于整个b3dm文件来说,偏移量必须是8的倍数。如果不对齐,必须用二进制空格(即0x20)填够(在featrueTableJSON、batchTableJSON的后面补空格)。
为啥不在起始位置对齐呢?因为b3dm文件的开头是28字节的文件头,如果以起始位置对齐,那还需要在文件头和特征表的JSO数据之间塞入4个字节填满,尾端可能还需要再填入多个字节以满足批量表的JSON数据偏移量的问题。故选尾部字节对齐比较简单,末尾对齐,即 (28 + ftJSON长)能整除8,(28 + ftTable长 + btJSON长)能整除8。

二进制数据体的起始、末尾对齐

二进制数据体,无论是特征表还是批量表,首个字节相对于b3dm文件的字节偏移量,必须是8的倍数,结束字节的字节偏移量,也必须是8的倍数。如果不满足,可以填充任意数据字节满足此要求。
特别的是,tableBinary中,每一个属性值的第一个数值的第一个字节的偏移量,相对于整个b3dm文件,必须是其componentType的倍数,如果不满足,则必须用空白字节填满。
例如,上述height属性所在的batchTableBinary中,理所当然位于batchTableJson之后,而batchTableJson又是8byte对齐的,假设batchTableBinary起始字节是800,那么height的第一个值起始字节就是800,由于height属性的componentType是FLOAT,即4字节,800 ÷ 4 能整除,所以没有问题。
但是,假如换一个属性,其componentType是BYTE,即 1字节,那么假设第二个属性的 componentType是DOUBLE,即8字节,就会出现第二个属性的第一个值起始偏移量是810,810 ÷ 8 并不能整除,必须补齐6个空白字节,以满足第二个属性第一个值的起始偏移量是 810+6 = 816字节。

5.编码端序

特征表、批量表的二进制数据,无论是tableJson还是tableBinary,均使用小端序编码(LittleEndian)。
对于一个整数值,如果使用小端字节序,整数的高位存储在内存地址高的位置,整数的低位存储在内存地址低的位置上

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值