cesium 3DTiles之pnts格式详解

Point Cloud

1 概述

点云(Point Cloud)瓦片格式用于高效流式传输大规模点云数据,常用于 3D 可视化中。每个点由位置(Position)和可选的属性定义,这些属性用来描述点的外观(如颜色、法线等)或应用特定的元数据。

在 3D Tiles 的术语中,每个点被称为一个“特征”(Feature)。Point Cloud 瓦片本身是一个二进制块,采用小端字节序(Little Endian)。

2 布局

Point Cloud 瓦片由头部(Header)和正文(Body)两部分组成。以下是 Point Cloud 布局的简图(虚线表示可选字段):

| Header | Body (Feature Table + Batch Table) |
2.1 填充

瓦片的字节长度(byteLength)必须对齐到 8 字节边界。同时,瓦片中的特征表(Feature Table)和批处理表(Batch Table)也必须遵循各自的填充要求。

3 头部(Header)

头部是一个 28 字节的数据结构,包含以下字段:

字段名数据类型描述
magic4 字节 ANSI 字符串固定值 “pnts”,用于标识 Point Cloud 瓦片的内容。
versionuint32Point Cloud 格式的版本号,目前版本为 1。
byteLengthuint32整个瓦片的字节长度(包含头部和正文)。
featureTableJSONByteLengthuint32特征表 JSON 部分的字节长度。
featureTableBinaryByteLengthuint32特征表二进制部分的字节长度。
batchTableJSONByteLengthuint32批处理表 JSON 部分的字节长度。0 表示没有批处理表。
batchTableBinaryByteLengthuint32批处理表二进制部分的字节长度。如果批处理表 JSON 长度为 0,则该值为 0。

头部后面紧接着的是正文部分,它由特征表(Feature Table)和批处理表(Batch Table)组成。

4 特征表(Feature Table)

特征表包含每个瓦片和每个点的属性,这些属性定义了如何渲染点云数据。每个点的数据通过不同的语义(Semantics)进行标识,用于描述点的位置、颜色、法线等属性。

4.1 语义(Semantics)
4.1.1 点的语义(Point Semantics)

这些语义映射到一个特征值数组,用于定义每个点的属性。所有语义的数组长度必须相同,且等于点的数量。每个语义的值都是对特征表二进制部分的引用,而不是嵌入在特征表 JSON 头部中的。

  • 如果同时定义了 POSITIONPOSITION_QUANTIZED,则使用高精度的 POSITION
  • 如果同时定义了 NORMALNORMAL_OCT16P,则使用高精度的 NORMAL

常见的点语义包括:

语义名数据类型描述必需
POSITIONfloat32[3]定义点的位置,包含 x、y 和 z 坐标。
POSITION_QUANTIZEDuint16[3]定义量化的点位置,包含 x、y 和 z 坐标的量化值。
RGBAuint8[4]定义点的 RGBA 颜色值。
RGBuint8[3]定义点的 RGB 颜色值。
RGB565uint1616 位压缩 RGB 颜色,提供 5 位红色、6 位绿色、5 位蓝色。
NORMALfloat32[3]定义点的法向量。
NORMAL_OCT16Puint8[2]定义点的法向量,使用 16 位精度的八度编码。
BATCH_IDuint8, uint16, uint32定义点的批处理 ID,用于从批处理表中检索元数据。
4.1.2 全局语义(Global Semantics)

这些语义定义了所有点的全局属性。

语义名数据类型描述必需
POINTS_LENGTHuint32渲染的点的数量。每个语义的数组长度应与该值相同。
RTC_CENTERfloat32[3]定义点的位置相对于中心的偏移量。
QUANTIZED_VOLUME_OFFSETfloat32[3]定义量化体积的偏移量。
QUANTIZED_VOLUME_SCALEfloat32[3]定义量化体积的缩放值。
CONSTANT_RGBAuint8[4]定义所有点的常量 RGBA 颜色。
BATCH_LENGTHuint32定义唯一的 BATCH_ID 数量。

4.2 点的位置(Point Positions)

4.2.1 坐标参考系统(Coordinate Reference System, CRS)

3D Tiles 使用的是右手坐标系,具有三个轴(x, y, z),并且 x 和 y 的叉乘结果为 z。3D Tiles 定义了局部坐标系统中的 z 轴为上(up)轴。这意味着,在局部笛卡尔坐标系统中,z 轴指向上方。

4.2.2 RTC_CENTER

