使用 javascript 解析二进制点数据



问题

我正在从描述 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 个垃圾字节来填充剩余空间

到目前为止,我所处的位置:

假设二进制点变量保存来自 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);

情况可能并非如此,因为我计划在下一步中将类型化数组直接转录到 Three.js 缓冲区几何中,并且保留一个 [大型] 超普通 JS 数组会增加开销。


下一步:将点放入 Three.js 缓冲区几何图形

我将使用 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);

我知道到目前为止这一切都非常松散,但我只是在黑暗中四处游荡,把这一切写下来有助于我思考清楚。

你有一个双倍的gUint8View..第二个应该是bUint8View。

我想你想要数据视图 api... 然后你可以做...

var x= view.getFloat64(0); 
var y= view.getFloat64(8); 
var z= view.getFloat64(16);
var r = view.getUInt8(24); 
var g = view.getUInt8(25); 
var v = view.getUInt8(26); 

另外..您确定"100位"标头还是是指字节?似乎很奇怪,您的数据源将从奇怪的非 8 位边界开始,这将使 TR

复杂化。代码的 THREE 面看起来大致正确。

您走在正确的轨道上:)我刚刚做了一个类似的应用程序来解析海斯特-耶鲁的星表,并制作一个星星点云。

好东西!

相关内容

  • 没有找到相关文章

最新更新