Skip to content
  • 首页
  • 留言
  • 关于

Share the joys of programming and technology

3dTiles数据解析

3dTiles数据解析

2024年9月7日 liyanliang Comments 2 comments
阅读次数: 186

Contents

  • 1 1.解析json文件
  • 2 2.解析b3dm模型
  • 3 3.关于glTF格式详解
  • 4 参考资料
    • 4.1 1.解析json文件
    • 4.2 2.解析3dtile-b3dm格式
    • 4.3 3.glTF
  • 5 相关文章

1.解析json文件

3dtiles的数据结构:
Tileset

2.解析b3dm模型

(1)b3dm模型文件时二进制文件,其中包含glTF文件:

img

img

当使用tiny_gltf库解析glTF时,需要减去(28byte + featuretable的byte + batchTable的byte ):

 bool TinyGLTF::ExtractGltfFromMemory(Model *model,
                                     std::string *err,
                                     std::string *warn,
                                     const unsigned char *bytes,
                                     unsigned int size,
                                     const std::string &base_dir,
                                     unsigned int check_sections) {
     if (size < 28) {
        if (err) {
          (*err) = "Too short data size for b3dm Binary.";
        }
        return false;
      }

      if (bytes[0] == 'b' && bytes[1] == '3' && bytes[2] == 'd' &&
          bytes[3] == 'm') {
        // ok
      } else {
        if (err) {
          (*err) = "Invalid magic.";
        }
        return false;
      }

      unsigned int version;                     // 4 bytes
      unsigned int byteLength;                  // 4 bytes
      unsigned int featureTableJSONByteLength;  // 4 bytes
      unsigned int featureTableBinaryByteLength;// 4 bytes;
      unsigned int batchTableJSONByteLength;    // 4 bytes
      unsigned int batchTableBinaryByteLength;  // 4 bytes;

      // @todo { Endian swap for big endian machine. }
      memcpy(&version, bytes + 4, 4);
      swap4(&version);
      memcpy(&byteLength, bytes + 8, 4);
      swap4(&byteLength);
      memcpy(&featureTableJSONByteLength, bytes + 12, 4);
      swap4(&featureTableJSONByteLength);
      memcpy(&featureTableBinaryByteLength, bytes + 16, 4);
      swap4(&featureTableBinaryByteLength);
      memcpy(&batchTableJSONByteLength, bytes + 20, 4);
      swap4(&batchTableJSONByteLength);
      memcpy(&batchTableBinaryByteLength, bytes + 24, 4);
      swap4(&batchTableBinaryByteLength);

      if ((byteLength != size) || (byteLength < 1) ) {
        if (err) {
          (*err) = "Invalid b3dm binary.";
        }
        return false;
      }

     const int byteOffset = 28 + featureTableJSONByteLength + batchTableJSONByteLength;

   // 解析glTF二进制
     bool ret = LoadBinaryFromMemory(
           model, err, warn, &bytes[byteOffset],
           byteLength - byteOffset, base_dir, check_sections);

      if (!ret) {
        return ret;
      }

      return true;
 }

(2)使用tiny_gltf库解析3dtiles数据
需要3个文件stb_image.h,stb_image_write.h,json.hpp和tiny_gltf.h
使用时需要注意,在调用#include "tiny_gltf.h"文件中的函数时,需要添加三个宏,如:

 // Define these only in *one* .cc file.
 #define TINYGLTF_IMPLEMENTATION
 #define STB_IMAGE_IMPLEMENTATION
 #define STB_IMAGE_WRITE_IMPLEMENTATION
 // #define TINYGLTF_NOEXCEPTION // optional. disable exception handling.
 #include "tiny_gltf.h"

 using namespace tinygltf;

 Model model;
 TinyGLTF loader;
 std::string err;
 std::string warn;

 bool ret = loader.LoadASCIIFromFile(&model, &err, &warn, argv[1]);
 //bool ret = loader.LoadBinaryFromFile(&model, &err, &warn, argv[1]); // for binary glTF(.glb)

 if (!warn.empty()) {
   printf("Warn: %s\n", warn.c_str());
 }

 if (!err.empty()) {
   printf("Err: %s\n", err.c_str());
 }

 if (!ret) {
   printf("Failed to parse glTF\n");
   return -1;
 }

