0

問題

3D 空間内の色付きポイントのグループを記述する API からバイナリ データを受信して​​います。その意図は、ポイントを解析し、それらを Three.js の buffergeometry で使用することです。

バイナリ形式のデータを操作することになると、ここで少し頭を悩ませているので、あなたの助けが必要です.


API からのバイナリ データについて:

バイナリ データは、次の形式のヘッダーで始まります。

HTTP/1.1 200 OK
Content-Length: 13632 // varies depending on the query

ヘッダーの後に空白行が続き、次にこれらのポイントが次の形式で示されます。

32 バイトごと:

  • X: double (8 バイト)
  • Y: double (8 バイト)
  • Z: ダブル (8 バイト)
  • R: unsigned char (1バイト)
  • G: unsigned char (1バイト)
  • B: unsigned char (1バイト)
  • 残りのスペースを埋めるための 5 ガベージ バイト

私がこれまでにいる場所:

binaryPoints変数が API からの生のバイナリ データを保持しているとします私がこれまでに理解しているように、最初にデータを arrayBuffer にバイトサイズ 32 (各ポイントのサイズ) で追加する必要があります。次に、そのバッファーを操作するために 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
  }

……が、正直なところ、ここまで来てしまった情報をどうしたらいいのか分からなかっ。私が見つけたいくつかの例では、ループは 1 種類の情報のみを持つバイナリ データを処理します (私の場合は、X 値しかないかのようになります)。

ポイントの新しいプレーンJavaScript配列を作成し、次のような値を追加する必要があります:

// psuedo code
var points = [];

// in the loop
points[i].x = data.getFloat64Array(offset);

次のステップで Typed Arrays を Three.js bufferGeometries に直接転記する予定であり、[大きな] 余分な単純な 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);

これまでのところ、これはすべて非常にルーズなものであることはわかっていますが、暗闇の中で動き回っているだけなので、これをすべて書き留めておくと、考えるのに役立ちます.

4

1 に答える 1

0

2 倍の gUint8View があります。2 つ目は 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 ビット以外の奇妙な境界で開始され、解析が非常に複雑になるのは奇妙に思えます。

コードの THREE 側はほぼ正しいように見えます。

あなたは正しい軌道に乗っています:) HYGスターカタログを解析し、星の点群を作成するために同様のアプリを実行しました....

いい物!

于 2018-05-18T02:26:04.380 に答える