点的位置可以相对于一个中心点进行定义,以提高渲染的精度(见 “Precisions”)。如果定义了 RTC_CENTER,则所有点的位置都相对于该中心点进行计算。这种方法尤其适用于高精度渲染,允许对整个点云的变换应用更加精确的操作。

4.2.3 量化位置(Quantized Positions)

如果未定义 POSITION,则可以使用 POSITION_QUANTIZED 来存储点的位置,这些位置是相对于量化体积(Quantized Volume)定义的。量化体积通过偏移量(offset)和缩放因子(scale)来映射量化位置到局部坐标空间。

如果既没有定义 POSITION 也没有定义 POSITION_QUANTIZED,则该瓦片无需渲染。

请添加图片描述

量化体积的定义包括偏移量和缩放因子,分别存储在全局语义 QUANTIZED_VOLUME_OFFSETQUANTIZED_VOLUME_SCALE 中。如果没有定义这些全局语义,就无法使用 POSITION_QUANTIZED

量化位置到局部空间的映射公式如下:

POSITION = POSITION_QUANTIZED * QUANTIZED_VOLUME_SCALE / 65535.0 + QUANTIZED_VOLUME_OFFSET

4.3 点的颜色(Point Colors)

如果定义了多个颜色语义,则颜色的优先顺序为:RGBA > RGB > RGB565 > CONSTANT_RGBA。例如,如果一个瓦片的特征表包含 RGBACONSTANT_RGBA 属性,运行时将使用 RGBA 作为每个点的颜色。

如果没有定义任何颜色语义,运行时可以使用应用程序定义的默认颜色来渲染点。

无论如何,都可以使用 3D Tiles 样式(Style)在运行时改变最终渲染的颜色和其他视觉属性。

4.4 点的法线(Point Normals)

每个点的法线是一个可选属性,能够通过启用光照、隐藏表面去除等渲染技术来提高点云的视觉质量。法线将在应用瓦片变换的逆转置矩阵后进行变换。

4.4.1 八度编码法线向量(Oct-encoded Normal Vectors)

八度编码(Oct-encoding)是一种高效表示独立单位向量的方式。具体而言,八度编码将单位法线向量存储为无符号且未归一化的范围([0, 255]),并在运行时将其映射到有符号归一化范围([-1.0, 1.0])。

Cesium 中提供了一个实现,用于编码和解码这些单位向量,相关模块为 AttributeCompression

4.5 批处理点(Batched Points)

点云中的不同特征可以通过 BATCH_ID 语义进行批处理。例如,一个房间的门的所有点会分配相同的 BATCH_ID,而窗户的点则会有不同的 BATCH_ID。这对于按对象进行拾取(picking)或存储应用程序特定的元数据非常有用,特别是在声明式样式(styling)和应用程序用例(如填充用户界面、发出 REST API 请求等)中。

BATCH_ID 语义可以具有 UNSIGNED_BYTEUNSIGNED_SHORTUNSIGNED_INT 的数据类型。如果没有指定 componentType,则默认为 UNSIGNED_SHORT

全局语义 BATCH_LENGTH 定义了唯一的 BATCH_ID 数量,类似于Batched 3D Model

4.6 示例(Examples)

4.6.1 只有位置(Positions Only)

这是一个简单的示例,包含四个点,它们位于单位长度正方形的四个角上:

var featureTableJSON = { POINTS_LENGTH: 4, POSITION: { byteOffset: 0 } 
}; var featureTableBinary = new Buffer(new Float32Array([ 0.0, 0.0, 0.0,  1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0 
]).buffer);
4.6.2 位置和颜色(Positions and Colors)

以下示例包含四个点(分别为红色、绿色、蓝色和黄色),它们的位置是相对于中心定义的:

var featureTableJSON = { POINTS_LENGTH: 4, RTC_CENTER: [1215013.8, -4736316.7, 4081608.4], POSITION: { byteOffset: 0 }, RGB: { byteOffset: 48 } 
}; var positionBinary = new Buffer(new Float32Array([ 0.0, 0.0, 0.0,  1.0, 0.0, 0.0,  0.0, 0.0, 1.0,  1.0, 0.0, 1.0 
]).buffer); var colorBinary = new Buffer(new Uint8Array([ 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 0 
]).buffer); var featureTableBinary = Buffer.concat([positionBinary, colorBinary]);
4.6.3 量化位置和八度编码法线(Quantized Positions and Oct-encoded Normals)

