问题
我从描述 3D 空间中一组彩色点的 API 接收二进制数据。目的是解析这些点并在 Three.js 的缓冲几何中使用它们。
在处理二进制格式的数据时,我有点不知所措,所以我需要你的帮助。
关于来自 API 的二进制数据:
二进制数据以以下格式的标头开头:
HTTP/1.1 200 OK
Content-Length: 13632 // varies depending on the query
标题后面是一个空行,然后是这种格式的这些点:
每 32 个字节:
- X:双(8字节)
- Y:双(8字节)
- Z:双(8字节)
- R:无符号字符(1 字节)
- G:无符号字符(1 字节)
- B:无符号字符(1 字节)
- 5个垃圾字节来填充剩余空间
到目前为止我在哪里:
假设binaryPoints变量保存来自 API 的原始二进制数据。据我所知,我必须首先将数据添加到一个字节大小为 32(每个点的大小)的 arrayBuffer 中。接下来,我将该缓冲区添加到 DataView 对象以对其进行操作。
// create a 32-byte arrayBuffer (each point takes up 32 bytes)
const buffer = await binaryPoints.arrayBuffer(32);
// create a dataview of the buffer to read the points
const data = new DataView(buffer);
所以我还没有很多。我想我需要通过实现偏移来计算标题占用的空间,我想从标题中获取点数。
// temporary hard-set values
const numPoints = 1000;
const offsetFromHeader = 100; // bits
从我看到的一些示例和其他 SO 问题中,我相信我应该一次循环通过缓冲区 32 个字节,同时读出 xyzrgb 值。它可能看起来像:
// offset is in bits, increases by 256 each iteration (32*8)
for (var i=0, offset=offsetFromHeader; i<numPoints; i++, offset += 256) {
// Go through each xyz value, using Float64Array (double) to store that value
const xFloat64View = data.getFloat64Array(offset);
const yFloat64View = data.getFloat64Array(offset + 64);
const zFloat64View = data.getFloat64Array(offset + 128);
// Go through each rgb value, using Uint8Array (1 byte unsigned int) to store that value
const rUint8View = data.getUint8Array(offset + 192);
const gUint8View = data.getUint8Array(offset + 200);
const bUint8View = data.getUint8Array(offset + 208);
// just ignore the final bits
}
...但说实话,一旦我到了这一点,我就无法弄清楚如何处理这些信息。在我发现的一些示例中,循环通过只有一种信息类型的二进制数据运行(在我的情况下,就好像我只有 X 值)。
我是否应该创建一个新的纯 javascript 点数组并添加如下值:
// psuedo code
var points = [];
// in the loop
points[i].x = data.getFloat64Array(offset);
情况可能并非如此,因为我计划在下一步中将 Typed Arrays 直接转录到 Three.js bufferGeometries 中,并且保留一个 [large] 额外的普通 JS 数组会增加开销。
下一步:将点放入 Three.js bufferGeometry
我将使用 Three.js 的 bufferGeometry 中的点来渲染点云。我知道这会通知我想要的上一部分的输出。
它可能看起来像:
const bufferGeometry = new THREE.BufferGeometry();
let vertices = new Float32Array(); // xyz
let colors = new Float32Array(); // rgb
bufferGeometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
bufferGeometry.addAttribute('color', new THREE.BufferAttribute(colors, 3));
const points = new THREE.Points(bufferGeometry, material);
scene.add(points);
我知道到目前为止这一切都很松散,但我只是在黑暗中四处乱窜,把这一切写下来帮助我思考清楚。