? ? ? ?五一之前第二次在工作中遇到了需要自主生成3dtiles以在cesium中顯示3d模型的需求,這一次在實(shí)現(xiàn)這個(gè)需求時(shí)發(fā)現(xiàn)之前對(duì)3dtiles格式的理解有很多不到之處,趁著端午節(jié)假期把這些理解記錄下來(lái)以備之后再次需要時(shí)查看。
? ? ? ?這篇文章并沒(méi)有完全說(shuō)明3dtiles文件的所有組織方式,只解析類(lèi)似gltf格式的b3dm文件格式,其中多有不到之處,如不能解決您的問(wèn)題,請(qǐng)多包涵。
? ? ? ?我在學(xué)習(xí)的過(guò)程中主要參考了這幾個(gè)地方:
1.b3dm組織方式:https://zhuanlan.zhihu.com/p/158994083
2.gltf組織方式:https://zhuanlan.zhihu.com/p/65735191
3.3dtiles github文檔:https://link.zhihu.com/?target=https%3A//github.com/CesiumGS/3d-tiles/tree/master/specification/TileFormats/Batched3DModel%23binary-gltf
目錄
一、一個(gè)3Dtiles文件夾內(nèi)都包括什么
二、.json文件內(nèi)容
三、b3dm文件的組織方式
3.1 b3dm組織方式
3.2 注意?。。。?/p>
四、結(jié)語(yǔ)
一、一個(gè)3Dtiles文件夾內(nèi)都包括什么
? ? ? ? 一個(gè)3dtiles文件包括一個(gè)組織文件(.json)和數(shù)個(gè)瓦片文件(.i3dm/.b3dm/.pnts/.cmpt)
? ? ? ?組織文件是3dtiles的入口,其中記錄了每個(gè)瓦片的范圍、各條屬性的極值、每個(gè)瓦片的顯示范圍等整體信息;瓦片文件則記錄具體要顯示的模型信息。
二、.json文件內(nèi)容
? ? ? ? .json文件就是一個(gè)正常的JSON文件,只是其中的內(nèi)容需要按照制定好的規(guī)則填寫(xiě)
詳細(xì)的.json文件規(guī)則可以參考這里:https://github.com/CesiumGS/3d-tiles/tree/main/specification
? ? ? ? 這里只通過(guò)一個(gè)可用的例子展示幾個(gè)關(guān)鍵的內(nèi)容。
{
/* asset屬性中記錄版權(quán)信息、版本信息、垂直軸等信息*/
"asset": {
"gltfUpAxis": "Z",
"version": "1.0"
},
/* geometricError是幾何誤差,這個(gè)我不太理解,和顯示細(xì)節(jié)有關(guān),要求是是非負(fù)且由父到子遞減*/
"geometricError": [
1000000
],
/* properties是模型各個(gè)屬性的最大最小值,規(guī)定必須只能記錄最大值和最小值,這樣支持3dtiles的引擎才能正確獲取這個(gè)屬性*/
"properties": {
"I": {
"minimum": 3.0,
"maximum": 179.0
},
"J": {
"minimum": 5.0,
"maximum": 184.0
}
},
/* root是3dtile樹(shù)狀結(jié)構(gòu)的根節(jié)點(diǎn)*/
"root": {
/* 轉(zhuǎn)換矩陣,這樣寫(xiě)相當(dāng)于沒(méi)轉(zhuǎn)換,這個(gè)沒(méi)接觸過(guò)的話(huà)可以搜索坐標(biāo)變換(還有很多領(lǐng)域有這個(gè),其實(shí)都是一個(gè)事)*/
"transform": [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
],
/* 同上*/
"geometricError": 10000,
/* 當(dāng)子節(jié)點(diǎn)加載時(shí)和父節(jié)點(diǎn)的關(guān)系,ADD是疊加,REPLACE是替換*/
"refine": "ADD",
/* 子節(jié)點(diǎn),可以鑲套*/
"children": [
{
"boundingVolume": {
"box": [
-2294502.3282544096,
3706199.5334441354,
4644166.925639546,
263.23593662912026,
0,
0,
0,
176.47964480728842,
0,
0,
0,
166.596532296855
]
},
"geometricError": 1000,
/* 該節(jié)點(diǎn)的瓦片文件*/
"content": {
"uri": "./1.b3dm"
}
}
],
/* 根節(jié)點(diǎn)的要素范圍,有三種設(shè)置方式,這里的box是記錄中心點(diǎn)和三個(gè)軸方向的半距*/
"boundingVolume": {
"box": [
-2302317.288889875,
3706793.65386175,
4639561.535310894,
8965.85696362378,
0,
0,
0,
5891.165495929075,
0,
0,
0,
6173.917311145924
]
}
}
}
三、b3dm文件的組織方式
? ? ? ? 最上面關(guān)于b3dm的文章已經(jīng)寫(xiě)的非常好了,這里我按照自己的方式嘗試講的更具象一些,并單獨(dú)說(shuō)明一些稍微難理解的地方。
? ? ? ? b3dm實(shí)質(zhì)上是由數(shù)個(gè)二進(jìn)制信息體拼接而成,下面用字符串展示出具體內(nèi)容,實(shí)際使用時(shí)要存儲(chǔ)為對(duì)應(yīng)數(shù)據(jù)格式的二進(jìn)制體。
3.1 b3dm內(nèi)容
? ? ? ? 先是文件頭,固定長(zhǎng)度為28byte
? ? ? ?然后是要素表,再是要素表數(shù)據(jù)體,瓦片類(lèi)型為b3dm的3dtiles不需要要素表來(lái)儲(chǔ)存其屬性名信息,故要素表可以固定為以下兩種,要素表數(shù)據(jù)體為空。
"{"BATCH_LENGTH":XXXX}"
或
"{"BATCH_LENGTH":XXXX,"RTC_CENTER":[XXX,XXX,XXX]}"
BATCH_LENGTH為這個(gè)b3dm中單體化要素的個(gè)數(shù)
RTC_CENTER為這個(gè)b3dm的中心點(diǎn),如果設(shè)置了這個(gè)屬性,則后面glb里的坐標(biāo)都會(huì)加上這個(gè)中心
? ? ? ?值得一提的是由于3dtiles里的數(shù)字最多只能識(shí)別16位有效數(shù)字,因此需要盡可能多的保留小數(shù)點(diǎn)后的信息時(shí),可以把中心點(diǎn)整數(shù)部分放在這里,這樣后面glb里每個(gè)坐標(biāo)小數(shù)點(diǎn)前的位數(shù)能減少一些,小數(shù)點(diǎn)后能保存的信息也就多一些。
? ? ? ?然后是批量表,再是批量表數(shù)據(jù)體,這兩個(gè)部分要對(duì)應(yīng)著填寫(xiě)
批量表
"{"filed1":{"byteOffset":0,"componetType":FLOAT,"type":SCALAR},"filed2":{"byteOffset":12,"componetType":FLOAT,"type":SCALAR}}"
其中field1和field2是屬性名,也就是身高、年齡之類(lèi)的,
byteOffset是這個(gè)屬性是在后面數(shù)據(jù)體的什么位置開(kāi)始
componetType是這個(gè)屬性的類(lèi)型,有固定的名稱(chēng)得參考官方的github文檔,鏈接在上面
type可以簡(jiǎn)單理解為就三類(lèi):SCALAR(一個(gè)數(shù))VEC2(兩個(gè)數(shù))VEC3(三個(gè)數(shù)),如果這三類(lèi)滿(mǎn)足不了你的需求,還有MAT2、MAT3等,這個(gè)和gltf的type是一致的,可以查閱gltf格式文檔
批量表數(shù)據(jù)體
"111222"
每個(gè)屬性的具體數(shù)據(jù),個(gè)數(shù)需要和前面要素表里BATCH_LENGTH保持一致,例如前面要素表是"{"BATCH_LENGTH":3}",那1,1,1就是上面批量表中filed1的值,至于這三個(gè)值是如何和后面glb里要素對(duì)應(yīng)上的,要講到glb時(shí)才能明了。
這時(shí)上面byteOffset的意思也能解釋了,可以看到filed1的類(lèi)型是FLOAT,F(xiàn)LOAT是4個(gè)字節(jié)長(zhǎng)度,BATCH_LENGTH又是3,則第四個(gè)數(shù)開(kāi)始是filed2嗎,需要從頭跳過(guò)12個(gè)字節(jié)開(kāi)始讀,因此field2的byteOffset是12
? ? ? ? 最后是glb,這部分和glb文件的內(nèi)容幾乎完全一致,只是多了batchID這個(gè)屬性,原glb文件內(nèi)容很多,這里就不展開(kāi)了,有需要的話(huà)還請(qǐng)參閱glb格式文檔,或者之后單獨(dú)寫(xiě)一個(gè)gltf和glb的說(shuō)明,這里就只說(shuō)明batchID要怎么添加以及有什么用處
{
'asset': {
'generator': '給我一塊奧利奧吧',
'version': '2.0'
},
'scene': 0,
'scenes': [
{
'nodes': [
0
]
}
],
'nodes': [
{
'matrix': [
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
],
'mesh': 0
}
],
'meshes': [
{
'primitives': [
{
'attributes': {
'POSITION': 0,
'NORMAL': 1,
'_BATCHID': 2
},
'material': 0,
'mode': 4
}
]
}
],
'materials': [
{
'pbrMetallicRoughness': {
'metallicFactor': 0
},
'name': 'Material'
}
],
'accessors': [
{
'bufferView': 0,
'byteOffset': 0,
'componentType': 5126,
'count': 312,
'min': [
-2294765.5641910387,
3706023.0537993284,
4644000.329107248
],
'max': [
-2294239.0923177805,
3706376.013088943,
4644333.522171842
],
'type': 'VEC3'
},
{
'bufferView': 1,
'byteOffset': 0,
'componentType': 5126,
'count': 312,
'max': [
1,
1,
1
],
'min': [
-1,
-1,
-1
],
'type': 'VEC3'
},
{
'bufferView': 2,
'byteOffset': 0,
'componentType': 5126,
'count': 312,
'max': [
1
],
'min': [
0
],
'type': 'SCALAR'
}
],
'bufferViews': [
{
'buffer': 0,
'byteLength': 3744,
'byteOffset': 0,
'target': 34962
},
{
'buffer': 0,
'byteLength': 3744,
'byteOffset': 3744,
'target': 34962
},
{
'buffer': 0,
'byteLength': 1248,
'byteOffset': 7488,
'target': 34962
}
],
'buffers': [
{
'byteLength': 8736
}
]
}
下面這段解釋需要了解gltf格式才能看懂:
? ? ? ?也就是說(shuō)在普通的glb基礎(chǔ)上新增一個(gè)bufferview,這個(gè)bufferview在meshes中叫_BATCHID,這個(gè)BATCHID從0開(kāi)始,每有一個(gè)三角面就需要寫(xiě)入一個(gè)BATCHID,這個(gè)BATCHID意味著在取值時(shí)從批量表數(shù)據(jù)體里取第幾個(gè)數(shù)據(jù)。
至此,一個(gè)完整的b3dm文件就構(gòu)建好了
3.2 注意?。。?!
“
二進(jìn)制數(shù)據(jù)體,無(wú)論是要素表、批量表,首個(gè)字節(jié)相對(duì)于b3dm文件的字節(jié)偏移量,必須是8的倍數(shù),結(jié)束字節(jié)的字節(jié)偏移量,也必須是8的倍數(shù)。
如果不滿(mǎn)足,可以填充空白字節(jié)滿(mǎn)足此要求。
特別的,二進(jìn)制數(shù)據(jù)體中,每一個(gè)屬性值的第一個(gè)數(shù)值的第一個(gè)字節(jié)的偏移量,相對(duì)于整個(gè)b3dm文件,必須是其?componentType
?的倍數(shù),如果不滿(mǎn)足,則必須用空白字節(jié)填滿(mǎn)。
”
? ? ? ?也就是說(shuō),在生成要素表、要素表數(shù)據(jù)體、批量表、批量表數(shù)據(jù)體時(shí),如果他們的二進(jìn)制長(zhǎng)度不是8的倍數(shù),要在后面補(bǔ)充空格直到他們的長(zhǎng)度為8的倍數(shù)。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-795994.html
四、結(jié)語(yǔ)
? ? ? ? 3dtiles能實(shí)現(xiàn)的內(nèi)容還有很多很多,我自己也只是剛剛了解了這一點(diǎn),如果這篇文章的內(nèi)容不能幫助到您,再次請(qǐng)您見(jiàn)諒。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-795994.html
到了這里,關(guān)于基于b3dm的3Dtiles文件組織方式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!