这个示例中,四个点将有指向上方的法线向量 [0.0, 1.0, 0.0],并且它们位于一个量化体积的角上,量化体积的范围从 -250.0 到 250.0 单位:

var featureTableJSON = { POINTS_LENGTH: 4, QUANTIZED_VOLUME_OFFSET: [-250.0, 0.0, -250.0], QUANTIZED_VOLUME_SCALE: [500.0, 0.0, 500.0], POSITION_QUANTIZED: { byteOffset: 0 }, NORMAL_OCT16P: { byteOffset: 24 } 
}; var positionQuantizedBinary = new Buffer(new Uint16Array([ 0, 0, 0,  65535, 0, 0,  0, 0, 65535,  65535, 0, 65535 
]).buffer); var normalOct16PBinary = new Buffer(new Uint8Array([ 128, 255, 128, 255, 128, 255, 128, 255 
]).buffer); var featureTableBinary = Buffer.concat([positionQuantizedBinary, normalOct16PBinary]);
4.6.4 批处理点(Batched Points)

这个示例中,前两个点的 batchId 为 0,后两个点的 batchId 为 1。注意,Batch Table 只包含两个名字:

var featureTableJSON = { POINTS_LENGTH: 4, BATCH_LENGTH: 2, POSITION: { byteOffset: 0 }, BATCH_ID: { byteOffset: 48, componentType: "UNSIGNED_BYTE" } 
}; var positionBinary = new Buffer(new Float32Array([ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0 
]).buffer); var batchIdBinary = new Buffer(new Uint8Array([ 0, 0, 1, 1 
]).buffer); var featureTableBinary = Buffer.concat([positionBinary, batchIdBinary]); var batchTableJSON = { names: ['object1', 'object2'] 
};
4.6.5 每点属性(Per-point Properties)

在这个示例中,四个点将有元数据存储在 Batch Table 的 JSON 和二进制部分:

var featureTableJSON = { POINTS_LENGTH: 4, POSITION: { byteOffset: 0 } 
}; var featureTableBinary = new Buffer(new Float32Array([ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0 
]).buffer); var batchTableJSON = { names: ['point1', 'point2', 'point3', 'point4'] 
};

5 批处理表(Batch Table)

批处理表存储的是按 batchId 索引的应用程序特定元数据,可用于声明式样式和应用程序特定用例(如填充 UI 或发出 REST API 请求)。

  • 如果定义了 BATCH_ID 语义,批处理表存储每个 batchId 的元数据,批处理表的数组长度将等于 BATCH_LENGTH
  • 如果未定义 BATCH_ID 语义,批处理表存储每个点的元数据,批处理表的数组长度将等于 POINTS_LENGTH

6 文件扩展名和 MIME 类型(File Extension and MIME Type)

点云瓦片使用 .pnts 扩展名和 application/octet-stream MIME 类型。文件扩展名是可选的,有效的实现可以忽略扩展名,直接通过头部的魔术字段来识别内容格式。

7 实现示例(Implementation Example)

这部分内容是非规范性的,实际代码实现可以参考 Cesium 的 PointCloud3DModelTileContent.js 文件,它提供了 3D Tiles 的头部读取代码。
TilesBuilder 工具可转换部分三维格式

8 属性参考(Property Reference)

8.1 点云特征表(Point Cloud Feature Table)

点云特征表定义了用于描述瓦片中点的位置信息和外观属性的语义。其属性包括:

  • POSITION: 定义点的位置(包括量化位置)。
  • POSITION_QUANTIZED: 定义量化点的位置。
  • RGBA, RGB, RGB565: 定义点的颜色。
  • NORMAL, NORMAL_OCT16P: 定义点的法线。
  • BATCH_ID: 用于批处理每个点的 batchId
  • POINTS_LENGTH: 定义点的数量。
  • RTC_CENTER: 定义渲染中心。
  • QUANTIZED_VOLUME_OFFSETQUANTIZED_VOLUME_SCALE: 定义量化体积的偏移和缩放因子。

这些属性可以直接在 JSON 中定义,或者通过 BinaryBodyReference 对象引用二进制体中的对应部分。

8.2 二进制体引用(BinaryBodyReference)

BinaryBodyReference 定义了一个对象,该对象指向二进制体中存储特定属性值的部分,包含 byteOffset 属性,指定从二进制缓冲区的偏移量。

属性:
  • byteOffset (类型: number, 必需):
    指定在二进制体中的偏移量(单位为字节)。

    • 要求: 必需
    • 最小值: 大于等于 0
  • 其他属性:
    可以根据需要在 BinaryBodyReference 中添加其他自定义属性,但 byteOffset 是必需的。

