获取的大致流程如下,实际上还有许多其他逻辑,再此省略
为何在读取数据时有那么多的偏移,可参考法克鸡丝的数据图
https://www.cnblogs.com/fuckgiser/p/6554666.html
下面是我参照源码,自己请求其中一个tile的执行逻辑
//请求函数
axios.get(uri,{
responseType: 'arraybuffer', // 默认的
}).then((res)=> {
_this.processData(res.data)
})
//处理函数
processData(arrayBuffer){
//
var uint8Array = new Uint8Array(arrayBuffer);
var view = new DataView(arrayBuffer);
//偏移字节数byteOffset 默认为4,TILE中的前4个字节为magic标识
//getUint32()方法从DataView相对于起始位置偏移 n 个字节处开始,获取一个32-bit数,即为tile的版本
//具体可查看fuckgis 3D tile的数据结构
//https://www.cnblogs.com/fuckgiser/p/6554666.html
var byteOffset=0
byteOffset += sizeOfUint32; // Skip magic
var version = view.getUint32(byteOffset, true);
//继续往下移动
byteOffset += sizeOfUint32; // Skip magic
//得到featuretableJSON字节长度
var featureTableJsonByteLength = view.getUint32(byteOffset, true);
byteOffset += sizeOfUint32;
//得到featuretable 二进制字节长度
var featureTableBinaryByteLength = view.getUint32(byteOffset, true);
//多次offset后,可以直接读取内容gltf
var featureTableBinary = new Uint8Array(arrayBuffer, byteOffset, featureTableBinaryByteLength);
//转换到featuretable的buffer中
var featureTable = new Cesium3DTileFeatureTable(featureTableJson, featureTableBinary);
// getPropertyArray 函数中调用getTypedArrayFromBinary,
// 在调用 typedArray = ComponentDatatype.createArrayBufferView(componentType, featureTable.buffer.buffer, featureTable.buffer.byteOffset + byteOffset, count * componentLength);
var positions = featureTable.getPropertyArray('POSITION_QUANTIZED', ComponentDatatype.UNSIGNED_SHORT, 3);
//然后挂载到点云的_parsedContent属性中
var pointCloud={}
pointCloud._parsedContent = {
positions : positions, //相应的顶点数量
colors : colors,//相应的颜色数量
normals : normals,//空
batchIds : batchIds, //空
styleableProperties : styleableProperties,//空
draco : draco//空
};
//完成了数据的写入
//下一步是 shader的创建,在createShaders函数中
//创建完成之后,会调用 drawCommand.shaderProgram._bind()执行
}
讲到3D TILES获取到数据后,initialize函数将数据存储到pointcloud对象的_parsedContent属性中;
当update逻辑进入之后会有createResource的调用,将数据从_parsedContent取出
然后利用buffer将数据读取出
塞入到atrribute中,这里的配置项是不是跟geometry特别类似了呢,接近webgl原生了
参照:https://blog.csdn.net/A873054267/article/details/105134695
然后存储顶点矩阵中
最后塞入drawcommand中,可以发现,此时顶点着色器和片元着色器都未赋值,在update逻辑中会由shaderProgram的createShaders进行创建,绑定到程序上执行
由此完成了,数据源、顶点着色器、片元着色器与gl程序的关联。
跟踪代码可以发现,cesium中的绘图操作在drawCommand中;
顶点着色器:
attribute vec3 a_position;
varying vec4 v_color;
uniform vec4 u_pointSizeAndTimeAndGeometricErrorAndDepthMultiplier;
uniform vec4 u_constantColor; uniform vec4 u_highlightColor;
float u_pointSize; float u_time;
attribute vec3 a_color;
uniform vec4 u_quantizedVolumeScaleAndOctEncodedRange;
void main() {
u_pointSize = u_pointSizeAndTimeAndGeometricErrorAndDepthMultiplier.x;
u_time = u_pointSizeAndTimeAndGeometricErrorAndDepthMultiplier.y;
vec4 color = vec4(a_color, 1.0);
vec3 position = a_position * u_quantizedVolumeScaleAndOctEncodedRange.xyz;
vec3 position_absolute = vec3(czm_model * vec4(position, 1.0)); vec3 normal = vec3(1.0);
gl_PointSize = u_pointSize;
color = color * u_highlightColor;
v_color = color;
gl_Position = czm_modelViewProjection * vec4(position, 1.0);
}
片元着色器:
uniform vec4 czm_pickColor;
varying vec4 v_color;
void main() {
gl_FragColor = czm_gammaCorrect(v_color);
}