上篇:
3dTile技术研究-概念详述(7)Batched 3D Model
下篇:
3dTile技术研究-概念详述(8)Feature Table
1. 内容(Contents)
- 概述(Overview)
- 布局(Layout)
- 标头(Header)
- Feature Table
- Batch Table
- glTF
- File extension and MIME type
- Property reference
2. 概述(Overview)
Instanced 3D Model是高效传输和渲染大量对象(也叫实例)的tile格式,有一点变化。最简单的场景,比如,一个相同的树对象可能被放在(或者叫实例化在)几个地方。每个实例引用了相同的对象(树),且有各自实例的属性,比如位置。用核心的的3D Tiles格式语言来说,每个实例是一个对象。
除了表达tree对象之外,Instanced 3D Model对于消防栓、下水道帽、灯具和交通灯等外部功能,以及用于内部CAD功能,如螺栓、阀门和电源插座也是有用的。
一个Instanced 3D Model tile是以小端方式存储的二进制数据流。
实现注意项:可以用一个Composite tile来创建有不同类型的instanced models的tiles,比如,合并trees和交通灯两个Instanced 3D Model tiles。
实现注意项: Instanced 3D Model可以很好的映射到ANGLE_instanced_arrays扩展,以高效的使用WebGL渲染。
3. 布局(Layout)
tile由标头部分和紧随其后的二进制体构成。下面的图片展示了Instanced 3D Model的布局(虚线标记的是可选的字段):
布局和b3dm基本一致
3.1 填充(Padding)
tile的byteLength
必须是8字节边界对齐的。包含的Feature Table和Batch Table必须遵守它们各自的填充要求。
binary glTF(如果出现的话)必须开始和结束语8字节的边界,这样glTF的字节对齐要求可以得到保障。这可以通过填充Feature Table或Batch Table。
另外,如果glTF字段(glTF field)是UTF-8字符串,必须在它的后面填充空格字符串(0x20)以满足tile的字节对齐要求,而在运行时请求glTF资源之前必须被去掉。
glTF字段(glTF field),其实翻译成字段不准确,原意表示的是glTF领域,也就是内容,具体请参考下面的第6章。
4. 标头(Header)
32字节的标头含有下面的字段:
Field name | Data type | Description |
---|---|---|
magic | 4-byte ANSI string | "i3dm" . This can be used to identify the content as an Instanced 3D Model tile. |
version | uint32 | The version of the Instanced 3D Model format. It is currently 1 . |
byteLength | uint32 | The length of the entire tile, including the header, in bytes. |
featureTableJSONByteLength | uint32 | The length of the Feature Table JSON section in bytes. |
featureTableBinaryByteLength | uint32 | The length of the Feature Table binary section in bytes. |
batchTableJSONByteLength | uint32 | The length of the Batch Table JSON section in bytes. Zero indicates that there is no Batch Table. |
batchTableBinaryByteLength | uint32 | The length of the Batch Table binary section in bytes. If batchTableJSONByteLength is zero, this will also be zero. |
gltfFormat | uint32 | Indicates the format of the glTF field of the body. 0 indicates it is a uri, 1 indicates it is embedded binary glTF. See the glTF section below. |
二进制体紧随在标头部分之后,并且由三部分构成:Feature Table
, Batch Table
, 和 glTF
。
5. Feature Table
Feature Table含有用来创建实例化对象(instanced models)的i3dm
语义值。更多的有用信息请参考Feature Table specification。
See Property reference for the i3dm
feature table schema reference. The full JSON schema can be found in i3dm.featureTable.schema.json.
5.1 语义(Semantics)
5.1.1 实例语义(Instance semantics)
这些语义映射到用来创建实例的一个对象属性值数组。这些数组的长度对于所有的语义必须一样,且等于实例的数量。每个实例语义的值必须引用指向Feature Table的二进制体;它们不能嵌入到Feature Table的JSON标头中。
如果一个语义依赖另一个语义,那后者必须是定义的。如果一个实例的SCALE
和SCALE_NON_UNIFORM
都定义了,那么这两个缩放操作都要被应用。如果一个实例的POSITION
和POSITION_QUANTIZED
都定义了,这个更高精度的POSITION
将会被使用。如果一个实例的NORMAL_UP
, NORMAL_RIGHT
, NORMAL_UP_OCT32P
, 和 NORMAL_RIGHT_OCT32P
都定义了,那么较高精度的NORMAL_UP
和NORMAL_RIGHT
将被使用。
Semantic | Data Type | Description | Required |
---|---|---|---|
POSITION | float32[3] | A 3-component array of numbers containing 一个包含实例的x,y,z笛卡尔坐标位置的3个数值元素的数组。 | ✅ Yes, unless POSITION_QUANTIZED is defined. |
POSITION_QUANTIZED | uint16[3] | A 3-component array of numbers containing
一个包含实例的x,y,z量化的笛卡尔坐标位置的3个数值元素的数组。 | ✅ Yes, unless POSITION is defined. |
NORMAL_UP | float32[3] | A unit vector defining the 一个定义了实例的旋转(绕)的up方向的单位向量。 | 🔴 No, unless NORMAL_RIGHT is defined. |
NORMAL_RIGHT | float32[3] | A unit vector defining the 一个定义了实例旋转的right方向的单位向量,它必须正交于up方向。 | 🔴 No, unless NORMAL_UP is defined. |
NORMAL_UP_OCT32P | uint16[2] | An oct-encoded unit vector with 32-bits of precision defining the 具有32位精度的八进制编码的单位向量,定义了实例旋转的 | 🔴 No, unless NORMAL_RIGHT_OCT32P is defined. |
NORMAL_RIGHT_OCT32P | uint16[2] | An oct-encoded unit vector with 32-bits of precision defining the 具有32位精度的八进制编码的单位向量,定义实例旋转的 | 🔴 No, unless NORMAL_UP_OCT32P is defined. |
SCALE | float32 | A number defining a scale to apply to all axes of the instance. 一个定义了需要应用于实例的所有轴的缩放值。 | 🔴 No. |
SCALE_NON_UNIFORM | float32[3] | A 3-component array of numbers defining the scale to apply to the 一个定义了实例的x,y,z轴对应缩放的3元素数值数组。 | 🔴 No. |
BATCH_ID | uint8 , uint16 (default), or uint32 | The 实例的 | 🔴 No. |
5.1.2 全局语义(Global semantics)
这些语义定义了针对于所有实例的全局属性。
Semantic | Data Type | Description | Required |
---|---|---|---|
INSTANCES_LENGTH | uint32 | The number of instances to generate. The length of each array value for an instance semantic should be equal to this. 需要创建的实例的数量。实例语义的每个数组长度值需要和这个数量相等。 | ✅ Yes. |
RTC_CENTER | float32[3] | A 3-component array of numbers defining the center position when instance positions are defined relative-to-center. 定义了中心位置的3元素数值数组,当实例的位置被定义为相对于中心(relative-to-center)的时候有效。 | 🔴 No. |
QUANTIZED_VOLUME_OFFSET | float32[3] | A 3-component array of numbers defining the offset for the quantized volume. 定义了量化的volume的偏移的3元素数值数组。 | 🔴 No, unless POSITION_QUANTIZED is defined. |
QUANTIZED_VOLUME_SCALE | float32[3] | A 3-component array of numbers defining the scale for the quantized volume. 定义了量化的volume的缩放的3元素数值数组。 | 🔴 No, unless POSITION_QUANTIZED is defined. |
EAST_NORTH_UP | boolean | When 当值是true并且每个实例的旋转没有定义时,每个实例将会默认的为WGS84椭球体的
| 🔴 No. |
可以在examples section中找到使用了这些语义的例子。
5.2 实例方向(Instance orientation)
实例的方向被up
和right
向量生成的正交坐标轴定义。这个方向需要被 tile transform作用。
标准坐标系中的x轴对应于转换后的right
向量,y轴对应于up
向量。z
轴应该对应于up
向量,但是这常常被忽略,因为它总是由right
和up
叉乘所得。
在标准坐标系中的一个盒子:
盒子被转换了,它的方向被旋转了:
5.2.1 八进制编码的法向向量(Oct-encoded normal vectors)
如果没有为实例定义NORMAL_UP
和NORMAL_RIGHT
,则其方向可以作为八进制编码的法向存储在NORMAL_UP_OCT32P
和中NORMAL_RIGHT_OCT32P
。它们使用在独立单位向量的有效表示法调查中描述的八进制编码定义了up
和right
。八进制编码的值存储在无符号的非规范化范围([0, 65535]
)中,然后在运行时映射到有符号的规范化范围([-1.0, 1.0]
)。
在CesiumJS的AttributeCompression 模块中可以找到对这些单位矢量进行编码和解码的实现。
5.2.2 默认方向(Default orientation)
如果不存在NORMAL_UP
和NORMAL_RIGHT
或NORMAL_UP_OCT32P
和NORMAL_RIGHT_OCT32P
,则实例没有自定义方向。如果EAST_NORTH_UP
为true
,则假定该实例在WGS84
椭圆体上,并且其方向将默认为其制图位置处的参考框架的east/north/up
。这适用于诸如树木之类的实例模型,其方向始终从其在椭球表面上的位置朝上。
5.2.3 实例位置(Instance position)
POSITION
定义了实例的位置,该位置还没有被tile的转换矩阵作用。
RTC_CENTER
(实例的)位置可能会定义为相对于中心的(relative-to-center),以进行高精度的渲染,参考Precisions, Precisions。如果这样定义了,RTC_CENTER
指定了所有实例位置相对于的中心位置的值。
Quantized positions
如果实例的POSITION
未定义,则其位置可以存储在中POSITION_QUANTIZED
,后者定义相对于量化体积的实例位置。如果没有POSITION
或POSITION_QUANTIZED
定义,实例将不会被创建。
量化的体积由offset
和scale
定义,并将量化的位置映射到局部空间,如下图所示:
offset
存储在全局语义QUANTIZED_VOLUME_OFFSET
中,并且scale
存储在全局语义QUANTIZED_VOLUME_SCALE
中。如果未定义这些全局语义,POSITION_QUANTIZED
则无法使用。
可以使用以下公式将量化的位置映射到本地空间:
POSITION = POSITION_QUANTIZED * QUANTIZED_VOLUME_SCALE / 65535.0 + QUANTIZED_VOLUME_OFFSET
5.2.4 实例缩放(Instance scaling)
缩放可以使用SCALE
和SCALE_NON_UNIFORM
语义应用于实例。 SCALE
沿着所有轴施加均匀的缩放,而SCALE_NON_UNIFORM
独立地应用缩放到x
,y
和z
轴。
5.3 例子(Examples)
下面的例子展示了如何生成Feature Table的JSON和二进制数据。
Positions only
在这个最小的例子中,我们把4个实例以默认的方向放到了一个单位长度的正方形的四个角上:
var featureTableJSON = {
INSTANCES_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);
Quantized positions and oct-encoded normals
在此示例中,四个实例的以八进制格式编码的放置方向为的up
([0.0, 1.0, 0.0]
)、right
([1.0, 0.0, 0.0]
),并将它们放置在量化体积的角上,该量化体积在x
和z
方向上跨越-250.0
到个250.0
单位:
VAR featureTableJSON = {
INSTANCES_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_UP_OCT32P:{
byteOffset:24
} ,
NORMAL_RIGHT_OCT32P:{
byteOffset:40
}
} ;
VAR positionQuantizedBinary = 新 缓冲液(新 Uint16Array ([
0 , 0 , 0 ,
65535 , 0 , 0 ,
0 , 0 , 65535 ,
65535 , 0 , 65535
] )。缓冲液);
var normalUpOct32PBinary = new Buffer (new Uint16Array ([
32768 , 65535 ,
32768 , 65535 ,
32768 , 65535 ,
32768 , 65535
] )。缓冲);
VAR normalRightOct32PBinary = 新 缓冲液(新 Uint16Array ([
65535 , 32768 ,
65535 , 32768 ,
65535 , 32768 ,
65535 , 32768
] )。缓冲);
var featureTableBinary = Buffer 。连续([ positionQuantizedBinary , normalUpOct32PBinary , normalRightOct32PBinary ] );
6. Batch Table
包含以batchId
组织的源数据,它可以用于声明式样式。更多信息请参考Batch Table。
可以参考该系列博客中关于Batch Table的一篇:3dTile技术研究-概念详述(9)Batch Table
7. glTF
嵌入了包含模型几何和纹理信息的glTF 2.0。
要实例化的glTF资源存储在Feature Table 和 Batch Table之后。它可能嵌入了所有的几何、纹理和动画数据,或者可能部分或全部的引用外部资源来存储这些数据。
header.gltfFormat
指定了glTF字段的格式:
- 当
header.gltfFormat
的值是0时,glTF字段是一个UTF-8的字符串,其中包含一个glTF的uri或者二进制的glTF内容。 - 当
header.gltfFormat
的值是1时,glTF字段是一个包含了binary glTF的二进制数据。
glTF字段(glTF field),其实翻译成字段不准确,原意表示的是glTF领域,也就是内容。
7.1 坐标系(Coordinate system)
默认的嵌入的glTFs使用了一个y-up的右手坐标系。为了保持与3D Tiles的z-up坐标系的一致性,在运行时必须对glTFs进行转换。详细参考glTF transforms。
8. File extension and MIME type
Batched 3D Model tiles使用.i3dm
扩展格式和application/octet-stream
MIME type。
显示的文件扩展名是可选的。有效的实现可能会忽略高扩展名而在标头的 magic
字段标记内容的格式。
参考之前的文章,有示例截图。
传送:
3dTile技术研究-概念详述(7)Batched 3D Model
3dTile技术研究-概念详述(8)Feature Table