8.2.1 BinaryBodyReference.byteOffset

byteOffsetBinaryBodyReference 中的一个关键属性,定义了该属性值在二进制缓冲区中的起始位置。它指定了从二进制数据开始位置的偏移量,通常是字节单位。

  • 类型: number
  • 要求: 必需
  • 最小值: >= 0

8.3 GlobalPropertyCartesian3

GlobalPropertyCartesian3 是一个对象,它定义了适用于所有特征的全局 3 组件数值属性。 通常,这些数值表示与三维坐标相关的全局属性,如位置、方向等。

8.4 GlobalPropertyCartesian4

GlobalPropertyCartesian4 是一个对象,它定义了适用于所有特征的全局 4 组件数值属性。 这通常用于表示四维数值属性,例如带有时间或颜色信息的 3D 坐标。

8.5 GlobalPropertyScalar

GlobalPropertyScalar 是一个对象,它定义了适用于所有特征的全局标量数值属性。 这种类型的属性用于表示单一的数值,如某些全局设置或常量参数。

8.6 Property

Property 是一个用户定义的属性,指定每个特征的应用程序特定元数据。
这些属性的值可以直接在 JSON 中定义,也可以通过BinaryBodyReference 引用二进制体中的某个部分。 如果 Property 是数组类型,它允许存储每个特征的多个值。

如果你有兴趣了解如何实现或使用点云格式,或者在具体的项目中遇到技术难题,可以随时向我咨询!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/886190.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【SpringBoot】20 同步调用、异步调用、异步回调

Git仓库 https://gitee.com/Lin_DH/system 介绍 同步调用:指程序在执行时,调用方需要等待函数调用返回结果后,才能继续执行下一步操作,是一种阻塞式调用。 异步调用:指程序在执行时,调用方在调用函数后立…

ESLint 使用教程(五):ESLint 和 Prettier 的结合使用与冲突解决

系列文章 ESLint 使用教程(一):从零配置 ESLint ESLint 使用教程(二):一步步教你编写 Eslint 自定义规则 ESLint 使用教程(三):12个ESLint 配置项功能与使用方式详解 ES…

Qt_day5_常用类

常用类 目录 1. QString 字符串类(掌握) 2. 容器类(掌握) 2.1 顺序容器QList 2.2 关联容器QMap 3. 几种Qt数据类型(熟悉) 3.1 跨平台数据类型 3.2 QVariant 统一数据类型 3.3 QStringList 字符串列表 4. QD…

VBA学习笔记:基础知识

1.打开编辑器 工具-选项,可设置编辑器字体大小等 2. 运行 快捷键F5,或 运行-运行宏 若提示宏被禁止,解决办法之一:工具-宏-安全性-安全级-中,关闭excel重新打开,启用宏 保存文件格式为xla或xlam 3. 基本…

【CANOE】【学习】【DecodeString】字节转为中文字符输出

系列文章目录 文章目录 系列文章目录前言一、DecodeString 转为中文字节输出二、代码举例1.代码Demo2.DecodeString 函数说明函数语法:参数说明:返回值:使用示例:示例代码: 说明: 前言 有时候使用的时候&a…

超好用shell脚本NuShell mac安装

利用管道控制任意系统 Nu 可以在 Linux、macOS 和 Windows 上运行。一次学习,处处可用。 一切皆数据 Nu 管道使用结构化数据,你可以用同样的方式安全地选择,过滤和排序。停止解析字符串,开始解决问题。 强大的插件系统 具备强…

【Window主机访问Ubuntu从机——Xrdp配置与使用】

使用Xrdp在Window环境下远程桌面访问Ubuntu主机 文章目录 Ubuntu安装图形化界面Ubuntu安装Xrdp通过网线连接两台主机Window主机有线连接配置Ubuntu从机设置测试有线连接 Window主机打开远程桌面功能参考文章总结 Ubuntu安装图形化界面 sudo apt update sudo apt upgrade sudo …

ECharts图表图例8

用eclipse软件制作动态单仪表图 用java知识点 代码截图:

实验6记录网络与故障排除

实验6记录网络与故障排除 实验目的及要求: 通过实验,掌握如何利用文档记录网络设备相关信息并完成网络拓扑结构的绘制。能够使用各种技术和工具来找出连通性问题,使用文档来指导故障排除工作,确定具体的网络问题,实施…