3.关于glTF格式详解

 {
   "scenes" : [ // 只包含了一个场景
     {
       "nodes" : [ 0, 1]
     }
   ],
   "nodes" : [ // 将mesh对象附着到两个不同的node对象,将其渲染了两次
     {
       "mesh" : 0
     },
     {
       "mesh" : 0,
       "translation" : [ 1.0, 0.0, 0.0 ] // 使用translation属性来将mesh对象的渲染位置移动到其它地方
       "rotation": [ 0.259, 0.0, 0.0, 0.966 ], // 四元数
       "scale": [ 2.0, 1.0, 0.5 ] // x,y和z轴的缩放系数
       // 或者只给出一个matrix进行变换
       "matrix": [ // 描述了一个缩放(2,1,0.5),绕x轴旋转30度,平移(10,20,30)的matrix属性
         2.0,    0.0,    0.0,    0.0,
         0.0,    0.866,  0.5,    0.0,
         0.0,   -0.25,   0.433,  0.0,
         10.0,   20.0,   30.0,    1.0
     ]
     } 
   ],

   "meshes" : [
     {
       "primitives" : [ {
         "attributes" : {
           "POSITION" : 1, // 引用了索引为1的accessor对象
           "NORMAL" : 2 // "NORMAL"属性引用了索引为2的accessor对象
         },
         "indices" : 0
       } ]
     }
   ],

   "buffers" : [ // 表示了一个没有任何层次结构和意义的二进制数据块
     {
       "uri" : "data:application/octet-stream;base64,AAA为了排版而删除,可以使用英文原文中的代码=",
       "byteLength" : 80 // 使用了大小为80字节的经过编码的数据URI作为缓冲的数据
     }
   ],
   "bufferViews" : [ // 一个bufferView对象代表了一个buffer对象的部分数据
     {
       "buffer" : 0,
       "byteOffset" : 0,
       "byteLength" : 6, // 引用了索引为0的buffer对象的前6个字节的数据
       "target" : 34963 // 表示数据使用方式的常量,ELEMENT_ARRAY_BUFFER
     },
     {
       "buffer" : 0,
       "byteOffset" : 8,
       "byteLength" : 72, // 从偏移值8开始的36个字节的buffer对象的数据
       "target" : 34962 // ARRAY_BUFFER
     }
   ],
   "accessors" : [
     {  // 表示顶点索引数据是unsigned short类型的标量
       "bufferView" : 0, // 引用了索引为0的bufferView,这一bufferView对象描述了buffer数据中的顶点索引数据
       "byteOffset" : 0,  // 指定了accessor所访问数据的开始位置
       "componentType" : 5123, // 定义了数据分量的基础类型,5123代表UNSIGNED_SHORT。同short占用2个字节
       "count" : 3, // count属性指定了数据元素的数量,对应三角形的3个顶点的索引值
       "type" : "SCALAR", 
       "max" : [ 2 ],
       "min" : [ 0 ]
     },
     {  // 这一accessor对象描述了分量类型为float的3D向量数据
       "bufferView" : 1,
       "byteOffset" : 0,  // 指定了accessor所访问数据的开始位置
       "componentType" : 5126, // 5126代表FLOAT,一个float类型值占4个字节
       "count" : 3, // count属性指定了数据元素的数量
       "type" : "VEC3",
       "max" : [ 1.0, 1.0, 0.0 ], // min和max属性定义了3D对象的包围盒
       "min" : [ 0.0, 0.0, 0.0 ]
     },
     {
       "bufferView" : 1,
       "byteOffset" : 36,
       "componentType" : 5126, // 5126代表FLOAT
       "count" : 3, // count属性指定了数据元素的数量
       "type" : "VEC3",
       "max" : [ 0.0, 0.0, 1.0 ], // min和max属性定义了3D对象的包围盒
       "min" : [ 0.0, 0.0, 1.0 ]
     }
   ],

   "asset" : {
     "version" : "2.0"
   }
 }

