前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Cesium之b3dm格式

Cesium之b3dm格式

作者头像
Jean
发布2021-05-11 10:02:34
5.9K0
发布2021-05-11 10:02:34
举报
文章被收录于专栏:Web行业观察Web行业观察

//作者:迷途的小书童

//微信公众号:g0415shenweri

b3dm格式

参考文档:

https://github.com/CesiumGS/3d-tiles/blob/master/specification/TileFormats/Batched3DModel/README.md

工具设计

计划写一个工具来查看B3dm的格式,顺便了解其原理。主要分为两部分,一部分是对属性参数的解析,一部分是对gltf的解析。

网址一:https://github.com/daniel-hilton/gltf-b3dm-convertor

实现gltf-b3dm-convertor的互相转换。

这个库无法使用,而且缺少问题

网址二:https://github.com/CesiumGS/3d-tiles-validator

这里的工具可以验证自己导出的3dtiles的格式是否正确

网址三:https://github.com/KhronosGroup/glTF-Validator

这个工具可以验证gltf的格式是否正确

网址四:https://github.com/CesiumGS/3d-tiles-validator/tree/master/samples-generator

这个工具可以自动生成3dtiles格式

网址五:https://www.cnblogs.com/onsummer/p/13252896.html

发现一个同行,有不少研究心得

由于有了这些轮子,基本上不需要再自己设计了,我们只需要加工即可。

B3dm格式验证

文件名:lib\validateB3dm.js

B3dm例子解读

这里推荐一个json格式化的工具:

https://www.bejson.com/explore/index_new/0

featureTableJson:

代码语言:javascript
复制
{
    "BATCH_LENGTH": 10,
    "RTC_CENTER": [
        1214914.5525041146,
        -4736388.031625768,
        4081548.0407588882
    ]
}
代码语言:javascript
复制
  • BATCH_LENGTH:模型的个数,即这个B3dm的文件里面有10个模型
  • RTC_CENTER:模型中心点的坐标,即下面所有模型的坐标都是以这个中心点为原点的坐标。

batchTableJson:

代码语言:javascript
复制


{
    "id": [
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9
    ],
    "Longitude": [
        -1.3197004795898053,
        -1.3197036065852055,
        -1.319708772296242,
        -1.3197052536661238,
        -1.3197012996975566,
        -1.3197180493677987,
        -1.3197058762367364,
        -1.3196853243969762,
        -1.3196881546957797,
        -1.3197161145487923
    ],
    "Latitude": [
        0.6988582109,
        0.6988621128191176,
        0.698870582386204,
        0.6988575056044288,
        0.6988603596248432,
        0.6988530761634713,
        0.6988687144359211,
        0.6988698975892317,
        0.6988569944876143,
        0.6988651780819983
    ],
    "Height": [
        11.721514919772744,
        12.778013898059726,
        9.500697679817677,
        8.181250356137753,
        10.231159372255206,
        12.68863015063107,
        6.161747192963958,
        7.122806219384074,
        12.393268510699272,
        11.431036269292235
    ]
}

这里的id、Longitude、Latitude和Height都拥有10个元素的数组,这里其实是和上面的BATCH_LENGTH为10是一一对应的。也就是说这个字符串保存的是每个模型对应的属性信息。

接下来我,我们来研究gltf的json如下:

代码语言:javascript
复制
  
代码语言:javascript
复制
  "scenes": [
        {
            "nodes": [
                0
            ]
        }
    ]
代码语言:javascript
复制

scenes场景引用了nodes数组下标为0的对象。

