Cesium之b3dm格式

190 篇文章 38 订阅

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:

{
    "BATCH_LENGTH": 10,
    "RTC_CENTER": [
        1214914.5525041146,
        -4736388.031625768,
        4081548.0407588882
    ]
}

复制

 

复制

  • BATCH_LENGTH:模型的个数,即这个B3dm的文件里面有10个模型
  • RTC_CENTER:模型中心点的坐标,即下面所有模型的坐标都是以这个中心点为原点的坐标。

batchTableJson:



{
    "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如下:

  

复制

  "scenes": [
        {
            "nodes": [
                0
            ]
        }
    ]

复制

 

复制

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



    "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的节点。



    "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

  

复制

  "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
            ]
        }
    ]

复制

 

复制

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

     

复制

   {
            "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:引用了bufferviews数组的索引为0
  • byteOffset:bufferviews数据偏移0字节
  • componentType:5126 代表数值类型为float
  • count:代表由240个vec3数据
  • type:数据类型为三维向量 VEC3
  • min:max:表示240个vec3的最小和最大值
 "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
        }
    ]

复制

 

复制

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

具体可以参考下面网址:

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

    

复制

    {
            "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了

   

复制

 "buffers": [
        {
            "name": "buffer",
            "byteLength": 7440
        }
    ]

复制

 

复制

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

完整的json格式如下:

{
    "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
            ]
        }
    ]
}

复制

 

复制

buffer数据获取

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

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cesium B3DM文件是一种用于三维地球可视化的开放格式文件,用于存储建筑物、地形、植被等元素的3D模型和纹理。然而,由于其中包含了大量的几何数据和纹理信息,所以Cesium B3DM文件往往会比较大。 造成Cesium B3DM文件过大的原因有以下几点: 1. 几何数据:Cesium B3DM文件中存储了建筑物、地形等物体的几何信息,包括顶点坐标、法线、纹理坐标等。这些数据量庞大,尤其是对于复杂的建筑物或大范围的地形,会导致文件大小增加。 2. 纹理信息:Cesium B3DM文件中还包含了贴图信息,用于给模型上色或添加纹理。纹理图像的像素数目和颜色深度决定了文件的大小。有时候高分辨率的纹理图像会导致文件变得非常庞大。 3. 数据冗余:在一些情况下,Cesium B3DM文件可能包含了冗余的数据,比如重复的顶点坐标或纹理坐标。这些冗余数据会占据额外的存储空间,使文件变大。 为了解决Cesium B3DM文件过大的问题,可以采取一些优化措施: 1. 减少细节:对于一些不太重要的细节,可以进行简化,例如减少建筑物的边角或细小物体的数量。这样可以有效地减少几何数据量,从而减小文件大小。 2. 压缩数据:可以采用专业的数据压缩算法对文件进行压缩,减少文件大小。常用的压缩算法包括LZ77、DEFLATE等。 3. 使用纹理压缩:可以采用纹理压缩算法,例如基于GPU的纹理压缩技术,将纹理图像进行压缩,进一步减小文件体积。 对于Cesium B3DM文件太大的问题,我们可以通过上述措施来进行优化。这样不仅可以减小文件大小,提高加载速度,还可以减少网络传输和存储成本。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值