【问题标题】:Parsing binary point data with javascript用javascript解析二进制点数据
【发布时间】:2018-05-18 02:14:11
【问题描述】:

问题

我从描述 3D 空间中一组彩色点的 API 接收二进制数据。目的是解析这些点并在 Three.js 中的 buffergeometry 中使用它们。

在处理二进制格式的数据时,我有点不知所措,所以我需要你的帮助。


关于来自 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);

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

【问题讨论】:

  • 看起来您是以位而不是字节来指定偏移量的。对吗?

标签: javascript three.js binary-data arraybuffer buffer-geometry


【解决方案1】:

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

我认为你想要 DataView 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 位边界开始,这会使 TREMendously 的解析变得复杂。

您的代码的三个方面看起来大致正确。

你在正确的轨道上 :) 我刚刚做了一个类似的应用程序来解析 HYG 星目录并制作星点云....

好东西!

【讨论】:

  • 谢谢,@manthrax!编辑了我的错字——复制粘贴伪代码的结果。我对偏移量的位与字节感到好奇;我切换到字节,它有帮助。就 headerOffset 而言,这只是一个硬设置值。我无法弄清楚如何辨别初始偏移量。我是否在缓冲区中搜索换行符的第一个实例?我将把这个问题拆分成多个小问题。
猜你喜欢
  • 2011-10-02
  • 2011-11-23
  • 2014-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
相关资源
最近更新 更多