参考资料

1.解析json文件

Reference:

RapidJSON的简单使用示例:

RapidJSON简介及使用

2.解析3dtile-b3dm格式

Reference:

(1)对相关资料做了总结和推荐:

Cesium之b3dm格式_全栈空间-程序员秘密

image-20220414105546750

(2)对b3dm二进制结构做了详细的解析:

3dTiles 数据规范详解[4.1] b3dm瓦片二进制数据文件结构 _

image-20220414105705179

(3)官网对Batched3DModel的介绍

3d-tiles/specification/TileFormats/Batched3DModel/

layout.png

(4)3dtiles官方规范

3d-tiles/specification

(5)

3dTile 数据文件格式说明

img

img

(6)3dtiles规范中文版pdf

链接: https://pan.baidu.com/s/1hhbvD_2DXrPCTOs7slsNHA 提取码: ejm7

3.glTF

(1)glTF官方github:

KhronosGroup/glTF

(2)glTF规范:

Specification.adoc

(3)对glTF格式的详细介绍,教程(glTF官方文档翻译)

glTF格式详解(glTF格式基本结构)

(4)博主的github写了一个解析glTF的工具:

模型导入之优雅姿势——glTF

songchaow/toy-renderer

(5)解析b3dm模型的库tiny_gltf(项目中用这个库解析)

https://github.com/fanvanzh/3dtiles

(6)tiny_gltf原始项目出处:

chainblocks/tinygltf

(7)glTF模型文件讲解(B站)

【日常 | 学习Vlog | 程序媛乐乐】数字孪生基础 | 三维模型 | What is glTF?

image-20220415101428317

相关文章

  • ObjectARX开发视频教程(C++)-创建模态对话框绘制直线ObjectARX开发视频教程(C++)-创建模态对话框绘制直线
  • WordPress分页插件 – WP-PageNavi的使用(替换现有脚本)WordPress分页插件 – WP-PageNavi的使用(替换现有脚本)
  • 去除重叠的闭合区域去除重叠的闭合区域
  • 从DLL中动态加载一个函数:LoadLibrary和GetProcAddress的使用从DLL中动态加载一个函数:LoadLibrary和GetProcAddress的使用
  • 通过数学方法来计算short类型的变量w的低八位x和高八位通过数学方法来计算short类型的变量w的低八位x和高八位
  • 如何调试Revit二次开发代码-教学视频(解决无法调试问题)如何调试Revit二次开发代码-教学视频(解决无法调试问题)

GIS
3dtiles, glTF

Post navigation

PREVIOUS
Games101和Games202脑图汇总
NEXT
通过数学方法来计算short类型的变量w的低八位x和高八位

2 thoughts on “3dTiles数据解析”

  1. SaimaMub说道:
    2024年10月12日 03:17

    https://vavadalf.com/ – как войти в казино Вавада и начать играть в азартные игры онлайн: простые инструкции для быстрого доступа к любимым слотам и бонусам.

    回复
  2. ZahraBiz说道:
    2024年10月12日 14:49

    Хотите узнать все о возможностях и преимуществах игры в онлайн казино vavada? Подробная информация об игровых слотах, бонусах и акциях в Vavada casino – только на нашем сайте!

    回复

发表回复 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注