读取文件内容、修改文件内容、识别文件夹目录(Web操作系统文件/文件夹详解)

前言 因 Unicode IDE 编辑器导入文件、文件夹需要,研究了下导入文件/文件夹的功能实现,发现目前相关文章有点少,故而记录下过程,如果有误,还望指正。(API的兼容性及相关属性、接口定义,请自行查看文件系统 …

【卡尔曼滤波】数据融合Fusion的应用 C语言、Python实现(Kalman Filter)

【卡尔曼滤波】数据融合Fusion的应用 C语言、Python实现(Kalman Filter) 更新以gitee为准: gitee地址 文章目录 卡尔曼滤波数据融合Python实现C语言实现多个数据如何融合附录:压缩字符串、大小端格式转换压缩字符串浮点数压缩Pac…

docker-hub 无法访问,使用windows魔法拉取docker images再上传到linux docker环境中

云机的服务器是可以docker拉取镜像的,但是本地的虚拟机、物理服务器等网络环境不好的情况,是无法访问docker-hub的,即使更换了docker镜像源国内源也无法使用。 本文章使用 在魔法网络环境下的windows,下载docker images后&#xf…

Python →爬虫实践

爬取研究中心的书目 现在&#xff0c;想要把如下网站中的书目信息爬取出来。 案例一 耶鲁 Publications | Yale Law School 分析网页&#xff0c;如下图所示&#xff0c;需要爬取的页面&#xff0c;标签信息是“<p>”&#xff0c;所以用 itemssoup.find_all("p&…

【Linux学习】【Ubuntu入门】1-4 ubuntu终端操作与shell命令1

1.使用快捷键CtrlAltT打开命令终端&#xff0c;或者单击右键点击… 2.常用shell命令 目录信息查看命令&#xff1a;ls ls -a&#xff1a;显示目录所有文件及文件夹&#xff0c;包括隐藏文件&#xff0c;比如以.开头的 ls -l&#xff1a;显示文件的详细信息 ls -al&#xff1…

WordPress 6.7 “Rollins”发布

每个 WordPress 版本都会向一位在音乐界留下不可磨灭印记的艺术家致敬。WordPress 6.7 的代号为“Rollins”&#xff0c;旨在向传奇爵士萨克斯演奏家桑尼罗林斯致敬。罗林斯是爵士乐界最伟大的即兴演奏家和先驱之一&#xff0c;他以精湛的技术、创新精神和无畏的音乐表达方式影…

ESXi安装【真机和虚拟机】(超详细)

项目简介&#xff1a; ESXi&#xff08;Elastic Sky X Integrated&#xff09;是VMware公司开发的一种裸机虚拟化管理程序&#xff0c;允许用户在单一物理服务器上运行多个虚拟机&#xff08;VM&#xff09;。它直接安装在服务器硬件上&#xff0c;而不是操作系统之上&#xff…

【若依框架】代码生成详细教程,15分钟搭建Springboot+Vue3前后端分离项目,基于Mysql8数据库和Redis5,管理后台前端基于Vue3和Element Plus,开发小程序数据后台

今天我们来借助若依来快速的搭建一个基于springboot的Java管理后台&#xff0c;后台网页使用vue3和 Element Plus来快速搭建。这里我们可以借助若依自动生成Java和vue3代码&#xff0c;这就是若依的强大之处&#xff0c;即便你不会Java和vue开发&#xff0c;只要跟着石头哥也可…

HBuilder(uniapp) 配置android模拟器

HBuilder&#xff08;uniapp&#xff09; 配置android模拟器 选择完成之后&#xff0c;点击ok&#xff0c;再次点击Configure—》AVD Manager

flutter插件:录制系统播放的声音

该插件基于flutter包 flutter_screen_recording 和 github库 SystemAudioCaptureAndroid&#xff0c;实现了在安卓手机上录制系统播放声音的功能&#xff0c;也就是说&#xff0c;只要一个安卓应用没有设置不允许其它应用录制声音&#xff0c;该插件可以录制该应用播放的声音。…

Mac中安装OhMyZsh

Mac中安装OhMyZsh 文章目录 Mac中安装OhMyZsh一、Homebrew二、OhMyZsh1、Oh-My-Zsh配置1.1&#xff1a;主题配置1.2&#xff1a;插件配置&#xff08;语法高亮和自动提示&#xff09;1、zsh-autosuggestions&#xff08;需下载安装&#xff09;&#xff1a;高亮显示所有支持的命…