代码语言:javascript
复制


    "nodes": [
        {
            "matrix": [
                1,
                0,
                0,
                0,
                0,
                0,
                -1,
                0,
                0,
                1,
                0,
                0,
                0,
                0,
                0,
                1
            ],
            "mesh": 0,
            "name": "rootNode"
        }

matrix是矩阵变换,这里的变化矩阵是为了使gltf的进行Z轴向上的翻转,具体参考官网介绍

https://github.com/CesiumGS/3d-tiles/blob/master/specification/README.md#gltf-transforms

nodes节点又引用了meshs数组下标为0的节点。

代码语言:javascript
复制


    "meshes": [
        {
            "primitives": [
                {
                    "attributes": {
                        "POSITION": 0,
                        "NORMAL": 1,
                        "_BATCHID": 2
                    },
                    "indices": 3,
                    "material": 0,
                    "mode": 4
                }
            ]
        }
    ]

POSITION、NORMAL、_BATCHID、indices和material对于的值,都对于与accessors的数组的索引,mode表示网格体的类型,这里4表示是三角网。其他详细描述参考下面网址:

https://github.com/KhronosGroup/glTF/tree/master/specification/2.0/#primitivemode

代码语言:javascript
复制
  
代码语言:javascript
复制
  "accessors": [
        {
            "bufferView": 0,
            "byteOffset": 0,
            "componentType": 5126,
            "count": 240,
            "type": "VEC3",
            "min": [
                -69.262685040012,
                -63.42564369086176,
                -51.21932876482606
            ],
            "max": [
                84.98775890329853,
                61.14907375629991,
                46.49423664715141
            ]
        },
        {
            "bufferView": 1,
            "byteOffset": 0,
            "componentType": 5126,
            "count": 240,
            "type": "VEC3",
            "min": [
                -0.9686407230533828,
                -0.7415693003175017,
                -0.7655772493024053
            ],
            "max": [
                0.9686407230533828,
                0.7415693003175017,
                0.7655772493024053
            ]
        },
        {
            "bufferView": 2,
            "byteOffset": 0,
            "componentType": 5126,
            "count": 240,
            "type": "SCALAR",
            "min": [
                0
            ],
            "max": [
                9
            ]
        },
        {
            "bufferView": 3,
            "byteOffset": 0,
            "componentType": 5123,
            "count": 360,
            "type": "SCALAR",
            "min": [
                0
            ],
            "max": [
                239
            ]
        }
    ]
代码语言:javascript
复制

accessors定义了4个bufferview。刚好和上面的索引可以对应上。我们研究第一个就可以了

代码语言:javascript
复制
     
代码语言:javascript
复制
   {
            "bufferView": 0,
            "byteOffset": 0,
            "componentType": 5126,
            "count": 240,
            "type": "VEC3",
            "min": [
                -69.262685040012,
                -63.42564369086176,
                -51.21932876482606
            ],
            "max": [
                84.98775890329853,
                61.14907375629991,
                46.49423664715141
            ]
        }
代码语言:javascript
复制
  • bufferView:引用了bufferviews数组的索引为0
  • byteOffset:bufferviews数据偏移0字节
  • componentType:5126 代表数值类型为float
  • count:代表由240个vec3数据
  • type:数据类型为三维向量 VEC3
  • min:max:表示240个vec3的最小和最大值
代码语言:javascript
复制
 "bufferViews": [
        {
            "buffer": 0,
            "byteLength": 2880,
            "byteOffset": 0,
            "target": 34962,
            "byteStride": 12
        },
        {
            "buffer": 0,
            "byteLength": 2880,
            "byteOffset": 2880,
            "target": 34962,
            "byteStride": 12
        },
        {
            "buffer": 0,
            "byteLength": 960,
            "byteOffset": 5760,
            "target": 34962,
            "byteStride": 4
        },
        {
            "buffer": 0,
            "byteLength": 720,
            "byteOffset": 6720,
            "target": 34963
        }
    ]
代码语言:javascript
复制

bufferviews我们也研究第一个数据,如下:

具体可以参考下面网址:

https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_005_BuffersBufferViewsAccessors.md

代码语言:javascript
复制
    
代码语言:javascript
复制
    {
            "buffer": 0,
            "byteLength": 2880,
            "byteOffset": 0,
            "target": 34962,
            "byteStride": 12
        }

buffer:引用buffer数组索引的为0

byteLength:字节的长度

byteOffset:buffer数据偏移0个字节开始

target:34962, 表示 ARRAY_BUFFER 表示这个数据是顶点属性,另外还可以表示顶点索引 通34963

byteStride:表示每个元素实际上占用12个字节,可以通过下图有个直观的了解byteStride的作用。

接下来就是buffer了

代码语言:javascript
复制
   
代码语言:javascript
复制
 "buffers": [
        {
            "name": "buffer",
            "byteLength": 7440
        }
    ]
代码语言:javascript
复制

这里buffer为7440大小保存了上面所有引用的数据。

完整的json格式如下:

代码语言:javascript
复制
{
    "accessors": [
        {
            "bufferView": 0,
            "byteOffset": 0,
            "componentType": 5126,
            "count": 240,
            "type": "VEC3",
            "min": [
                -69.262685040012,
                -63.42564369086176,
                -51.21932876482606
            ],
            "max": [
                84.98775890329853,
                61.14907375629991,
                46.49423664715141
            ]
        },
        {
            "bufferView": 1,
            "byteOffset": 0,
            "componentType": 5126,
            "count": 240,
            "type": "VEC3",
            "min": [
                -0.9686407230533828,
                -0.7415693003175017,
                -0.7655772493024053
            ],
            "max": [
                0.9686407230533828,
                0.7415693003175017,
                0.7655772493024053
            ]
        },
        {
            "bufferView": 2,
            "byteOffset": 0,
            "componentType": 5126,
            "count": 240,
            "type": "SCALAR",
            "min": [
                0
            ],
            "max": [
                9
            ]
        },
        {
            "bufferView": 3,
            "byteOffset": 0,
            "componentType": 5123,
            "count": 360,
            "type": "SCALAR",
            "min": [
                0
            ],
            "max": [
                239
            ]
        }
    ],
    "asset": {
        "generator": "3d-tiles-samples-generator",
        "version": "2.0"
    },
    "buffers": [
        {
            "name": "buffer",
            "byteLength": 7440
        }
    ],
    "bufferViews": [
        {
            "buffer": 0,
            "byteLength": 2880,
            "byteOffset": 0,
            "target": 34962,
            "byteStride": 12
        },
        {
            "buffer": 0,
            "byteLength": 2880,
            "byteOffset": 2880,
            "target": 34962,
            "byteStride": 12
        },
        {
            "buffer": 0,
            "byteLength": 960,
            "byteOffset": 5760,
            "target": 34962,
            "byteStride": 4
        },
        {
            "buffer": 0,
            "byteLength": 720,
            "byteOffset": 6720,
            "target": 34963
        }
    ],
    "materials": [
        {
            "pbrMetallicRoughness": {
                "baseColorFactor": [
                    1,
                    1,
                    1,
                    1
                ],
                "roughnessFactor": 1,
                "metallicFactor": 0
            },
            "alphaMode": "OPAQUE",
            "doubleSided": false,
            "emissiveFactor": [
                0,
                0,
                0
            ]
        }
    ],
    "meshes": [
        {
            "primitives": [
                {
                    "attributes": {
                        "POSITION": 0,
                        "NORMAL": 1,
                        "_BATCHID": 2
                    },
                    "indices": 3,
                    "material": 0,
                    "mode": 4
                }
            ]
        }
    ],
    "nodes": [
        {
            "matrix": [
                1,
                0,
                0,
                0,
                0,
                0,
                -1,
                0,
                0,
                1,
                0,
                0,
                0,
                0,
                0,
                1
            ],
            "mesh": 0,
            "name": "rootNode"
        }
    ],
    "scene": 0,
    "scenes": [
        {
            "nodes": [
                0
            ]
        }
    ]
}
代码语言:javascript
复制

buffer数据获取

这里决定取出buffer内部的一些数据对我们上述的理解进行验证

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WebHub 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • b3dm格式
  • 工具设计
  • B3dm格式验证
  • B3dm例子解读
  • buffer数据获取
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档