近期文章

  • ANR崩溃日志查看方法
  • 通过数学方法来计算short类型的变量w的低八位x和高八位
  • 3dTiles数据解析
  • Games101和Games202脑图汇总
  • LearnOpenGL脑图汇总
  • IBL计算总结
  • C++实现一个简单的语言解释器
  • OpenGL-法线贴图(Normal Mapping)
  • OpenGL-卡通着色(Cartoon)
  • OpenGL几何着色器实现贝塞尔曲线
  • WinDbg检查内存泄漏
  • OpenGL雾化效果实现-每像素雾化
  • OpenGL实现billboard效果(CPU)
  • 算法:寻找异常数字
  • OpenGL 几何着色器的应用
  • Midas XD-构件详图开发
  • Midas XD-选筋助手开发
  • Civil Designer开发-检测规范自动生成控制截面
  • Civil Designer开发-公路桥梁承载能力检算评定
  • Midas W-满堂支架快速建模助手开发

全站热点

  • C++编写的情人节小程序 (2,084)
  • 提取最小封闭区域 (1,699)
  • Modern OpenGL绘制圆柱体 (1,607)
  • OpenGL开发环境搭建-GLFW与GLAD配置 超详细 (1,469)
  • 截面特性计算程序-附源码 (1,292)
  • OpenGL绘制旋转立方体 (1,110)
  • 判断一个点是否在闭合区域内 (1,034)
  • WordPress分页插件 – WP-PageNavi的使用(替换现有脚本) (949)
  • OpenGL实现billboard效果(CPU) (866)
  • Midas W-满堂支架快速建模助手开发 (837)
  • 从DLL中动态加载一个函数:LoadLibrary和GetProcAddress的使用 (748)
  • Midas XD [错误] 右侧挡土墙的最下端深度必须小于地基的最下端深度 (710)
  • 两跨连续梁影响线绘制-附源码 (686)
  • 土木想往土木软件开发方向发展,应该如何准备 (680)
  • OpenGL几何着色器实现贝塞尔曲线 (664)
  • 通过Spy++抓取窗口以查询对话框id (614)
  • 使用ODA数据库出现 “ODA_ASSUME”: 找不到标识符的错误 (548)
  • #pragma message 编译时提示信息 (527)
  • OpenGL雾化效果实现-每像素雾化 (510)
  • midas XD2020的开发 (476)

分类

  • C# (3)
  • C++ (19)
  • GIS (1)
  • MFC (3)
  • ObjectARX (2)
  • OpenGL (11)
  • Revit开发 (1)
  • 学习笔记 (2)
  • 岩土 (2)
  • 算法 (1)
  • 结构设计 (7)
  • 职场生涯 (1)
  • 计算几何 (3)

归档

  • 2024 年 12 月 (1)
  • 2024 年 10 月 (1)
  • 2024 年 9 月 (1)
  • 2023 年 3 月 (2)
  • 2022 年 10 月 (1)
  • 2022 年 3 月 (1)
  • 2022 年 2 月 (1)
  • 2022 年 1 月 (5)
  • 2021 年 11 月 (7)
  • 2021 年 6 月 (3)
  • 2021 年 5 月 (2)
  • 2021 年 3 月 (2)
  • 2021 年 2 月 (8)
  • 2021 年 1 月 (18)

标签

3dtiles anr Bezier Curves BillBoard C++ CDN CivilDesigner DLL EasyX fog glTF MFC Midas W Midas XD NormalMapping ObjectARX ODA OpenGL OpenXML Open XML PBR revit WinDbg 基坑设计 影响线 截面特性 桥梁 桥梁检测 桥梁设计 算法 计算几何 设计模式

书签

  • 李燕良的CSDN
  • 崔济东的博客
  • C++爱好者博客
  • 陈学伟的博客
  • 贾苏的博客
  • 陈睦锋的博客
  • 孙勇的博客

统计

  • 0
  • 38
  • 23
  • 443
  • 188
  • 269,728
  • 78,177

实时访问地域

© 2025   liyanliang.net Copyright. All Rights Reserved.